Files
oc-discovery/daemons/pubsub/publish.go

206 lines
6.0 KiB
Go
Raw Normal View History

2026-01-28 17:22:29 +01:00
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