246 lines
6.8 KiB
Go
246 lines
6.8 KiB
Go
package infrastructure
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"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/models/resources"
|
|
"cloud.o-forge.io/core/oc-lib/tools"
|
|
)
|
|
|
|
func (ps *PubSubService) searchResponsePublishEvent(
|
|
ctx context.Context,
|
|
dt *tools.DataType,
|
|
user string,
|
|
peerID string,
|
|
payload []byte,
|
|
) error {
|
|
return ps.publishEvent(ctx, dt, SEARCH_RESPONSE, user, peerID, payload, true)
|
|
}
|
|
|
|
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), "", "", []string{}, 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), "", "", []string{}, 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
|
|
}
|
|
ps.SearchStream[user] = make(chan resources.ResourceInterface, 128) // set up the searchStream
|
|
if err := ps.subscribeEvents(ctx, dt, SEARCH_RESPONSE, id, 60); err != nil { // TODO Catpure Event !
|
|
return err
|
|
}
|
|
return ps.publishEvent(ctx, dt, SEARCH, user, peerID, payload, false)
|
|
}
|
|
|
|
func (ps *PubSubService) CreatePublishEvent(
|
|
ctx context.Context,
|
|
dt *tools.DataType,
|
|
user string,
|
|
payload []byte,
|
|
) error {
|
|
id, err := oclib.GenerateNodeID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return ps.publishEvent(ctx, dt, CREATE, user, id, payload, false)
|
|
}
|
|
|
|
func (ps *PubSubService) UpdatePublishEvent(
|
|
ctx context.Context,
|
|
dt *tools.DataType,
|
|
user string,
|
|
payload []byte,
|
|
) error {
|
|
id, err := oclib.GenerateNodeID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return ps.publishEvent(ctx, dt, UPDATE, user, id, payload, false)
|
|
}
|
|
|
|
func (ps *PubSubService) DeletePublishEvent(
|
|
ctx context.Context,
|
|
dt *tools.DataType,
|
|
user string,
|
|
payload []byte,
|
|
) error {
|
|
id, err := oclib.GenerateNodeID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return ps.publishEvent(ctx, dt, DELETE, user, id, payload, false)
|
|
}
|
|
|
|
func (ps *PubSubService) publishEvent(
|
|
ctx context.Context,
|
|
dt *tools.DataType,
|
|
action PubSubAction,
|
|
user string,
|
|
peerID string,
|
|
payload []byte,
|
|
chanNamedByDt bool,
|
|
) error {
|
|
name := "oc-catalog." + action.String() + "#" + peerID
|
|
if chanNamedByDt && dt != nil { // if a datatype is precised then : app.action.datatype#peerID
|
|
name = "oc-catalog." + action.String() + "." + (*dt).String() + "#" + peerID
|
|
}
|
|
|
|
from, err := oclib.GenerateNodeID()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
evt := 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 := 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
|