diff --git a/README.md b/README.md index e294fee..8e2052f 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ func initializeConfiguration(useRegistry bool, useProfile string) (*Configuratio } if useRegistry { - registryConfig := registry.Config{ + registryConfig := types.Config{ Host: conf.Registry.Host, Port: conf.Registry.Port, Type: conf.Registry.Type, @@ -49,7 +49,7 @@ func initializeConfiguration(useRegistry bool, useProfile string) (*Configuratio Stem: internal.ConfigRegistryStem, } - registryClient, err = factory.NewRegistryClient(registryConfig) + registryClient, err = registry.NewRegistryClient(registryConfig) if err != nil { return fmt.Errorf("connection to Registry could not be made: %v", err.Error()) } @@ -123,11 +123,12 @@ func listenForConfigChanges() { This code snippet shows how to get dependent service endpoint information and check status of the dependent service. ``` ... - if registry.Client != nil { - endpoint, err = registry.Client.GetServiceEndpoint(params.ServiceKey) + if e.RegistryClient != nil { + endpoint, err = (*e.RegistryClient).GetServiceEndpoint(params.ServiceKey) + ... url := fmt.Sprintf("http://%s:%v%s", endpoint.Address, endpoint.Port, params.Path) ... - if registry.Client.IsServiceAvailable(params.ServiceKey) { + if (*e.RegistryClient).IsServiceAvailable(params.ServiceKey) { ... } } diff --git a/internal/pkg/consul/client.go b/internal/pkg/consul/client.go index c33d3d2..e2bfc43 100644 --- a/internal/pkg/consul/client.go +++ b/internal/pkg/consul/client.go @@ -18,7 +18,7 @@ package consul import ( "fmt" - "github.com/edgexfoundry/go-mod-registry" + "github.com/edgexfoundry/go-mod-registry/pkg/types" consulapi "github.com/hashicorp/consul/api" "github.com/mitchellh/consulstructure" "github.com/pelletier/go-toml" @@ -46,7 +46,7 @@ type consulClient struct { } // Create new Consul Client. Service details are optional, not needed just for configuration, but required if registering -func NewConsulClient(registryConfig registry.Config,) (*consulClient, error) { +func NewConsulClient(registryConfig types.Config,) (*consulClient, error) { client := consulClient{ serviceKey: registryConfig.ServiceKey, @@ -280,13 +280,13 @@ func (client *consulClient) PutConfigurationValue(name string, value []byte) err } // Gets the service endpoint information for the target ID from Consul -func (client *consulClient) GetServiceEndpoint(serviceID string) (registry.ServiceEndpoint, error) { +func (client *consulClient) GetServiceEndpoint(serviceID string) (types.ServiceEndpoint, error) { services, err := client.consulClient.Agent().Services() if err != nil { - return registry.ServiceEndpoint{}, err + return types.ServiceEndpoint{}, err } - endpoint := registry.ServiceEndpoint{} + endpoint := types.ServiceEndpoint{} if service, ok := services[serviceID]; ok { endpoint.Port = service.Port endpoint.ServiceId = serviceID diff --git a/internal/pkg/consul/client_test.go b/internal/pkg/consul/client_test.go index f8ae4dd..c10a7c4 100644 --- a/internal/pkg/consul/client_test.go +++ b/internal/pkg/consul/client_test.go @@ -17,7 +17,6 @@ package consul import ( - "github.com/edgexfoundry/go-mod-registry" "log" "net/http" "net/http/httptest" @@ -31,6 +30,8 @@ import ( "github.com/hashicorp/consul/api" "github.com/pelletier/go-toml" "github.com/stretchr/testify/assert" + + "github.com/edgexfoundry/go-mod-registry/pkg/types" ) const ( @@ -55,7 +56,7 @@ type LoggingInfo struct { type MyConfig struct { Logging LoggingInfo - Service registry.ServiceEndpoint + Service types.ServiceEndpoint Port int Host string LogLevel string @@ -116,7 +117,7 @@ func TestHasConfigurationTrue(t *testing.T) { } // Now push a value so the configuration will exist - client.PutConfigurationValue("Dummy", []byte("Value")) + _ = client.PutConfigurationValue("Dummy", []byte("Value")) actual, err := client.HasConfiguration() if !assert.NoError(t, err) { @@ -164,7 +165,7 @@ func TestRegisterWithPingCallback(t *testing.T) { receivedPing = true writer.Header().Set("Content-Type", "text/plain") - writer.Write([]byte("pong")) + _,_ = writer.Write([]byte("pong")) doneChan <- true } @@ -178,13 +179,13 @@ func TestRegisterWithPingCallback(t *testing.T) { client := makeConsulClient(t, serverPort, true) // Make sure service is not already registered. - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) // Try to clean-up after test defer func(client *consulClient) { - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) }(client) // Register the service endpoint and health check callback @@ -203,8 +204,8 @@ func TestRegisterWithPingCallback(t *testing.T) { } func TestGetServiceEndpoint(t *testing.T) { - expectedNotFoundEndpoint := registry.ServiceEndpoint{} - expectedFoundEndpoint := registry.ServiceEndpoint{ + expectedNotFoundEndpoint := types.ServiceEndpoint{} + expectedFoundEndpoint := types.ServiceEndpoint{ ServiceId: serviceName, Host: serviceHost, Port: defaultServicePort, @@ -212,13 +213,13 @@ func TestGetServiceEndpoint(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure service is not already registered. - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) // Try to clean-up after test defer func(client *consulClient) { - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) }(client) // Test for endpoint not found @@ -251,8 +252,8 @@ func TestIsServiceAvailableNotRegistered(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure service is not already registered. - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) actual := client.IsServiceAvailable(client.serviceKey) if !assert.Error(t, actual, "expected error") { @@ -267,13 +268,13 @@ func TestIsServiceAvailableNotHealthy(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure service is not already registered. - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) // Try to clean-up after test defer func(client *consulClient) { - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) }(client) // Register the service endpoint, without test service to respond to health check @@ -303,7 +304,7 @@ func TestIsServiceAvailableHealthy(t *testing.T) { switch request.Method { case "GET": writer.Header().Set("Content-Type", "text/plain") - writer.Write([]byte("pong")) + _,_ = writer.Write([]byte("pong")) doneChan <- true } @@ -317,13 +318,13 @@ func TestIsServiceAvailableHealthy(t *testing.T) { client := makeConsulClient(t, serverPort, true) // Make sure service is not already registered. - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) // Try to clean-up after test defer func(client *consulClient) { - client.consulClient.Agent().ServiceDeregister(client.serviceKey) - client.consulClient.Agent().CheckDeregister(client.serviceKey) + _ = client.consulClient.Agent().ServiceDeregister(client.serviceKey) + _ = client.consulClient.Agent().CheckDeregister(client.serviceKey) }(client) // Register the service endpoint @@ -366,7 +367,7 @@ func TestConfigurationValueExists(t *testing.T) { if !assert.NoError(t, err) { t.Fatal() } - if !assert.Equal(t, expected, actual) { + if !assert.False(t, actual) { t.Fatal() } @@ -423,7 +424,7 @@ func TestPutConfigurationValue(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) //clean up the the key, if it exists - client.consulClient.KV().Delete(expectedFullKey, nil) + _,_ = client.consulClient.KV().Delete(expectedFullKey, nil) err := client.PutConfigurationValue(key, expected) assert.NoError(t, err) @@ -448,7 +449,7 @@ func TestGetConfiguration(t *testing.T) { EnableRemote: true, File: "NONE", }, - Service: registry.ServiceEndpoint{ + Service: types.ServiceEndpoint{ ServiceId: "Dummy", Host: "10.6.7.8", Port: 8080, @@ -460,14 +461,14 @@ func TestGetConfiguration(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) - client.PutConfigurationValue("Logging/EnableRemote", []byte(strconv.FormatBool(expected.Logging.EnableRemote))) - client.PutConfigurationValue("Logging/File", []byte(expected.Logging.File)) - client.PutConfigurationValue("Service/ServiceId", []byte(expected.Service.ServiceId)) - client.PutConfigurationValue("Service/Host", []byte(expected.Service.Host)) - client.PutConfigurationValue("Service/Port", []byte(strconv.Itoa(expected.Service.Port))) - client.PutConfigurationValue("Port", []byte(strconv.Itoa(expected.Port))) - client.PutConfigurationValue("Host", []byte(expected.Host)) - client.PutConfigurationValue("LogLevel", []byte(expected.LogLevel)) + _ = client.PutConfigurationValue("Logging/EnableRemote", []byte(strconv.FormatBool(expected.Logging.EnableRemote))) + _ = client.PutConfigurationValue("Logging/File", []byte(expected.Logging.File)) + _ = client.PutConfigurationValue("Service/ServiceId", []byte(expected.Service.ServiceId)) + _ = client.PutConfigurationValue("Service/Host", []byte(expected.Service.Host)) + _ = client.PutConfigurationValue("Service/Port", []byte(strconv.Itoa(expected.Service.Port))) + _ = client.PutConfigurationValue("Port", []byte(strconv.Itoa(expected.Port))) + _ = client.PutConfigurationValue("Host", []byte(expected.Host)) + _ = client.PutConfigurationValue("LogLevel", []byte(expected.LogLevel)) result, err := client.GetConfiguration(&MyConfig{}) @@ -497,7 +498,7 @@ func TestPutConfiguration(t *testing.T) { EnableRemote: true, File: "NONE", }, - Service: registry.ServiceEndpoint{ + Service: types.ServiceEndpoint{ ServiceId: "Dummy", Host: "10.6.7.8", Port: 8080, @@ -511,11 +512,11 @@ func TestPutConfiguration(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure the tree of values doesn't exist. - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) defer func() { // Clean up - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) }() err := client.PutConfiguration(expected, true) @@ -538,7 +539,7 @@ func TestPutConfiguration(t *testing.T) { assert.True(t,configValueSet("LogLevel", client)) } -func configValueSet(key string, client registry.Client) bool { +func configValueSet(key string, client *consulClient) bool { exists, _ := client.ConfigurationValueExists(key) return exists } @@ -547,11 +548,11 @@ func TestPutConfigurationTomlNoPreviousValues(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure the tree of values doesn't exist. - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) defer func() { // Clean up - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) }() configMap := createKeyValueMap() @@ -582,11 +583,11 @@ func TestPutConfigurationTomlWithoutOverWrite(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure the tree of values doesn't exist. - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) defer func() { // Clean up - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _ , _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) }() configMap := createKeyValueMap() @@ -629,10 +630,10 @@ func TestPutConfigurationTomlOverWrite(t *testing.T) { client := makeConsulClient(t, defaultServicePort, true) // Make sure the tree of values doesn't exist. - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _, _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) // Clean up after unit test defer func() { - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _, _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) }() configMap := createKeyValueMap() @@ -676,7 +677,7 @@ func TestWatchForChanges(t *testing.T) { EnableRemote: true, File: "NONE", }, - Service: registry.ServiceEndpoint{ + Service: types.ServiceEndpoint{ ServiceId: "Dummy", Host: "10.6.7.8", Port: 8080, @@ -691,20 +692,20 @@ func TestWatchForChanges(t *testing.T) { client := makeConsulClient(t, defaultServicePort, false) // Make sure the tree of values doesn't exist. - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _, _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) // Clean up after unit test defer func() { - client.consulClient.KV().DeleteTree(consulBasePath, nil) + _, _ = client.consulClient.KV().DeleteTree(consulBasePath, nil) }() - client.PutConfigurationValue("Logging/EnableRemote", []byte(strconv.FormatBool(expectedConfig.Logging.EnableRemote))) - client.PutConfigurationValue("Logging/File", []byte(expectedConfig.Logging.File)) - client.PutConfigurationValue("Service/ServiceId", []byte(expectedConfig.Service.ServiceId)) - client.PutConfigurationValue("Service/Host", []byte(expectedConfig.Service.Host)) - client.PutConfigurationValue("Service/Port", []byte(strconv.Itoa(expectedConfig.Service.Port))) - client.PutConfigurationValue("Port", []byte(strconv.Itoa(expectedConfig.Port))) - client.PutConfigurationValue("Host", []byte(expectedConfig.Host)) - client.PutConfigurationValue("LogLevel", []byte(expectedConfig.LogLevel)) + _ = client.PutConfigurationValue("Logging/EnableRemote", []byte(strconv.FormatBool(expectedConfig.Logging.EnableRemote))) + _ = client.PutConfigurationValue("Logging/File", []byte(expectedConfig.Logging.File)) + _ = client.PutConfigurationValue("Service/ServiceId", []byte(expectedConfig.Service.ServiceId)) + _ = client.PutConfigurationValue("Service/Host", []byte(expectedConfig.Service.Host)) + _ = client.PutConfigurationValue("Service/Port", []byte(strconv.Itoa(expectedConfig.Service.Port))) + _ = client.PutConfigurationValue("Port", []byte(strconv.Itoa(expectedConfig.Port))) + _ = client.PutConfigurationValue("Host", []byte(expectedConfig.Host)) + _ = client.PutConfigurationValue("LogLevel", []byte(expectedConfig.LogLevel)) updateChannel := make(chan interface{}) errorChannel := make(chan error) @@ -728,7 +729,7 @@ func TestWatchForChanges(t *testing.T) { } // Make a change to logging - client.PutConfigurationValue("Logging/File", []byte(expectedChange)) + _ = client.PutConfigurationValue("Logging/File", []byte(expectedChange)) pass-- continue @@ -745,7 +746,7 @@ func TestWatchForChanges(t *testing.T) { } func makeConsulClient(t *testing.T, servicePort int, setServiceInfo bool) *consulClient { - registryConfig := registry.Config{ + registryConfig := types.Config{ Host: testHost, Port: port, Stem: "edgex/core/1.0/", diff --git a/interface.go b/pkg/types/config.go similarity index 55% rename from interface.go rename to pkg/types/config.go index 784d7c5..663c9c1 100644 --- a/interface.go +++ b/pkg/types/config.go @@ -14,54 +14,9 @@ // limitations under the License. // -package registry +package types -import ( - "fmt" - "github.com/pelletier/go-toml" -) - -type Client interface { - // Registers the current service with Registry for discover and health check - Register() error - - // Checks to see if the Registry contains the service's configuration. - HasConfiguration() (bool, error) - - // Puts a full toml configuration into the Registry - PutConfigurationToml(configuration *toml.Tree, overwrite bool) error - - // Puts a full configuration struct into the Registry - PutConfiguration(configStruct interface{}, overwrite bool) error - - // Gets the full configuration from Consul into the target configuration struct. - // Passed in struct is only a reference for Registry. Empty struct is fine - // Returns the configuration in the target struct as interface{}, which caller must cast - GetConfiguration(configStruct interface{}) (interface{}, error) - - // Sets up a Consul watch for the target key and send back updates on the update channel. - // Passed in struct is only a reference for Registry, empty struct is ok - // Sends the configuration in the target struct as interface{} on updateChannel, which caller must cast - WatchForChanges(updateChannel chan<- interface{}, errorChannel chan<- error, configuration interface{}, waitKey string) - - // Simply checks if Registry is up and running at the configured URL - IsAlive() bool - - // Checks if a configuration value exists in the Registry - ConfigurationValueExists(name string) (bool, error) - - // Gets a specific configuration value from the Registry - GetConfigurationValue(name string) ([]byte, error) - - // Puts a specific configuration value into the Registry - PutConfigurationValue(name string, value []byte) error - - // Gets the service endpoint information for the target ID from the Registry - GetServiceEndpoint(serviceId string) (ServiceEndpoint, error) - - // Checks with the Registry if the target service is available, i.e. registered and healthy - IsServiceAvailable(serviceId string) (error) -} +import "fmt" // Config defines the information need to connect to the registry service and optionally register the service // for discovery and health checks @@ -90,13 +45,6 @@ type Config struct { CheckInterval string } -// ServiceEndpoint defines the service information returned by GetServiceEndpoint() need to connect to the target service -type ServiceEndpoint struct { - ServiceId string - Host string - Port int -} - // // A few helper functions for building URLs. // diff --git a/pkg/types/service_endpoint.go b/pkg/types/service_endpoint.go new file mode 100644 index 0000000..b9a51e0 --- /dev/null +++ b/pkg/types/service_endpoint.go @@ -0,0 +1,24 @@ +// +// Copyright (c) 2019 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package types + +// ServiceEndpoint defines the service information returned by GetServiceEndpoint() need to connect to the target service +type ServiceEndpoint struct { + ServiceId string + Host string + Port int +} diff --git a/pkg/factory/factory.go b/registry/factory.go similarity index 88% rename from pkg/factory/factory.go rename to registry/factory.go index 9147220..2b07448 100644 --- a/pkg/factory/factory.go +++ b/registry/factory.go @@ -14,15 +14,15 @@ // limitations under the License. // -package factory +package registry import ( "fmt" - "github.com/edgexfoundry/go-mod-registry" "github.com/edgexfoundry/go-mod-registry/internal/pkg/consul" + "github.com/edgexfoundry/go-mod-registry/pkg/types" ) -func NewRegistryClient(registryConfig registry.Config) (registry.Client, error) { +func NewRegistryClient(registryConfig types.Config) (Client, error) { if registryConfig.Host == "" || registryConfig.Port == 0 { return nil, fmt.Errorf("unable to create ConsulClient: registry host and/or port or serviceKey not set") diff --git a/pkg/factory/factory_test.go b/registry/factory_test.go similarity index 92% rename from pkg/factory/factory_test.go rename to registry/factory_test.go index 6d9c646..6160bdf 100644 --- a/pkg/factory/factory_test.go +++ b/registry/factory_test.go @@ -14,15 +14,16 @@ // limitations under the License. // -package factory +package registry import ( - "github.com/edgexfoundry/go-mod-registry" - "github.com/stretchr/testify/assert" "testing" + + "github.com/edgexfoundry/go-mod-registry/pkg/types" + "github.com/stretchr/testify/assert" ) -var registryConfig = registry.Config{ +var registryConfig = types.Config{ Host: "localhost", Port: 8500, Stem: "config", diff --git a/registry/interface.go b/registry/interface.go new file mode 100644 index 0000000..a469658 --- /dev/null +++ b/registry/interface.go @@ -0,0 +1,64 @@ +// +// Copyright (c) 2019 Intel Corporation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +package registry + +import ( + "github.com/edgexfoundry/go-mod-registry/pkg/types" + "github.com/pelletier/go-toml" +) + +type Client interface { + // Registers the current service with Registry for discover and health check + Register() error + + // Checks to see if the Registry contains the service's configuration. + HasConfiguration() (bool, error) + + // Puts a full toml configuration into the Registry + PutConfigurationToml(configuration *toml.Tree, overwrite bool) error + + // Puts a full configuration struct into the Registry + PutConfiguration(configStruct interface{}, overwrite bool) error + + // Gets the full configuration from Consul into the target configuration struct. + // Passed in struct is only a reference for Registry. Empty struct is fine + // Returns the configuration in the target struct as interface{}, which caller must cast + GetConfiguration(configStruct interface{}) (interface{}, error) + + // Sets up a Consul watch for the target key and send back updates on the update channel. + // Passed in struct is only a reference for Registry, empty struct is ok + // Sends the configuration in the target struct as interface{} on updateChannel, which caller must cast + WatchForChanges(updateChannel chan<- interface{}, errorChannel chan<- error, configuration interface{}, waitKey string) + + // Simply checks if Registry is up and running at the configured URL + IsAlive() bool + + // Checks if a configuration value exists in the Registry + ConfigurationValueExists(name string) (bool, error) + + // Gets a specific configuration value from the Registry + GetConfigurationValue(name string) ([]byte, error) + + // Puts a specific configuration value into the Registry + PutConfigurationValue(name string, value []byte) error + + // Gets the service endpoint information for the target ID from the Registry + GetServiceEndpoint(serviceId string) (types.ServiceEndpoint, error) + + // Checks with the Registry if the target service is available, i.e. registered and healthy + IsServiceAvailable(serviceId string) error +}