package bus import ( "context" "errors" "fmt" "strings" "git.novox.be/novox/mesh-sdk/go/buscalls" "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/stateobjects" "github.com/nats-io/nats.go/jetstream" ) // SentGet reads one object of a sender's store of sent objects by the reference that carried it (ADR 0666 §16): the // store is the sender's `_sent-objects`, and no other — a state's objects are reached through their owner's // bindings alone. It reads as this connection's account, which the bus lets read a sender's sent store only where the // grants part granted it (a bundle is held to what its runtime channel carries by the runtime call, not here), from the manifests' callers and consumers; a refusal says the store. func (c *Conn) SentGet(r buscalls.ObjectsSentGetRequest) (*buscalls.ObjectData, error) { ref := stateobjects.Ref{Store: r.Store, Object: r.Object, Size: r.Size, Digest: r.Digest, Form: stateobjects.FormVersion} if _, ok := stateobjects.ReadRef(stateobjects.Wrap(ref)); !ok { return nil, errors.New("a sent object is named by the reference's store, object, size and sha256, as the reply or event carried them") } if !strings.HasSuffix(r.Store, catalogue.BusNameSeparator+catalogue.SentObjectsLocal) { return nil, fmt.Errorf("%s is no sent store (a module's is `%s%s`): only a sent object is read by its reference", r.Store, catalogue.BusNameSeparator, catalogue.SentObjectsLocal) } js, err := c.jetStream() if err != nil { return nil, err } ctx, cancel := context.WithTimeout(context.Background(), StateTimeout) defer cancel() obs, err := js.ObjectStore(ctx, r.Store) if err != nil { return nil, fmt.Errorf("the sent store %s cannot be read as %s: it is not on the bus, or the bus grants this account no "+ "read of it (the manifests' callers and consumers are granted): %w", r.Store, c.cred.Module, err) } info, err := obs.GetInfo(ctx, r.Object) if errors.Is(err, jetstream.ErrObjectNotFound) { return nil, fmt.Errorf("the sent object %s is not in %s: it is kept 7 days, then expires", r.Object, r.Store) } if err != nil { return nil, fmt.Errorf("the sent object %s of %s: %w", r.Object, r.Store, err) } data, err := obs.GetBytes(ctx, r.Object) if err != nil { return nil, fmt.Errorf("the sent object %s of %s: %w", r.Object, r.Store, err) } return &buscalls.ObjectData{Info: objectInfoOf(info), Data: data}, nil }