Documentation
¶
Index ¶
- Constants
- Variables
- func CreateTypeSet(ts map[string]px.Type) px.TypeSet
- func FederatedLoader(parentLoader px.Loader) px.Loader
- func NewSubService(def serviceapi.Definition) serviceapi.Service
- type Builder
- func (ds *Builder) BuildResource(goType interface{}, bld func(f ResourceTypeBuilder)) px.AnnotatedType
- func (ds *Builder) RegisterAPI(name string, callable interface{})
- func (ds *Builder) RegisterApiType(name string, callable interface{})
- func (ds *Builder) RegisterHandler(name string, callable interface{}, stateType px.Type)
- func (ds *Builder) RegisterState(name string, state wf.State)
- func (ds *Builder) RegisterStateConverter(sf wf.StateConverter)
- func (ds *Builder) RegisterStep(step wf.Step)
- func (ds *Builder) RegisterType(typ px.Type)
- func (ds *Builder) RegisterTypes(namespace string, values ...interface{}) []px.Type
- func (ds *Builder) Server() *Server
- type ResourceTypeBuilder
- type Server
- func (s *Server) AddApi(name string, callable interface{}) serviceapi.Definition
- func (s *Server) Identifier(px.Context) px.TypedName
- func (s *Server) Invoke(c px.Context, api, name string, arguments ...px.Value) (result px.Value)
- func (s *Server) Metadata(px.Context) (typeSet px.TypeSet, definitions []serviceapi.Definition)
- func (s *Server) State(c px.Context, name string, parameters px.OrderedMap) px.PuppetObject
Examples ¶
Constants ¶
const ( AlreadyRegistered = `WF_ALREADY_REGISTERED` ApiTypeNotRegistered = `WF_API_TYPE_NOT_REGISTERED` IllegalTypeName = `WF_ILLEGAL_TYPE_NAME` NoCommonNamespace = `WF_NO_COMMON_NAMESPACE` NoSuchApi = `WF_NO_SUCH_API` NoSuchMethod = `WF_NO_SUCH_METHOD` NoSuchState = `WF_NO_SUCH_STATE` NotFound = `WF_NOT_FOUND` NotFunc = `WF_NOT_FUNC` NotPuppetObject = `WF_NOT_PUPPET_OBJECT` NoStateConverter = `WF_NO_STATE_CONVERTER` TypeNameClash = `WF_TYPE_NAME_CLASH` )
Variables ¶
var ErrorMetaType px.ObjectType
var ParameterMetaType px.ObjectType
var ServerVersion = semver.MustParseVersion(`0.1.0`)
Functions ¶
func FederatedLoader ¶
New creates a new federated loader instance
func NewSubService ¶
func NewSubService(def serviceapi.Definition) serviceapi.Service
Types ¶
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
func (*Builder) BuildResource ¶
func (ds *Builder) BuildResource(goType interface{}, bld func(f ResourceTypeBuilder)) px.AnnotatedType
func (*Builder) RegisterAPI ¶
RegisterAPI registers a struct as an invokable. The callable instance given as the argument becomes the actual receiver the calls.
func (*Builder) RegisterApiType ¶
RegisterAPIType registers a the type of a struct as an invokable type. The struct should be a zero value. This method must be used to ensure that all type info is present for callable instances added to an already created service
func (*Builder) RegisterHandler ¶
RegisterHandler registers a callable struct as an invokable capable of handling a state described using px.Type. The callable instance given as the argument becomes the actual receiver the calls.
func (*Builder) RegisterState ¶
RegisterState registers the unresolved state of a resource.
func (*Builder) RegisterStateConverter ¶
func (ds *Builder) RegisterStateConverter(sf wf.StateConverter)
func (*Builder) RegisterStep ¶
RegisterStep registers an step
func (*Builder) RegisterType ¶
func (*Builder) RegisterTypes ¶
RegisterTypes registers arbitrary Go types to the TypeSet exported by this service.
A value is typically a pointer to the zero value of a struct. The name of the generated type for that struct will be the struct name prefixed by the service ID.
Example (AnnotatedTypeSet) ¶
package main import ( "bytes" "fmt" "os" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/pcore/serialization" "github.com/lyraproj/pcore/types" "github.com/lyraproj/servicesdk/annotation" "github.com/lyraproj/servicesdk/service" ) type OwnerRes struct { Id *string Phone string } type ContainedRes struct { Id *string OwnerId string Stuff string } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterTypes("My", sb.BuildResource(&OwnerRes{}, func(rtb service.ResourceTypeBuilder) { rtb.ProvidedAttributes(`id`) rtb.ImmutableAttributes(`telephoneNumber`) rtb.Tags(map[string]string{`Phone`: `name=>telephoneNumber`}) rtb.AddRelationship(`mine`, `My::ContainedRes`, annotation.KindContained, annotation.CardinalityMany, ``, []string{`id`, `ownerId`}) }), sb.BuildResource(&ContainedRes{}, func(rtb service.ResourceTypeBuilder) { rtb.ProvidedAttributes(`id`) rtb.AddRelationship(`owner`, `My::OwnerRes`, annotation.KindContainer, annotation.CardinalityOne, ``, []string{`ownerId`, `id`}) }), ) s := sb.Server() ts, md := s.Metadata(c) bld := bytes.NewBufferString(``) coll := serialization.NewJsonStreamer(bld) sr := serialization.NewSerializer(pcore.RootContext(), px.EmptyMap) sr.Convert(types.WrapValues([]px.Value{ts, px.Wrap(c, md)}), coll) dr := serialization.NewDeserializer(c, px.EmptyMap) serialization.JsonToData(`/tmp/tst`, bld, dr) dt := dr.Value().(*types.Array) dt.At(0).ToString(os.Stdout, px.PrettyExpanded, nil) fmt.Println() }) }
Output: TypeSet[{ pcore_uri => 'http://puppet.com/2016.1/pcore', pcore_version => '1.0.0', name_authority => 'http://puppet.com/2016.1/runtime', name => 'My', version => '0.1.0', types => { ContainedRes => { annotations => { Lyra::Resource => { 'providedAttributes' => ['id'], 'relationships' => { 'owner' => { 'type' => OwnerRes, 'kind' => 'container', 'cardinality' => 'one', 'keys' => ['ownerId', 'id'] } } } }, attributes => { 'id' => Optional[String], 'ownerId' => String, 'stuff' => String } }, OwnerRes => { annotations => { Lyra::Resource => { 'immutableAttributes' => ['telephoneNumber'], 'providedAttributes' => ['id'], 'relationships' => { 'mine' => { 'type' => ContainedRes, 'kind' => 'contained', 'cardinality' => 'many', 'keys' => ['id', 'ownerId'] } } } }, attributes => { 'id' => Optional[String], 'telephoneNumber' => String } } } }]
Example (NestedType) ¶
package main import ( "fmt" "os" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type MyRes struct { Name string Phone string } type MyOuterRes struct { Who *MyRes What string } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterTypes("My", &MyOuterRes{}) s := sb.Server() ts, _ := s.Metadata(c) ts.ToString(os.Stdout, px.PrettyExpanded, nil) fmt.Println() }) }
Output: TypeSet[{ pcore_uri => 'http://puppet.com/2016.1/pcore', pcore_version => '1.0.0', name_authority => 'http://puppet.com/2016.1/runtime', name => 'My', version => '0.1.0', types => { MyOuterRes => { attributes => { 'who' => Optional[MyRes], 'what' => String } }, MyRes => { attributes => { 'name' => String, 'phone' => String } } } }]
Example (RecursiveType) ¶
package main import ( "fmt" "os" "time" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type MyRes struct { Name string Phone string } type Person struct { Who *MyRes Children []*Person Born time.Time } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterTypes("My", &Person{}) s := sb.Server() ts, _ := s.Metadata(c) ts.ToString(os.Stdout, px.PrettyExpanded, nil) fmt.Println() }) }
Output: TypeSet[{ pcore_uri => 'http://puppet.com/2016.1/pcore', pcore_version => '1.0.0', name_authority => 'http://puppet.com/2016.1/runtime', name => 'My', version => '0.1.0', types => { MyRes => { attributes => { 'name' => String, 'phone' => String } }, Person => { attributes => { 'who' => Optional[MyRes], 'children' => Array[Optional[Person]], 'born' => Timestamp } } } }]
type ResourceTypeBuilder ¶
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) AddApi ¶
func (s *Server) AddApi(name string, callable interface{}) serviceapi.Definition
func (*Server) Invoke ¶
Example ¶
package main import ( "fmt" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type testAPI struct{} func (*testAPI) First() string { return `first` } func (*testAPI) Second(suffix string) string { return `second ` + suffix } func main() { pcore.Do(func(c px.Context) { api := `My::TheApi` sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterAPI(api, &testAPI{}) s := sb.Server() fmt.Println(s.Invoke(c, api, `first`)) fmt.Println(s.Invoke(c, api, `second`, px.Wrap(c, `place`))) }) }
Output: first second place
func (*Server) Metadata ¶
func (s *Server) Metadata(px.Context) (typeSet px.TypeSet, definitions []serviceapi.Definition)
Example (Api) ¶
package main import ( "fmt" "os" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" "github.com/lyraproj/servicesdk/wf" ) type MyIdentityService struct { extToId map[string]px.URI idToExt map[px.URI]string } func (is *MyIdentityService) GetExternal(id px.URI) (string, error) { if ext, ok := is.idToExt[id]; ok { return ext, nil } return ``, wf.NotFound } func (is *MyIdentityService) GetInternal(ext string) (px.URI, error) { if id, ok := is.extToId[ext]; ok { return id, nil } return px.URI(``), wf.NotFound } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterAPI(`My::Identity`, &MyIdentityService{map[string]px.URI{}, map[px.URI]string{}}) s := sb.Server() ts, defs := s.Metadata(c) ts.ToString(os.Stdout, px.PrettyExpanded, nil) fmt.Println() for _, def := range defs { fmt.Println(px.ToPrettyString(def)) } }) }
Output: TypeSet[{ pcore_uri => 'http://puppet.com/2016.1/pcore', pcore_version => '1.0.0', name_authority => 'http://puppet.com/2016.1/runtime', name => 'My', version => '0.1.0', types => { Identity => { functions => { 'getExternal' => Callable[ [String], String], 'getInternal' => Callable[ [String], String] } } } }] Service::Definition( 'identifier' => TypedName( 'namespace' => 'definition', 'name' => 'My::Identity' ), 'serviceId' => TypedName( 'namespace' => 'service', 'name' => 'My::Service' ), 'properties' => { 'interface' => My::Identity, 'style' => 'callable' } )
Example (Definitions) ¶
package main import ( "fmt" "github.com/lyraproj/issue/issue" "github.com/lyraproj/servicesdk/lang/go/lyra" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type MyRes struct { Name string Phone string } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterTypes("My", &MyRes{}) sb.RegisterStep((&lyra.Workflow{ Steps: map[string]lyra.Step{ `X`: &lyra.Resource{ State: func(struct { A string B string `lookup:"foo"` C int `puppet:"value=>23"` D *string `puppet:"value=>undef"` E *string F *string `value:"77"` }) *MyRes { return &MyRes{Name: `Bob`, Phone: `12345`} }}, `Y`: &lyra.Call{ Parameters: struct { P string `lookup:"foo" alias:"B"` }{}, StepName: `z`, }}}).Resolve(c, `My::Test`, issue.ParseLocation(`(file: /test/x.go)`))) s := sb.Server() _, defs := s.Metadata(c) for _, def := range defs { fmt.Println(px.ToPrettyString(def)) } }) }
Output: Service::Definition( 'identifier' => TypedName( 'namespace' => 'definition', 'name' => 'My::Test' ), 'serviceId' => TypedName( 'namespace' => 'service', 'name' => 'My::Service' ), 'properties' => { 'steps' => [ Service::Definition( 'identifier' => TypedName( 'namespace' => 'definition', 'name' => 'My::Test::X' ), 'serviceId' => TypedName( 'namespace' => 'service', 'name' => 'My::Service' ), 'properties' => { 'parameters' => [ Lyra::Parameter( 'name' => 'a', 'type' => String ), Lyra::Parameter( 'name' => 'b', 'type' => String, 'value' => Deferred( 'name' => 'lookup', 'arguments' => ['foo'] ) ), Lyra::Parameter( 'name' => 'c', 'type' => Integer, 'value' => 23 ), Lyra::Parameter( 'name' => 'd', 'type' => Optional[String] ), Lyra::Parameter( 'name' => 'e', 'type' => Optional[String] ), Lyra::Parameter( 'name' => 'f', 'type' => Optional[String], 'value' => '77' )], 'resourceType' => My::MyRes, 'style' => 'resource', 'origin' => '(file: /test/x.go)' } ), Service::Definition( 'identifier' => TypedName( 'namespace' => 'definition', 'name' => 'My::Test::Y' ), 'serviceId' => TypedName( 'namespace' => 'service', 'name' => 'My::Service' ), 'properties' => { 'parameters' => [ Lyra::Parameter( 'name' => 'p', 'type' => String, 'alias' => 'b', 'value' => Deferred( 'name' => 'lookup', 'arguments' => ['foo'] ) )], 'call' => 'z', 'style' => 'call', 'origin' => '(file: /test/x.go)' } )], 'style' => 'workflow', 'origin' => '(file: /test/x.go)' } )
Example (State) ¶
package main import ( "fmt" "github.com/lyraproj/issue/issue" "github.com/lyraproj/servicesdk/lang/go/lyra" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type MyRes struct { Name string Phone string } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterTypes("My", &MyRes{}) sb.RegisterStateConverter(lyra.StateConverter) sb.RegisterStep((&lyra.Workflow{ Steps: map[string]lyra.Step{ `X`: &lyra.Resource{ State: func(parameters struct { A string B string }) *MyRes { return &MyRes{Name: `Bob`, Phone: `12345`} }}}}).Resolve(c, `My::Test`, issue.ParseLocation(`(file: /test/x.go)`))) s := sb.Server() fmt.Println(px.ToPrettyString(s.State(c, `My::Test::X`, px.EmptyMap))) }) }
Output: My::MyRes( 'name' => 'Bob', 'phone' => '12345' )
Example (TypeSet) ¶
package main import ( "fmt" "os" "github.com/lyraproj/pcore/pcore" "github.com/lyraproj/pcore/px" "github.com/lyraproj/servicesdk/service" ) type testAPI struct{} func (*testAPI) First() string { return `first` } func (*testAPI) Second(suffix string) string { return `second ` + suffix } type MyRes struct { Name string Phone string } func main() { pcore.Do(func(c px.Context) { sb := service.NewServiceBuilder(c, `My::Service`) sb.RegisterAPI(`My::TheApi`, &testAPI{}) sb.RegisterTypes("My", &MyRes{}) s := sb.Server() ts, _ := s.Metadata(c) ts.ToString(os.Stdout, px.PrettyExpanded, nil) fmt.Println() }) }
Output: TypeSet[{ pcore_uri => 'http://puppet.com/2016.1/pcore', pcore_version => '1.0.0', name_authority => 'http://puppet.com/2016.1/runtime', name => 'My', version => '0.1.0', types => { MyRes => { attributes => { 'name' => String, 'phone' => String } }, TheApi => { functions => { 'first' => Callable[ [0, 0], String], 'second' => Callable[ [String], String] } } } }]
func (*Server) State ¶
func (s *Server) State(c px.Context, name string, parameters px.OrderedMap) px.PuppetObject