Files
oc-discovery/daemons/node/stream/handler.go

158 lines
4.7 KiB
Go
Raw Normal View History

2026-01-30 16:57:36 +01:00
package stream
import (
"context"
"crypto/subtle"
2026-01-30 16:57:36 +01:00
"encoding/json"
"errors"
"oc-discovery/daemons/node/common"
"strings"
oclib "cloud.o-forge.io/core/oc-lib"
"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"
)
type Verify struct {
IsVerified bool `json:"is_verified"`
}
func (ps *StreamService) getTopicName(topicName string) string {
2026-01-30 16:57:36 +01:00
ns := strings.Split(topicName, ".")
if len(ns) > 0 {
return ns[0]
2026-01-30 16:57:36 +01:00
}
return tools.NONE.String()
2026-01-30 16:57:36 +01:00
}
func (ps *StreamService) handleEvent(topicName string, evt *common.Event) error {
action := ps.getTopicName(topicName)
ps.handleEventFromPartner(evt, action)
if action == "verify_resource" {
if evt.DataType == -1 {
tools.NewNATSCaller().SetNATSPub(tools.VERIFY_RESOURCE, tools.NATSResponse{
FromApp: "oc-discovery",
Method: int(tools.VERIFY_RESOURCE),
Payload: evt.Payload,
})
} else if err := ps.verifyResponse(evt); err != nil {
return err
}
2026-01-30 16:57:36 +01:00
}
if action == tools.PB_SEARCH_RESPONSE.String() {
2026-01-30 16:57:36 +01:00
if err := ps.retrieveResponse(evt); err != nil {
return err
}
}
return errors.New("no action authorized available : " + action)
}
func (abs *StreamService) verifyResponse(event *common.Event) error { //
res, err := resources.ToResource(int(event.DataType), event.Payload)
if err != nil || res == nil {
return nil
}
verify := Verify{
IsVerified: false,
}
access := oclib.NewRequestAdmin(oclib.LibDataEnum(event.DataType), nil)
data := access.LoadOne(res.GetID())
if data.Err == "" && data.Data != nil {
if b, err := json.Marshal(data.Data); err == nil {
if res2, err := resources.ToResource(int(event.DataType), b); err == nil {
verify.IsVerified = subtle.ConstantTimeCompare(res.GetSignature(), res2.GetSignature()) == 1
}
}
}
if b, err := json.Marshal(verify); err == nil {
abs.PublishVerifyResources(nil, "", event.From, b)
}
2026-01-30 16:57:36 +01:00
return nil
}
func (abs *StreamService) retrieveResponse(event *common.Event) error { //
res, err := resources.ToResource(int(event.DataType), event.Payload)
if err != nil || res == nil {
return nil
}
b, err := json.Marshal(res.Serialize(res))
2026-02-03 15:25:15 +01:00
go tools.NewNATSCaller().SetNATSPub(tools.CATALOG_SEARCH_EVENT, tools.NATSResponse{
2026-01-30 16:57:36 +01:00
FromApp: "oc-discovery",
Datatype: tools.DataType(event.DataType),
Method: int(tools.CATALOG_SEARCH_EVENT),
Payload: b,
})
return nil
}
func (ps *StreamService) handleEventFromPartner(evt *common.Event, action string) error {
2026-01-30 16:57:36 +01:00
resource, err := resources.ToResource(int(evt.DataType), evt.Payload)
if err != nil {
return err
}
b, err := json.Marshal(resource)
if err != nil {
return err
}
switch action {
case tools.PB_SEARCH.String():
2026-01-30 16:57:36 +01:00
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
peers := access.Search(nil, evt.From, false)
if len(peers.Data) > 0 {
p := peers.Data[0].(*peer.Peer)
// TODO : something if peer is missing in our side !
ps.SendResponse(p, evt)
2026-02-04 11:35:19 +01:00
} else if p, err := ps.Node.GetPeerRecord(context.Background(), evt.From); err == nil && len(p) > 0 { // peer from is peerID
ps.SendResponse(p[0], evt)
2026-01-30 16:57:36 +01:00
}
case tools.PB_CREATE.String():
case tools.PB_UPDATE.String():
2026-02-03 15:25:15 +01:00
go tools.NewNATSCaller().SetNATSPub(tools.CREATE_RESOURCE, tools.NATSResponse{
2026-01-30 16:57:36 +01:00
FromApp: "oc-discovery",
Datatype: tools.DataType(evt.DataType),
Method: int(tools.CREATE_RESOURCE),
Payload: b,
})
case tools.PB_DELETE.String():
2026-02-03 15:25:15 +01:00
go tools.NewNATSCaller().SetNATSPub(tools.REMOVE_RESOURCE, tools.NATSResponse{
2026-01-30 16:57:36 +01:00
FromApp: "oc-discovery",
Datatype: tools.DataType(evt.DataType),
Method: int(tools.REMOVE_RESOURCE),
Payload: b,
})
default:
return errors.New("no action authorized available : " + action)
2026-01-30 16:57:36 +01:00
}
return nil
}
func (abs *StreamService) SendResponse(p *peer.Peer, event *common.Event) error {
dts := []oclib.LibDataEnum{oclib.LibDataEnum(event.DataType)}
if event.DataType == -1 { // expect all resources
dts = []oclib.LibDataEnum{oclib.LibDataEnum(oclib.COMPUTE_RESOURCE), oclib.LibDataEnum(oclib.STORAGE_RESOURCE),
oclib.LibDataEnum(oclib.PROCESSING_RESOURCE), oclib.LibDataEnum(oclib.DATA_RESOURCE), oclib.LibDataEnum(oclib.WORKFLOW_RESOURCE)}
}
var m map[string]string
err := json.Unmarshal(event.Payload, &m)
if err != nil {
return err
}
for _, dt := range dts {
access := oclib.NewRequestAdmin(oclib.LibDataEnum(event.DataType), nil)
peerID := p.GetID()
searched := access.Search(abs.FilterPeer(peerID, m["search"]), "", false)
for _, ss := range searched.Data {
if j, err := json.Marshal(ss); err == nil {
if event.DataType != -1 {
ndt := tools.DataType(dt.EnumIndex())
abs.PublishResources(&ndt, event.User, peerID, j)
} else {
abs.PublishResources(nil, event.User, peerID, j)
2026-02-04 11:35:19 +01:00
}
2026-01-30 16:57:36 +01:00
}
}
}
return nil
}