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, filter *dbs.Filters, resource []byte, protos ...protocol.ID) error { access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil) p := access.Search(filter, "", false) for _, pes := range p.Data { for _, proto := range protos { if _, err := ps.PublishCommon(dt, user, pes.(*peer.Peer).PeerID, proto, resource); err != nil { return err } } } return nil } func (ps *StreamService) PublishCommon(dt *tools.DataType, user string, toPeerID string, proto protocol.ID, resource []byte) (*common.Stream, error) { fmt.Println("PublishCommon") if toPeerID == ps.Key.String() { 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(p.Data[0].(*peer.Peer).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, payload []byte) error { if *dt == tools.PEER { var p peer.Peer if err := json.Unmarshal(payload, &p); err != nil { return err } pid, err := pp.Decode(p.PeerID) if 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, p.PeerID, ProtocolUpdateResource, b2); err != nil { return err } if p.Relation == peer.PARTNER { if ps.Streams[ProtocolHeartbeatPartner] == nil { ps.Streams[ProtocolHeartbeatPartner] = map[pp.ID]*common.Stream{} } fmt.Println("SHOULD CONNECT") ps.ConnectToPartner(p.StreamAddress) } else if ps.Streams[ProtocolHeartbeatPartner] != nil && ps.Streams[ProtocolHeartbeatPartner][pid] != nil { for _, pids := range ps.Streams { if pids[pid] != nil { delete(pids, pid) } } } } } return nil } ks := []protocol.ID{} for k := range protocolsPartners { ks = append(ks, k) } ps.PublishesCommon(dt, user, &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, ks...) 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), peerID.ID.String(), dt, user, payload) fmt.Println("SEND EVENT ", evt.From, evt.DataType, evt.Timestamp) if err := json.NewEncoder(stream.Stream).Encode(evt); err != nil { stream.Stream.Close() logger.Err(err) return stream, nil } return stream, nil }