206 lines
6.0 KiB
Go
206 lines
6.0 KiB
Go
|
|
package pubsub
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"encoding/json"
|
||
|
|
"errors"
|
||
|
|
"oc-discovery/daemons"
|
||
|
|
"oc-discovery/models"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
oclib "cloud.o-forge.io/core/oc-lib"
|
||
|
|
"cloud.o-forge.io/core/oc-lib/dbs"
|
||
|
|
"cloud.o-forge.io/core/oc-lib/models/peer"
|
||
|
|
"cloud.o-forge.io/core/oc-lib/tools"
|
||
|
|
)
|
||
|
|
|
||
|
|
func (ps *PubSubService) SearchPublishEvent(
|
||
|
|
ctx context.Context,
|
||
|
|
dt *tools.DataType,
|
||
|
|
typ string,
|
||
|
|
user string,
|
||
|
|
search string,
|
||
|
|
) error {
|
||
|
|
switch typ {
|
||
|
|
case "partner":
|
||
|
|
ps.searchPartnersPublishEvent(
|
||
|
|
ctx, dt, user, search,
|
||
|
|
)
|
||
|
|
case "all":
|
||
|
|
b, err := json.Marshal(map[string]string{
|
||
|
|
"search": search,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
ps.searchPublishEvent(
|
||
|
|
ctx, dt, user, "", b,
|
||
|
|
)
|
||
|
|
case "known":
|
||
|
|
ps.searchKnownPublishEvent(
|
||
|
|
ctx, dt, user, search,
|
||
|
|
)
|
||
|
|
default:
|
||
|
|
return errors.New("no type of research found")
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (ps *PubSubService) searchPartnersPublishEvent(
|
||
|
|
ctx context.Context,
|
||
|
|
dt *tools.DataType,
|
||
|
|
user string,
|
||
|
|
search string,
|
||
|
|
) error {
|
||
|
|
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
|
||
|
|
f := &dbs.Filters{
|
||
|
|
And: map[string][]dbs.Filter{ // search by name if no filters are provided
|
||
|
|
"state": {{Operator: dbs.EQUAL.String(), Value: peer.ONLINE.EnumIndex()}},
|
||
|
|
"relation": {{Operator: dbs.EQUAL.String(), Value: peer.PARTNER.EnumIndex()}},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
if search != "" {
|
||
|
|
f.Or = map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
|
||
|
|
"abstractintanciatedresource.abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.type": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.owners.name": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: search}},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
b, err := json.Marshal(map[string]string{
|
||
|
|
"search": search,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
peersKnown := access.Search(f, "", false)
|
||
|
|
for _, known := range peersKnown.Data {
|
||
|
|
if err := ps.searchPublishEvent(ctx, dt, user, known.GetID(), b); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (ps *PubSubService) searchKnownPublishEvent(
|
||
|
|
ctx context.Context,
|
||
|
|
dt *tools.DataType,
|
||
|
|
user string,
|
||
|
|
search string,
|
||
|
|
) error {
|
||
|
|
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
|
||
|
|
f := &dbs.Filters{
|
||
|
|
And: map[string][]dbs.Filter{ // search by name if no filters are provided
|
||
|
|
"state": {{Operator: dbs.EQUAL.String(), Value: peer.ONLINE.EnumIndex()}},
|
||
|
|
"relation": {{Operator: dbs.NOT.String(), Value: &dbs.Filters{
|
||
|
|
And: map[string][]dbs.Filter{
|
||
|
|
"relation": {{Operator: dbs.EQUAL.String(), Value: peer.BLACKLIST.EnumIndex()}},
|
||
|
|
},
|
||
|
|
}}},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
if search != "" {
|
||
|
|
f.Or = map[string][]dbs.Filter{ // filter by like name, short_description, description, owner, url if no filters are provided
|
||
|
|
"abstractintanciatedresource.abstractresource.abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.type": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.short_description": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.description": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.owners.name": {{Operator: dbs.LIKE.String(), Value: search}},
|
||
|
|
"abstractintanciatedresource.abstractresource.abstractobject.creator_id": {{Operator: dbs.EQUAL.String(), Value: search}},
|
||
|
|
}
|
||
|
|
}
|
||
|
|
b, err := json.Marshal(map[string]string{
|
||
|
|
"search": search,
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
peersKnown := access.Search(f, "", false)
|
||
|
|
for _, known := range peersKnown.Data {
|
||
|
|
if err := ps.searchPublishEvent(ctx, dt, user, known.GetID(), b); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func (ps *PubSubService) searchPublishEvent(
|
||
|
|
ctx context.Context,
|
||
|
|
dt *tools.DataType,
|
||
|
|
user string,
|
||
|
|
peerID string,
|
||
|
|
payload []byte,
|
||
|
|
) error {
|
||
|
|
id, err := oclib.GenerateNodeID()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if err := ps.subscribeEvents(ctx, dt, tools.PB_SEARCH_RESPONSE, id, 60); err != nil { // TODO Catpure Event !
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return ps.publishEvent(ctx, dt, tools.PB_SEARCH, user, peerID, payload, false)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (ps *PubSubService) ToPartnerPublishEvent(
|
||
|
|
ctx context.Context, action tools.PubSubAction, dt *tools.DataType, user string, payload []byte) error {
|
||
|
|
id, err := oclib.GenerateNodeID()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
return ps.publishEvent(ctx, dt, action, user, id, payload, false)
|
||
|
|
}
|
||
|
|
|
||
|
|
func (ps *PubSubService) publishEvent(
|
||
|
|
ctx context.Context,
|
||
|
|
dt *tools.DataType,
|
||
|
|
action tools.PubSubAction,
|
||
|
|
user string,
|
||
|
|
peerID string,
|
||
|
|
payload []byte,
|
||
|
|
chanNamedByDt bool,
|
||
|
|
) error {
|
||
|
|
name := action.String() + "#" + peerID
|
||
|
|
if chanNamedByDt && dt != nil { // if a datatype is precised then : app.action.datatype#peerID
|
||
|
|
name = action.String() + "." + (*dt).String() + "#" + peerID
|
||
|
|
}
|
||
|
|
|
||
|
|
from, err := oclib.GenerateNodeID()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
evt := models.Event{
|
||
|
|
Type: name,
|
||
|
|
From: from,
|
||
|
|
User: user,
|
||
|
|
Timestamp: time.Now().Unix(),
|
||
|
|
Payload: payload,
|
||
|
|
}
|
||
|
|
if dt != nil {
|
||
|
|
evt.DataType = int64(dt.EnumIndex())
|
||
|
|
} else {
|
||
|
|
evt.DataType = -1
|
||
|
|
}
|
||
|
|
|
||
|
|
body, _ := json.Marshal(evt)
|
||
|
|
priv, err := daemons.LoadKeyFromFile(false)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
sig, _ := priv.Sign(body)
|
||
|
|
evt.Signature = sig
|
||
|
|
|
||
|
|
msg, _ := json.Marshal(evt)
|
||
|
|
|
||
|
|
topic, err := ps.PS.Join(name)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
return topic.Publish(ctx, msg)
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO REVIEW PUBLISHING + ADD SEARCH ON PUBLIC : YES
|
||
|
|
// TODO : Search should verify DataType
|