package stream import ( "context" "encoding/json" "errors" "fmt" "oc-discovery/daemons/node/common" 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" pp "github.com/libp2p/go-libp2p/core/peer" "github.com/libp2p/go-libp2p/core/protocol" ) func (ps *StreamService) PublishesCommon(dt *tools.DataType, user string, groups []string, filter *dbs.Filters, resource []byte, protos ...protocol.ID) error { access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil) var p oclib.LibDataShallow if filter == nil { p = access.LoadAll(false) } else { p = access.Search(filter, "", false) } for _, pes := range p.Data { for _, proto := range protos { if _, err := ps.PublishCommon(dt, user, groups, pes.(*peer.Peer).PeerID, proto, resource); err != nil { continue } } } return nil } func (ps *StreamService) PublishCommon(dt *tools.DataType, user string, groups []string, toPeerID string, proto protocol.ID, resource []byte) (*common.Stream, error) { fmt.Println("PublishCommon") if toPeerID == ps.Key.String() { fmt.Println("Can't send to ourself !") return nil, errors.New("Can't send to ourself !") } access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil) p := access.Search(&dbs.Filters{ And: map[string][]dbs.Filter{ // search by name if no filters are provided "peer_id": {{Operator: dbs.EQUAL.String(), Value: toPeerID}}, }, }, toPeerID, false) var pe *peer.Peer if len(p.Data) > 0 && p.Data[0].(*peer.Peer).Relation != peer.BLACKLIST { pe = p.Data[0].(*peer.Peer) } else if pps, err := ps.Node.GetPeerRecord(context.Background(), toPeerID); err == nil && len(pps) > 0 { pe = pps[0] } if pe != nil { ad, err := pp.AddrInfoFromString(pe.StreamAddress) if err != nil { return nil, err } return ps.write(toPeerID, ad, dt, user, resource, proto) } return nil, errors.New("peer unvalid " + toPeerID) } func (ps *StreamService) ToPartnerPublishEvent( ctx context.Context, action tools.PubSubAction, dt *tools.DataType, user string, groups []string, payload []byte) error { if *dt == tools.PEER { var p peer.Peer if err := json.Unmarshal(payload, &p); err != nil { return err } if _, err := pp.Decode(p.PeerID); err != nil { return err } if pe, err := oclib.GetMySelf(); err != nil { return err } else if pe.GetID() == p.GetID() { return fmt.Errorf("can't send to ourself") } else { pe.Relation = p.Relation pe.Verify = false if b2, err := json.Marshal(pe); err == nil { if _, err := ps.PublishCommon(dt, user, groups, p.PeerID, ProtocolUpdateResource, b2); err != nil { return err } } } return nil } ks := []protocol.ID{} for k := range protocolsPartners { ks = append(ks, k) } var proto protocol.ID proto = ProtocolCreateResource switch action { case tools.PB_DELETE: proto = ProtocolDeleteResource case tools.PB_UPDATE: proto = ProtocolUpdateResource } ps.PublishesCommon(dt, user, groups, &dbs.Filters{ // filter by like name, short_description, description, owner, url if no filters are provided And: map[string][]dbs.Filter{ "relation": {{Operator: dbs.EQUAL.String(), Value: peer.PARTNER}}, }, }, payload, proto) return nil } func (s *StreamService) write( did string, peerID *pp.AddrInfo, dt *tools.DataType, user string, payload []byte, proto protocol.ID) (*common.Stream, error) { logger := oclib.GetLogger() var err error pts := map[protocol.ID]*common.ProtocolInfo{} for k, v := range protocols { pts[k] = v } for k, v := range protocolsPartners { pts[k] = v } // should create a very temp stream if s.Streams, err = common.TempStream(s.Host, *peerID, proto, did, s.Streams, pts, &s.Mu); err != nil { return nil, errors.New("no stream available for protocol " + fmt.Sprintf("%v", proto) + " from PID " + peerID.ID.String()) } stream := s.Streams[proto][peerID.ID] evt := common.NewEvent(string(proto), s.Host.ID().String(), dt, user, payload) fmt.Println("SEND EVENT ", peerID, proto, evt.From, evt.DataType, evt.Timestamp) if err := json.NewEncoder(stream.Stream).Encode(evt); err != nil { stream.Stream.Close() logger.Err(err) return nil, err } if protocolInfo, ok := protocols[proto]; ok && protocolInfo.WaitResponse { go s.readLoop(stream, peerID.ID, proto, &common.ProtocolInfo{PersistantStream: true}) } return stream, nil }