diff --git a/cmd/device-hub-cli/cmd_create.go b/cmd/device-hub-cli/cmd_create.go index 5293891..9e220de 100644 --- a/cmd/device-hub-cli/cmd_create.go +++ b/cmd/device-hub-cli/cmd_create.go @@ -4,15 +4,9 @@ package main import ( "context" - "strings" - "github.com/fiorix/protoc-gen-cobra/iocodec" "github.com/spf13/cobra" - "github.com/thingful/device-hub/describe" - "github.com/thingful/device-hub/endpoint" - "github.com/thingful/device-hub/listener" "github.com/thingful/device-hub/proto" - "github.com/thingful/device-hub/registry" ) var createCommand = &cobra.Command{ @@ -20,55 +14,50 @@ var createCommand = &cobra.Command{ Short: "Create listener, endpoint and profile resources", RunE: func(cmd *cobra.Command, args []string) error { - /* TODO : add ability to generate examples */ - sample := proto.CreateRequest{ - Configuration: map[string]string{}, + conn, client, err := dial() + if err != nil { + return err } + defer conn.Close() - err := roundTrip(sample, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - - v := proto.CreateRequest{} - - err := in.Decode(&v) - - if err != nil { - return err - } - - // validate the policy file before sending it over the wire - var params describe.Parameters - - register := registry.Default - - endpoint.Register(register) - listener.Register(register) - - switch strings.ToLower(v.Type) { - - case "listener": - params, err = register.DescribeListener(v.Kind) - case "endpoint": - params, err = register.DescribeEndpoint(v.Kind) - } - + for _, r := range _resources.R { + req := proto.CreateRequest{} + err := r.Raw.Decode(&req) if err != nil { return err } - - _, err = describe.NewValues(v.Configuration, params) - - if err != nil { - return err + if r.Data["type"] != "process" { + + err := describeValidate(req) + if err != nil { + return err + } + resp, err := client.Create(context.Background(), &req) + if err != nil { + return err + } + + err = _encoder.Encode(resp) + if err != nil { + return err + } + + } else { + + var conf processConf + err := r.Raw.Decode(&conf) + if err != nil { + return err + } + + err = startCall(conf, client) + if err != nil { + return err + } } - resp, err := cli.Create(context.Background(), &v) - if err != nil { - return err - } - - return out.Encode(resp) + } - }) - return err + return nil }, } diff --git a/cmd/device-hub-cli/cmd_delete.go b/cmd/device-hub-cli/cmd_delete.go index 40aecbf..62b2aa4 100644 --- a/cmd/device-hub-cli/cmd_delete.go +++ b/cmd/device-hub-cli/cmd_delete.go @@ -5,7 +5,6 @@ package main import ( "context" - "github.com/fiorix/protoc-gen-cobra/iocodec" "github.com/spf13/cobra" "github.com/thingful/device-hub/proto" ) @@ -15,28 +14,45 @@ var deleteCommand = &cobra.Command{ Short: "Delete listener, profile and endpoint resources", RunE: func(cmd *cobra.Command, args []string) error { - sample := proto.DeleteRequest{} + conn, client, err := dial() + if err != nil { + return err + } + defer conn.Close() - err := roundTrip(sample, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - - v := proto.DeleteRequest{} - - err := in.Decode(&v) + _resources.Reverse() + for _, r := range _resources.R { + req := proto.DeleteRequest{} + err := r.Raw.Decode(&req) if err != nil { return err } - - resp, err := cli.Delete(context.Background(), &v) - - if err != nil { - return err + if r.Data["type"] != "process" { + resp, err := client.Delete(context.Background(), &req) + if err != nil { + return err + } + + err = _encoder.Encode(resp) + if err != nil { + return err + } + + } else { + var conf processConf + err := r.Raw.Decode(&conf) + if err != nil { + return err + } + err = stopCall(conf.URI, client) + if err != nil { + return err + } } - return out.Encode(resp) - - }) + } - return err + return nil }, } diff --git a/cmd/device-hub-cli/cmd_pipe.go b/cmd/device-hub-cli/cmd_pipe.go deleted file mode 100644 index 54cefdc..0000000 --- a/cmd/device-hub-cli/cmd_pipe.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright © 2017 thingful - -package main - -import ( - "context" - "errors" - "fmt" - "strings" - - "github.com/fiorix/protoc-gen-cobra/iocodec" - "github.com/spf13/cobra" - "github.com/thingful/device-hub/proto" -) - -func startCommand() *cobra.Command { - - request := proto.StartRequest{ - Endpoints: []string{}, - Tags: map[string]string{}, - } - - tags := []string{} - - startCommand := &cobra.Command{ - Use: "start", - Short: "Start processing messages on a uri", - RunE: func(cmd *cobra.Command, args []string) error { - - if len(args) == 0 { - return errors.New("specify a profile") - } - - request.Profile = args[0] - - for _, m := range tags { - - bits := strings.Split(m, ":") - - if len(bits) != 2 { - return fmt.Errorf("metadata not colon (:) separated : %s", m) - } - - request.Tags[bits[0]] = bits[1] - } - - err := roundTrip(request, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - - resp, err := cli.Start(context.Background(), &request) - - if err != nil { - return err - } - - return out.Encode(resp) - - }) - return err - }, - } - - startCommand.Flags().StringVarP(&request.Listener, "listener", "l", request.Listener, "listener uid to accept messages on") - startCommand.Flags().StringVarP(&request.Uri, "uri", "u", request.Uri, "uri to listen on") - startCommand.Flags().StringSliceVarP(&request.Endpoints, "endpoint", "e", request.Endpoints, "endpoint uid to push messages to, may be specified multiple times") - startCommand.Flags().StringSliceVarP(&tags, "tags", "t", tags, "colon separated (k:v) runtime tags to attach to requests, may be specified multiple times") - - return startCommand -} - -var stopCommand = &cobra.Command{ - Use: "stop", - Short: "Stop processing messages on a uri", - RunE: func(cmd *cobra.Command, args []string) error { - - v := proto.StopRequest{} - - err := roundTrip(v, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - if len(args) == 0 { - return errors.New("specify a uri to stop") - } - - v.Uri = strings.TrimSpace(args[0]) - - resp, err := cli.Stop(context.Background(), &v) - - if err != nil { - return err - } - - return out.Encode(resp) - - }) - return err - }, -} - -var statusCommand = &cobra.Command{ - Use: "status", - Short: "List running pipes", - RunE: func(cmd *cobra.Command, args []string) error { - - v := proto.StatusRequest{} - - err := roundTrip(v, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - - resp, err := cli.Status(context.Background(), &v) - - if err != nil { - return err - } - - return out.Encode(resp) - - }) - return err - }, -} diff --git a/cmd/device-hub-cli/cmd_process.go b/cmd/device-hub-cli/cmd_process.go new file mode 100644 index 0000000..a3863da --- /dev/null +++ b/cmd/device-hub-cli/cmd_process.go @@ -0,0 +1,168 @@ +// Copyright © 2017 thingful + +package main + +import ( + "context" + "fmt" + "strings" + + "github.com/spf13/cobra" + "github.com/thingful/device-hub/proto" +) + +func startCommand() *cobra.Command { + + startCommand := &cobra.Command{ + Use: "start", + Short: "Start processing messages on a uri", + RunE: func(cmd *cobra.Command, args []string) error { + var profile string + conn, client, err := dial() + if err != nil { + return err + } + defer conn.Close() + + if len(args) != 0 { + profile = strings.TrimSpace(args[0]) + } + if _config.RequestFile != "" { + + r := resource{} + err = r.Load(_config.RequestFile) + if err != nil { + return err + } + + err := r.Raw.Decode(&_config.ProcessFile) + if err != nil { + return err + } + } + return startCall(processConf{ProfileUID: profile}, client) + }, + } + + startCommand.Flags().StringVarP(&_config.ProcessFile.ListenerUID, "listener", "l", _config.ProcessFile.ListenerUID, "listener uid to accept messages on") + startCommand.Flags().StringVarP(&_config.ProcessFile.URI, "uri", "u", _config.ProcessFile.URI, "uri to listen on") + startCommand.Flags().StringSliceVarP(&_config.ProcessFile.EndpointUIDs, "endpoint", "e", _config.ProcessFile.EndpointUIDs, "endpoint uid to push messages to, may be specified multiple times") + startCommand.Flags().StringSliceVarP(&_config.ProcessFile.Tags, "tags", "t", _config.ProcessFile.Tags, "colon separated (k:v) runtime tags to attach to requests, may be specified multiple times") + + return startCommand +} + +func startCall(conf processConf, client proto.HubClient) error { + req := proto.StartRequest{ + Tags: map[string]string{}, + } + + req.Profile = conf.ProfileUID + if req.Profile == "" { + req.Profile = _config.ProcessFile.ProfileUID + } + req.Listener = conf.ListenerUID + if req.Listener == "" { + req.Listener = _config.ProcessFile.ListenerUID + } + + req.Uri = conf.URI + if req.Uri == "" { + req.Uri = _config.ProcessFile.URI + } + req.Endpoints = conf.EndpointUIDs + if len(req.Endpoints) == 0 { + req.Endpoints = _config.ProcessFile.EndpointUIDs + } + + var tags []string + + if len(conf.Tags) != 0 { + tags = conf.Tags + } else { + tags = _config.ProcessFile.Tags + } + + for _, m := range tags { + bits := strings.Split(m, ":") + if len(bits) != 2 { + return fmt.Errorf("metadata not colon (:) separated : %s", m) + } + req.Tags[bits[0]] = bits[1] + } + + resp, err := client.Start(context.Background(), &req) + if err != nil { + return err + } + + return _encoder.Encode(resp) +} + +var stopCommand = &cobra.Command{ + Use: "stop", + Short: "Stop processing messages on a uri", + RunE: func(cmd *cobra.Command, args []string) error { + var uri string + + if len(args) != 0 { + uri = strings.TrimSpace(args[0]) + } + + conn, client, err := dial() + if err != nil { + return err + } + defer conn.Close() + + if _config.RequestFile != "" { + r := resource{} + + err = r.Load(_config.RequestFile) + if err != nil { + return err + } + + err = r.Raw.Decode(&_config.ProcessFile) + if err != nil { + return err + } + uri = _config.ProcessFile.URI + } + return stopCall(uri, client) + + }, +} + +func stopCall(uri string, client proto.HubClient) error { + req := proto.StopRequest{ + Uri: strings.TrimSpace(uri), + } + resp, err := client.Stop(context.Background(), &req) + if err != nil { + return err + } + return _encoder.Encode(resp) +} + +var statusCommand = &cobra.Command{ + Use: "status", + Short: "List running pipes", + RunE: func(cmd *cobra.Command, args []string) error { + req := proto.StatusRequest{} + + conn, client, err := dial() + if err != nil { + return err + } + defer conn.Close() + + resp, err := client.Status(context.Background(), &req) + + if err != nil { + return err + } + + return _encoder.Encode(resp) + }, +} diff --git a/cmd/device-hub-cli/cmd_show.go b/cmd/device-hub-cli/cmd_show.go index 8f86b9c..f7ef7d6 100644 --- a/cmd/device-hub-cli/cmd_show.go +++ b/cmd/device-hub-cli/cmd_show.go @@ -6,7 +6,6 @@ import ( "context" "strings" - "github.com/fiorix/protoc-gen-cobra/iocodec" "github.com/spf13/cobra" "github.com/thingful/device-hub/proto" ) @@ -15,23 +14,21 @@ var showCommand = &cobra.Command{ Use: "show", Short: "Display one or many resources", RunE: func(cmd *cobra.Command, args []string) error { - - v := proto.ShowRequest{ + req := proto.ShowRequest{ Filter: strings.Join(args, ","), } - err := roundTrip(v, func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error { - - resp, err := cli.Show(context.Background(), &v) - - if err != nil { - return err - } - - return out.Encode(resp) + conn, client, err := dial() + if err != nil { + return err + } + defer conn.Close() - }) + resp, err := client.Show(context.Background(), &req) + if err != nil { + return err + } - return err + return _encoder.Encode(resp) }, } diff --git a/cmd/device-hub-cli/helpers.go b/cmd/device-hub-cli/helpers.go index ceb2d41..b95dc71 100644 --- a/cmd/device-hub-cli/helpers.go +++ b/cmd/device-hub-cli/helpers.go @@ -8,12 +8,13 @@ import ( "fmt" "io/ioutil" "net" - "os" - "path" - "path/filepath" + "strings" - "github.com/fiorix/protoc-gen-cobra/iocodec" + "github.com/thingful/device-hub/describe" + "github.com/thingful/device-hub/endpoint" + "github.com/thingful/device-hub/listener" "github.com/thingful/device-hub/proto" + "github.com/thingful/device-hub/registry" "golang.org/x/oauth2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -108,114 +109,31 @@ func dial() (*grpc.ClientConn, proto.HubClient, error) { return conn, proto.NewHubClient(conn), nil } -type roundTripFunc func(cli proto.HubClient, in iocodec.Decoder, out iocodec.Encoder) error +// describeValidate validate the policy file before sending it over the wire +func describeValidate(v proto.CreateRequest) (err error) { + var params describe.Parameters -func roundTrip(sample interface{}, fn roundTripFunc) error { - cfg := _config - - var em iocodec.EncoderMaker - var ok bool + register := registry.Default - if cfg.ResponseFormat == "" { - em = iocodec.DefaultEncoders["json"] - } else { + endpoint.Register(register) + listener.Register(register) - em, ok = iocodec.DefaultEncoders[cfg.ResponseFormat] - if !ok { - return fmt.Errorf("invalid response format: %q", cfg.ResponseFormat) - } - } + switch strings.ToLower(v.Type) { - if cfg.PrintSampleRequest { - return em.NewEncoder(os.Stdout).Encode(sample) + case "listener": + params, err = register.DescribeListener(v.Kind) + case "endpoint": + params, err = register.DescribeEndpoint(v.Kind) } - decoders := []iocodec.Decoder{} - files := []*os.File{} - - // either no request file is not specified or set to std-in - if (cfg.RequestFile == "" && cfg.RequestDir == "") || cfg.RequestFile == "-" { - decoders = append(decoders, iocodec.DefaultDecoders["json"].NewDecoder(os.Stdin)) - - // or request file is specified - } else if cfg.RequestFile != "" { - - f, d, err := decoderFromPath(cfg.RequestFile) - - if err != nil { - return err - } - - decoders = append(decoders, d) - files = append(files, f) - - // or request dir is specified - } else if cfg.RequestDir != "" { - listing, err := ioutil.ReadDir(cfg.RequestDir) - - if err != nil { - return err - } - - for _, fi := range listing { - - fmt.Println(fi.Name()) - - folderPath := path.Join(cfg.RequestDir, fi.Name()) - f, d, err := decoderFromPath(folderPath) - - if err != nil { - return err - } - - decoders = append(decoders, d) - files = append(files, f) - - } - } - - defer func() { - for i, _ := range files { - files[i].Close() - } - }() - - conn, client, err := dial() if err != nil { return err } - defer conn.Close() - - for _, d := range decoders { - err := fn(client, d, em.NewEncoder(os.Stdout)) + _, err = describe.NewValues(v.Configuration, params) - if err != nil { - return err - } - } - - return nil -} - -func decoderFromPath(filePath string) (*os.File, iocodec.Decoder, error) { - - f, err := os.Open(filePath) if err != nil { - return nil, nil, fmt.Errorf("request file: %v", err) - } - - ext := filepath.Ext(filePath) - - if len(ext) > 0 && ext[0] == '.' { - ext = ext[1:] - if ext != "yaml" { - return nil, nil, fmt.Errorf("invalid request file format: %q", ext) - - } + return err } - - dm, _ := iocodec.DefaultDecoders["yaml"] - - return f, dm.NewDecoder(f), nil + return nil } diff --git a/cmd/device-hub-cli/main.go b/cmd/device-hub-cli/main.go index ac36c9c..905f7f2 100644 --- a/cmd/device-hub-cli/main.go +++ b/cmd/device-hub-cli/main.go @@ -6,6 +6,7 @@ import ( "os" "time" + "github.com/fiorix/protoc-gen-cobra/iocodec" "github.com/kelseyhightower/envconfig" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -17,13 +18,21 @@ import ( var RootCmd = &cobra.Command{ Use: "device-hub-cli", + PersistentPreRunE: func(cmd *cobra.Command, args []string) error { + // Set resources at CLI init + return _resources.SetResources(_config) + }, } // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. const _ = grpc.SupportPackageIsVersion4 -var _config = newConfig() +var ( + _config = newConfig() + _resources = newResources() + _encoder iocodec.Encoder +) type config struct { ServerAddr string `envconfig:"SERVER_ADDR" default:"127.0.0.1:50051"` @@ -42,6 +51,7 @@ type config struct { AuthTokenType string `envconfig:"AUTH_TOKEN_TYPE" default:"Bearer"` JWTKey string `envconfig:"JWT_KEY"` JWTKeyFile string `envconfig:"JWT_KEY_FILE"` + ProcessFile processConf } func newConfig() *config { @@ -81,6 +91,10 @@ func init() { RootCmd.AddCommand(describeCommand) _config.AddFlags(RootCmd.PersistentFlags()) + + // global encoder + em := iocodec.DefaultEncoders["json"] + _encoder = em.NewEncoder(os.Stdout) } func main() { diff --git a/cmd/device-hub-cli/resources.go b/cmd/device-hub-cli/resources.go new file mode 100644 index 0000000..001f9e9 --- /dev/null +++ b/cmd/device-hub-cli/resources.go @@ -0,0 +1,133 @@ +// Copyright © 2017 thingful + +package main + +import ( + "fmt" + "io/ioutil" + "path" + "path/filepath" + "sort" + + yaml "gopkg.in/yaml.v2" +) + +type rawContent []byte + +func (r rawContent) Decode(target interface{}) error { + err := yaml.Unmarshal(r, target) + if err != nil { + return fmt.Errorf("error decoding data: %s", err.Error()) + } + return nil +} + +// resource Represent a resource file, Data is basically used to order a resourceSlice +// Raw contains the file content +type resource struct { + FileName string + Data map[string]interface{} + Raw rawContent +} + +// Load the configuration file to Data +func (r *resource) Load(filePath string) (err error) { + r.Raw, err = ioutil.ReadFile(filePath) + if err != nil { + return fmt.Errorf("failed to read file [%s]: %s", filePath, err.Error()) + } + + _, r.FileName = filepath.Split(filePath) + + err = r.Raw.Decode(&r.Data) + if err != nil { + return fmt.Errorf("error parsing file [%s]: %s", filePath, err.Error()) + } + return nil +} + +// resources store appended resource files +type resources struct { + R []resource +} + +func newResources() *resources { + return &resources{} +} + +func (r *resources) Append(e resource) { + + r.R = append(r.R, e) +} + +func (r resources) Len() int { + return len(r.R) +} + +func (r resources) Less(i, j int) bool { + return r.R[j].Data["type"] == "process" +} + +func (r resources) Swap(i, j int) { + r.R[i], r.R[j] = r.R[j], r.R[i] +} + +// Sort is required to put processes at the end when executing create cmd +func (r resources) Sort() { + sort.Sort(resources(r)) +} + +// Reverse is required to put processes at first to stop them before delete resources +func (r resources) Reverse() { + sort.Sort(sort.Reverse(resources(r))) +} + +func (r resources) Print() { + for _, f := range r.R { + fmt.Println(f.FileName) + } +} + +// SetResources get cli passed resources +func (r *resources) SetResources(cfg *config) error { + var res resource + if cfg.RequestFile != "" { + err := res.Load(cfg.RequestFile) + if err != nil { + return err + } + r.Append(res) + return nil + + } else if cfg.RequestDir != "" { + listing, err := ioutil.ReadDir(cfg.RequestDir) + if err != nil { + return err + } + + for _, f := range listing { + folderPath := path.Join(cfg.RequestDir, f.Name()) + var _res resource // check if this could be outer scoped! (conf) + err = _res.Load(folderPath) + if err != nil { + return err + } + r.Append(_res) + } + } + // Sorted with process to the end by default + r.Sort() + // TODO validate? + r.Print() + return nil +} + +// processConf holds required data to start a process +type processConf struct { + URI string `yaml:"uri"` + Type string `yaml:"type"` + EndpointUIDs []string `yaml:"endpoint-uids"` + ListenerUID string `yaml:"listener-uid"` + ProfileUID string `yaml:"profile-uid"` + Tags []string `yaml:"tags"` +} diff --git a/docs/client.md b/docs/client.md index 3ae0a9a..39b4843 100644 --- a/docs/client.md +++ b/docs/client.md @@ -15,38 +15,38 @@ Client CLI Commands ========================= ``` - Command Name: create [-d|-f]= - Description: Creates Listeners, Endpoints and Profile resources + Description: Creates Listeners, Endpoints, Profile resources and start process if -d flag is used Flags: - Flag: -d Large Format: --request-dir Is required: Yes if -f isn't specified - Description: Directory containing client request file(s) (must be json, yaml, or xml) - Parameter: A filesystem path + Description: Directory containing client yaml request file(s) + Parameter: A filesystem path with valid yaml resources and processes files Example: device-hub-cli create -d=./test-configurations/ - Flag: -f Large Format: --request-file Is required: Yes if -d isn't specified - Description: Client request file (must be json, yaml, or xml); use "-" for stdin + json - Parameter: Directory containing client request file(s) (must be json, yaml, or xml) + Description: Client yaml request file + Parameter: Path containing client request file(s) (must be yaml) Example: device-hub-cli create -f=./test-configurations/mqtt_listener.yaml - Command Name: delete [-d|-f]= - Description: Delete listener, profile and endpoint resources + Description: Delete listener, profile, endpoint resources and stop processes if process files are specified Flags: - Flag: -d Large Format: --request-dir Is required: Yes if -f isn't specified - Description: Directory containing client request file(s) (must be json, yaml, or xml) + Description: Directory containing client yaml request file(s) Parameter: A filesystem path Example: device-hub-cli delete -d=./test-configurations/ - Flag: -f Large Format: --request-file Is required: Yes if -d isn't specified - Description: Client request file (must be json, yaml, or xml); use "-" for stdin + json - Parameter: Directory containing client request file(s) (must be json, yaml, or xml) + Description: Client request yaml file + Parameter: Directory containing client request file(s) Example: device-hub-cli delete -f=./test-configurations/mqtt_listener.yaml @@ -64,27 +64,33 @@ Client CLI Commands Description: List running pipes -- Command Name: start [-e -l -u ] +- Command Name: start [-f ] [-e -l -u ] Description: Start processing messages on an URI Flags: + - Flag: -f + Description: Start processing messages using a yaml config file + Large Format: --request-file + Is required: No + - Flag: -e Description: Endpoint uid to push messages to, may be specified multiple times Large Format: --endpoint - Is required: Yes + Is required: Yes if -f isn't specified - Flag: -l Description: Listener uid to accept messages on Large Format: --listener - Is required: Yes + Is required: Yes if -f isn't specified - Flag: -u Description: Uri to listen on Large Format: --uri - Is required: Yes + Is required: Yes if -f isn't specified - Flag: -t Description: Colon separated (k:v) runtime tags to attach to requests, may be specified multiple times Large Format: --tags + Is required: Yes if -f isn't specified Example: device-hub-cli start -e=stdout-endpoint -l=http-listener-local-port-8085 -u=/a thingful/helsinki-bus @@ -116,10 +122,6 @@ CLI Global Flags Description: response format (json, prettyjson, yaml, or xml) Default: json -- Flag: -p - Large Format: --print-sample-request - Description: Print sample request file and exit - - Flag: --timeout Description: Client connection timeout Default: 10s diff --git a/examples/config/helsinki_process.yaml b/examples/config/helsinki_process.yaml new file mode 100644 index 0000000..57906d7 --- /dev/null +++ b/examples/config/helsinki_process.yaml @@ -0,0 +1,8 @@ +uri: /b +type: process +endpoint-uids: + - stdout-endpoint +listener-uid: mqtt-helsinki-transport-service-listener +profile-uid: thingful/helsinki-bus +tags: + - foo:bar \ No newline at end of file diff --git a/examples/config/http_listener_process.yaml b/examples/config/http_listener_process.yaml new file mode 100644 index 0000000..e437d57 --- /dev/null +++ b/examples/config/http_listener_process.yaml @@ -0,0 +1,8 @@ +uri: /a +type: process +endpoint-uids: + - http-endpoint-example.com +listener-uid: http-listener-local-port-8085 +profile-uid: thingful/device-1 +tags: + - foo:bar \ No newline at end of file diff --git a/examples/config_test.go b/examples/config_test.go index 2bbfb56..5cb9efc 100644 --- a/examples/config_test.go +++ b/examples/config_test.go @@ -49,9 +49,12 @@ func TestConfigurationFilesAreValid(t *testing.T) { err = in.Decode(&entity) assert.Nil(t, err) - assert.NotEmpty(t, entity.Kind) assert.NotEmpty(t, entity.Type) + if strings.ToLower(entity.Type) != "process" { + assert.NotEmpty(t, entity.Kind) + } + var params describe.Parameters switch strings.ToLower(entity.Type) {