diff --git a/.github/workflows/github-ci.yml b/.github/workflows/github-ci.yml index b03699c..35baa7f 100644 --- a/.github/workflows/github-ci.yml +++ b/.github/workflows/github-ci.yml @@ -24,7 +24,8 @@ jobs: shell: bash run: | rm -rf script-delivery-ps - git clone ${{ secrets.SCRIPTS_DELIVERY_PS_GIT_URL }} script-delivery-ps + git clone ${{ secrets.SCRIPTS_DELIVERY_PS_GIT_URL }} eic-templates-cicd-ps + cp -r eic-templates-cicd-ps/script-delivery-ps script-delivery-ps - name: Execute increment script shell: bash @@ -102,5 +103,5 @@ jobs: - name: Execute measure script env: name: $(echo '${{ github.repository }}' | awk -F '/' '{print $2}') - run: ./script-delivery-ps/measure/measure.ps1 ${{ github.repository_owner }} ${{ env.name }} ${{ secrets.AWS_ACCESS_KEY_ID }} ${{ secrets.AWS_SECRET_ACCESS_KEY }} ${{ secrets.AWS_S3_BUCKET }} ${{ secrets.GITHUB_TOKEN }} + run: ./script-delivery-ps/measure/measure.ps1 ${{ github.repository_owner }} ${{ env.name }} ${{ secrets.AWS_ACCESS_KEY_ID }} ${{ secrets.AWS_SECRET_ACCESS_KEY }} ${{ secrets.AWS_S3_BUCKET }} ${{ secrets.AWS_S3_BUCKET_FOLDER }} ${{ secrets.GITHUB_TOKEN }} shell: bash diff --git a/.gitignore b/.gitignore index e958c76..35ff16f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ -.DS_Store -/dist -go.sum -*.tmp +.DS_Store +/dist +go.sum +*.tmp docker/id_rsa* \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 11c6320..5187f29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,136 +1,136 @@ -# Pip.Services Logo
Remote Procedure Calls for Pip.Services in Go Changelog - -## 1.5.2 (2023-01-12) -### Bug fixing -- Fixed https connection validation - -## 1.5.1 (2023-01-12) -### Features -- Update dependencies - -## 1.5.0 (2021-10-18) -### Features -* Added regexp supporting to interceptor - Examples: - - the interceptor route **"/dummies"** corresponds to all of this routes **"/dummies"**, **"/dummies/check"**, **"/dummies/test"** - - the interceptor route **"/dummies$"** corresponds only for this route **"/dummies"**. The routes **"/dummies/check"**, **"/dummies/test"** aren't processing by interceptor - Please, don't forgot, route in interceptor always automaticaly concateneted with base route, like this **service_base_route + route_in_interceptor**. - For example, "/api/v1/" - service base route, "/dummies$" - interceptor route, in result will be next expression - "/api/v1/dummies$" -## 1.4.4 (2021-08-30) -### Bug fixing -* Fix retry mechnaism in REST client - -## 1.4.3 (2021-08-23) -### Bug fixing -* Updated error propagation mechanism between client and services - -## 1.4.2 (2021-07-30) -### Features -* Add configuration parameters for CORS Headers in HttpEndpoint. Use *cors_headers* and *cors_origins*. - Example: - ```yml - -cors_headers: "correlation_id, access_token, Accept, Content-Type, Content-Length, X-CSRF-Token" - -cors_origins: "*" - ``` -## 1.4.1 (2021-07-26) -### Bug fixing -- Fix route checks in interceptors - -## 1.4.0 (2021-07-20) -### Features -* Add methods for controll CORS Headers in HttpEndpoint -* Add configuration parameters for CORS Headers in HttpEndpoint - -## 1.3.3 (2021-06-08) -### Features -* Update Instruments and added tracers -* Fix loggers -## 1.3.2 (2021-05-06) -### Features -* **test** Refactor test services running -* Encode URL params - -## 1.3.1 (2021-04-23) - -### Features -* Add InstrumentTiming - -## 1.3.0 (2021-04-23) - -### Breaking Changes -* **test** Added TestRestClient -* **test** Added TestCommandableHttpClient - -## 1.2.0 (2021-04-04) - -### Breaking Changes -* Introduced IRpcServiceOverrides -* Changed signature NewRpcService to InheritRpcService -* Changed signature NewCommandableRpcService to InheritRpcService - -## 1.1.3 (2021-03-15) - -### Features -* **services** Added **correlation_id** and **access_token** to CORS headers - -## 1.1.0 (2021-02-21) - -### Features -* **services** Added integration with Swagger UI - -## 1.0.13 (2020-12-10) - -### Features -* Fix work with CorrelationID in RestService -* Update dependencies - -## 1.0.12 (2020-12-10) - -### Features -* Fix headers in RestClient for properly work with others services - -## 1.0.8-1.0.11 (2020-12-02) - -### Features -* Added helper methods to RestOperations -* Changed RegisterWithAuth methods - -### Bug Fixes -* Fix authorizer - -## 1.0.7 (2020-11-20) - -### Features -* Added swagger support - -## 1.0.5-1.0.6 (2020-11-13) - -### Features -* Added helper methods - -## 1.0.3-1.0.4 (2020-11-12) - -### Features -* Added helper methods in RestService - -### Bug Fixes -* Fix signature CallCommand in CommandableHttpClient - -## 1.0.1-1.0.2 (2020-08-05) - -### Features -* Added error handler in Call method of RestClient - -### Bug Fixes -* Fix response error method - -## 1.0.0 (2020-01-28) - -Initial public release - -### Features -* **build** HTTP service factory -* **clients** mechanisms for retrieving connection settings -* **connect** helper module to retrieve connections services and clients -* **services** basic implementation of services for connecting - +# Pip.Services Logo
Remote Procedure Calls for Pip.Services in Go Changelog + +## 1.5.2 (2023-01-12) +### Bug fixing +- Fixed https connection validation + +## 1.5.1 (2023-01-12) +### Features +- Update dependencies + +## 1.5.0 (2021-10-18) +### Features +* Added regexp supporting to interceptor + Examples: + - the interceptor route **"/dummies"** corresponds to all of this routes **"/dummies"**, **"/dummies/check"**, **"/dummies/test"** + - the interceptor route **"/dummies$"** corresponds only for this route **"/dummies"**. The routes **"/dummies/check"**, **"/dummies/test"** aren't processing by interceptor + Please, don't forgot, route in interceptor always automaticaly concateneted with base route, like this **service_base_route + route_in_interceptor**. + For example, "/api/v1/" - service base route, "/dummies$" - interceptor route, in result will be next expression - "/api/v1/dummies$" +## 1.4.4 (2021-08-30) +### Bug fixing +* Fix retry mechnaism in REST client + +## 1.4.3 (2021-08-23) +### Bug fixing +* Updated error propagation mechanism between client and services + +## 1.4.2 (2021-07-30) +### Features +* Add configuration parameters for CORS Headers in HttpEndpoint. Use *cors_headers* and *cors_origins*. + Example: + ```yml + -cors_headers: "correlation_id, access_token, Accept, Content-Type, Content-Length, X-CSRF-Token" + -cors_origins: "*" + ``` +## 1.4.1 (2021-07-26) +### Bug fixing +- Fix route checks in interceptors + +## 1.4.0 (2021-07-20) +### Features +* Add methods for controll CORS Headers in HttpEndpoint +* Add configuration parameters for CORS Headers in HttpEndpoint + +## 1.3.3 (2021-06-08) +### Features +* Update Instruments and added tracers +* Fix loggers +## 1.3.2 (2021-05-06) +### Features +* **test** Refactor test services running +* Encode URL params + +## 1.3.1 (2021-04-23) + +### Features +* Add InstrumentTiming + +## 1.3.0 (2021-04-23) + +### Breaking Changes +* **test** Added TestRestClient +* **test** Added TestCommandableHttpClient + +## 1.2.0 (2021-04-04) + +### Breaking Changes +* Introduced IRpcServiceOverrides +* Changed signature NewRpcService to InheritRpcService +* Changed signature NewCommandableRpcService to InheritRpcService + +## 1.1.3 (2021-03-15) + +### Features +* **services** Added **correlation_id** and **access_token** to CORS headers + +## 1.1.0 (2021-02-21) + +### Features +* **services** Added integration with Swagger UI + +## 1.0.13 (2020-12-10) + +### Features +* Fix work with CorrelationID in RestService +* Update dependencies + +## 1.0.12 (2020-12-10) + +### Features +* Fix headers in RestClient for properly work with others services + +## 1.0.8-1.0.11 (2020-12-02) + +### Features +* Added helper methods to RestOperations +* Changed RegisterWithAuth methods + +### Bug Fixes +* Fix authorizer + +## 1.0.7 (2020-11-20) + +### Features +* Added swagger support + +## 1.0.5-1.0.6 (2020-11-13) + +### Features +* Added helper methods + +## 1.0.3-1.0.4 (2020-11-12) + +### Features +* Added helper methods in RestService + +### Bug Fixes +* Fix signature CallCommand in CommandableHttpClient + +## 1.0.1-1.0.2 (2020-08-05) + +### Features +* Added error handler in Call method of RestClient + +### Bug Fixes +* Fix response error method + +## 1.0.0 (2020-01-28) + +Initial public release + +### Features +* **build** HTTP service factory +* **clients** mechanisms for retrieving connection settings +* **connect** helper module to retrieve connections services and clients +* **services** basic implementation of services for connecting + diff --git a/component.json b/component.json index 6cc95d4..d19893e 100644 --- a/component.json +++ b/component.json @@ -1,10 +1,10 @@ -{ - "name": "pip-services3-rpc-go", - "type": "module", - "language": "go", - "version": "1.5.2", - "build": 0, - "registry": "pipservices", - "artifacts": [ - ] +{ + "name": "pip-services3-rpc-go", + "type": "module", + "language": "go", + "version": "1.5.2", + "build": 0, + "registry": "pipservices", + "artifacts": [ + ] } \ No newline at end of file diff --git a/connect/HttpConnectionResolver.go b/connect/HttpConnectionResolver.go index 4f7fee5..a0e417b 100644 --- a/connect/HttpConnectionResolver.go +++ b/connect/HttpConnectionResolver.go @@ -1,233 +1,233 @@ -package connect - -import ( - "net/url" - "strconv" - - cconf "github.com/pip-services3-go/pip-services3-commons-go/config" - cerr "github.com/pip-services3-go/pip-services3-commons-go/errors" - crefer "github.com/pip-services3-go/pip-services3-commons-go/refer" - cauth "github.com/pip-services3-go/pip-services3-components-go/auth" - ccon "github.com/pip-services3-go/pip-services3-components-go/connect" -) - -/* -HttpConnectionResolver helper class to retrieve connections for HTTP-based services abd clients. - -In addition to regular functions of ConnectionResolver is able to parse http:// URIs -and validate connection parameters before returning them. - -Configuration parameters: - - - connection: - - discovery_key: (optional) a key to retrieve the connection from IDiscovery - - ... other connection parameters - - - connections: alternative to connection - - [connection params 1]: first connection parameters - - ... - - [connection params N]: Nth connection parameters - - ... - - References: - -- *:discovery:*:*:1.0 (optional) IDiscovery services - -See: ConnectionParams -See: ConnectionResolver - -Example: - - config := cconf.NewConfigParamsFromTuples( - "connection.host", "10.1.1.100", - "connection.port", 8080, - ); - - connectionResolver = NewHttpConnectionResolver(); - connectionResolver.Configure(config); - connectionResolver.SetReferences(references); - - connection, err := connectionResolver.Resolve("123") - // Now use connection... -*/ -type HttpConnectionResolver struct { - //The base connection resolver. - ConnectionResolver ccon.ConnectionResolver - //The base credential resolver. - CredentialResolver cauth.CredentialResolver -} - -// NewHttpConnectionResolver creates new instance NewHttpConnectionResolver -// Returns pointer on NewHttpConnectionResolver -func NewHttpConnectionResolver() *HttpConnectionResolver { - return &HttpConnectionResolver{*ccon.NewEmptyConnectionResolver(), *cauth.NewEmptyCredentialResolver()} -} - -// Configure method are configures component by passing configuration parameters. -// Parameters: -// - config *cconf.ConfigParams configuration parameters to be set. -func (c *HttpConnectionResolver) Configure(config *cconf.ConfigParams) { - c.ConnectionResolver.Configure(config) - c.CredentialResolver.Configure(config) -} - -// SetReferences method are sets references to dependent components. -// Parameters: -// - references crefer.IReferences references to locate the component dependencies. -func (c *HttpConnectionResolver) SetReferences(references crefer.IReferences) { - c.ConnectionResolver.SetReferences(references) - c.CredentialResolver.SetReferences(references) -} - -func (c *HttpConnectionResolver) validateConnection(correlationId string, connection *ccon.ConnectionParams, credential *cauth.CredentialParams) error { - if connection == nil { - return cerr.NewConfigError(correlationId, "NO_CONNECTION", "HTTP connection is not set") - } - uri := connection.Uri() - if uri != "" { - return nil - } - - protocol := connection.Protocol() //"http" - if "http" != protocol && "https" != protocol { - return cerr.NewConfigError(correlationId, "WRONG_PROTOCOL", "Protocol is not supported by REST connection").WithDetails("protocol", protocol) - } - host := connection.Host() - if host == "" { - return cerr.NewConfigError(correlationId, "NO_HOST", "Connection host is not set") - } - port := connection.Port() - if port == 0 { - return cerr.NewConfigError(correlationId, "NO_PORT", "Connection port is not set") - } - // Check HTTPS credentials - if protocol == "https" { - // Sometimes when we use https we are on an internal network and do not want to have to deal with security. - // When we need a https connection and we don't want to pass credentials, flag is 'credential.internal_network', - // this flag just has to be present and non null for this functionality to work. - if val := credential.GetAsNullableString("internal_network"); val == nil || *val == "" { - // Check for credential - if credential == nil { - return cerr.NewConfigError(correlationId, "NO_CREDENTIAL", "SSL certificates are not configured for HTTPS protocol") - } else { - if credential.GetAsNullableString("ssl_key_file") == nil { - return cerr.NewConfigError( - correlationId, "NO_SSL_KEY_FILE", "SSL key file is not configured in credentials") - } else if credential.GetAsNullableString("ssl_crt_file") == nil { - return cerr.NewConfigError( - correlationId, "NO_SSL_CRT_FILE", "SSL crt file is not configured in credentials") - } - } - } - } - - return nil -} - -func (c *HttpConnectionResolver) updateConnection(connection *ccon.ConnectionParams) { - if connection == nil { - return - } - - uri := connection.Uri() - - if uri == "" { - protocol := connection.Protocol() // "http" - host := connection.Host() - port := connection.Port() - - uri := protocol + "://" + host - if port != 0 { - uri += ":" + strconv.Itoa(port) - } - connection.SetUri(uri) - } else { - address, _ := url.Parse(uri) - //protocol := ("" + address.protocol).replace(":", "") - protocol := address.Scheme - - connection.SetProtocol(protocol) - connection.SetHost(address.Hostname()) - port, _ := strconv.Atoi(address.Port()) - connection.SetPort(port) - } -} - -// Resolve method are resolves a single component connection. If connections are configured to be retrieved -// from Discovery service it finds a IDiscovery and resolves the connection there. -// Parameters: -// - correlationId string (optional) transaction id to trace execution through call chain. -// Returns: connection *ccon.ConnectionParams, credential *cauth.CredentialParams, err error -// resolved connection and credential or error. -func (c *HttpConnectionResolver) Resolve(correlationId string) (connection *ccon.ConnectionParams, credential *cauth.CredentialParams, err error) { - - connection, err = c.ConnectionResolver.Resolve(correlationId) - if err != nil { - return nil, nil, err - } - - credential, err = c.CredentialResolver.Lookup(correlationId) - if err == nil { - err = c.validateConnection(correlationId, connection, credential) - } - if err == nil && connection != nil { - c.updateConnection(connection) - } - - return connection, credential, err -} - -// ResolveAll method are resolves all component connection. If connections are configured to be retrieved -// from Discovery service it finds a IDiscovery and resolves the connection there. -// Parameters: -// - correlationId string (optional) transaction id to trace execution through call chain. -// Returns: connections []*ccon.ConnectionParams, credential *cauth.CredentialParams, err error -// resolved connections and credential or error. -func (c *HttpConnectionResolver) ResolveAll(correlationId string) (connections []*ccon.ConnectionParams, credential *cauth.CredentialParams, err error) { - - connections, err = c.ConnectionResolver.ResolveAll(correlationId) - if err != nil { - return nil, nil, err - } - - credential, err = c.CredentialResolver.Lookup(correlationId) - if connections == nil { - connections = make([]*ccon.ConnectionParams, 0) - } - - for _, connection := range connections { - if err == nil { - err = c.validateConnection(correlationId, connection, credential) - } - if err == nil && connection != nil { - c.updateConnection(connection) - } - } - return connections, credential, err -} - -// Register method are registers the given connection in all referenced discovery services. -// c method can be used for dynamic service discovery. -// Parameters: -// - correlationId string (optional) transaction id to trace execution through call chain. -// Returns: error -// nil if registered connection or error. - -func (c *HttpConnectionResolver) Register(correlationId string) error { - - connection, err := c.ConnectionResolver.Resolve(correlationId) - if err != nil { - return err - } - - credential, err := c.CredentialResolver.Lookup(correlationId) - // Validate connection - if err == nil { - err = c.validateConnection(correlationId, connection, credential) - } - if err == nil { - return c.ConnectionResolver.Register(correlationId, connection) - } else { - return err - } -} +package connect + +import ( + "net/url" + "strconv" + + cconf "github.com/pip-services3-go/pip-services3-commons-go/config" + cerr "github.com/pip-services3-go/pip-services3-commons-go/errors" + crefer "github.com/pip-services3-go/pip-services3-commons-go/refer" + cauth "github.com/pip-services3-go/pip-services3-components-go/auth" + ccon "github.com/pip-services3-go/pip-services3-components-go/connect" +) + +/* +HttpConnectionResolver helper class to retrieve connections for HTTP-based services abd clients. + +In addition to regular functions of ConnectionResolver is able to parse http:// URIs +and validate connection parameters before returning them. + +Configuration parameters: + + - connection: + - discovery_key: (optional) a key to retrieve the connection from IDiscovery + - ... other connection parameters + + - connections: alternative to connection + - [connection params 1]: first connection parameters + - ... + - [connection params N]: Nth connection parameters + - ... + + References: + +- *:discovery:*:*:1.0 (optional) IDiscovery services + +See: ConnectionParams +See: ConnectionResolver + +Example: + + config := cconf.NewConfigParamsFromTuples( + "connection.host", "10.1.1.100", + "connection.port", 8080, + ); + + connectionResolver = NewHttpConnectionResolver(); + connectionResolver.Configure(config); + connectionResolver.SetReferences(references); + + connection, err := connectionResolver.Resolve("123") + // Now use connection... +*/ +type HttpConnectionResolver struct { + //The base connection resolver. + ConnectionResolver ccon.ConnectionResolver + //The base credential resolver. + CredentialResolver cauth.CredentialResolver +} + +// NewHttpConnectionResolver creates new instance NewHttpConnectionResolver +// Returns pointer on NewHttpConnectionResolver +func NewHttpConnectionResolver() *HttpConnectionResolver { + return &HttpConnectionResolver{*ccon.NewEmptyConnectionResolver(), *cauth.NewEmptyCredentialResolver()} +} + +// Configure method are configures component by passing configuration parameters. +// Parameters: +// - config *cconf.ConfigParams configuration parameters to be set. +func (c *HttpConnectionResolver) Configure(config *cconf.ConfigParams) { + c.ConnectionResolver.Configure(config) + c.CredentialResolver.Configure(config) +} + +// SetReferences method are sets references to dependent components. +// Parameters: +// - references crefer.IReferences references to locate the component dependencies. +func (c *HttpConnectionResolver) SetReferences(references crefer.IReferences) { + c.ConnectionResolver.SetReferences(references) + c.CredentialResolver.SetReferences(references) +} + +func (c *HttpConnectionResolver) validateConnection(correlationId string, connection *ccon.ConnectionParams, credential *cauth.CredentialParams) error { + if connection == nil { + return cerr.NewConfigError(correlationId, "NO_CONNECTION", "HTTP connection is not set") + } + uri := connection.Uri() + if uri != "" { + return nil + } + + protocol := connection.Protocol() //"http" + if "http" != protocol && "https" != protocol { + return cerr.NewConfigError(correlationId, "WRONG_PROTOCOL", "Protocol is not supported by REST connection").WithDetails("protocol", protocol) + } + host := connection.Host() + if host == "" { + return cerr.NewConfigError(correlationId, "NO_HOST", "Connection host is not set") + } + port := connection.Port() + if port == 0 { + return cerr.NewConfigError(correlationId, "NO_PORT", "Connection port is not set") + } + // Check HTTPS credentials + if protocol == "https" { + // Sometimes when we use https we are on an internal network and do not want to have to deal with security. + // When we need a https connection and we don't want to pass credentials, flag is 'credential.internal_network', + // this flag just has to be present and non null for this functionality to work. + if val := credential.GetAsNullableString("internal_network"); val == nil || *val == "" { + // Check for credential + if credential == nil { + return cerr.NewConfigError(correlationId, "NO_CREDENTIAL", "SSL certificates are not configured for HTTPS protocol") + } else { + if credential.GetAsNullableString("ssl_key_file") == nil { + return cerr.NewConfigError( + correlationId, "NO_SSL_KEY_FILE", "SSL key file is not configured in credentials") + } else if credential.GetAsNullableString("ssl_crt_file") == nil { + return cerr.NewConfigError( + correlationId, "NO_SSL_CRT_FILE", "SSL crt file is not configured in credentials") + } + } + } + } + + return nil +} + +func (c *HttpConnectionResolver) updateConnection(connection *ccon.ConnectionParams) { + if connection == nil { + return + } + + uri := connection.Uri() + + if uri == "" { + protocol := connection.Protocol() // "http" + host := connection.Host() + port := connection.Port() + + uri := protocol + "://" + host + if port != 0 { + uri += ":" + strconv.Itoa(port) + } + connection.SetUri(uri) + } else { + address, _ := url.Parse(uri) + //protocol := ("" + address.protocol).replace(":", "") + protocol := address.Scheme + + connection.SetProtocol(protocol) + connection.SetHost(address.Hostname()) + port, _ := strconv.Atoi(address.Port()) + connection.SetPort(port) + } +} + +// Resolve method are resolves a single component connection. If connections are configured to be retrieved +// from Discovery service it finds a IDiscovery and resolves the connection there. +// Parameters: +// - correlationId string (optional) transaction id to trace execution through call chain. +// Returns: connection *ccon.ConnectionParams, credential *cauth.CredentialParams, err error +// resolved connection and credential or error. +func (c *HttpConnectionResolver) Resolve(correlationId string) (connection *ccon.ConnectionParams, credential *cauth.CredentialParams, err error) { + + connection, err = c.ConnectionResolver.Resolve(correlationId) + if err != nil { + return nil, nil, err + } + + credential, err = c.CredentialResolver.Lookup(correlationId) + if err == nil { + err = c.validateConnection(correlationId, connection, credential) + } + if err == nil && connection != nil { + c.updateConnection(connection) + } + + return connection, credential, err +} + +// ResolveAll method are resolves all component connection. If connections are configured to be retrieved +// from Discovery service it finds a IDiscovery and resolves the connection there. +// Parameters: +// - correlationId string (optional) transaction id to trace execution through call chain. +// Returns: connections []*ccon.ConnectionParams, credential *cauth.CredentialParams, err error +// resolved connections and credential or error. +func (c *HttpConnectionResolver) ResolveAll(correlationId string) (connections []*ccon.ConnectionParams, credential *cauth.CredentialParams, err error) { + + connections, err = c.ConnectionResolver.ResolveAll(correlationId) + if err != nil { + return nil, nil, err + } + + credential, err = c.CredentialResolver.Lookup(correlationId) + if connections == nil { + connections = make([]*ccon.ConnectionParams, 0) + } + + for _, connection := range connections { + if err == nil { + err = c.validateConnection(correlationId, connection, credential) + } + if err == nil && connection != nil { + c.updateConnection(connection) + } + } + return connections, credential, err +} + +// Register method are registers the given connection in all referenced discovery services. +// c method can be used for dynamic service discovery. +// Parameters: +// - correlationId string (optional) transaction id to trace execution through call chain. +// Returns: error +// nil if registered connection or error. + +func (c *HttpConnectionResolver) Register(correlationId string) error { + + connection, err := c.ConnectionResolver.Resolve(correlationId) + if err != nil { + return err + } + + credential, err := c.CredentialResolver.Lookup(correlationId) + // Validate connection + if err == nil { + err = c.validateConnection(correlationId, connection, credential) + } + if err == nil { + return c.ConnectionResolver.Register(correlationId, connection) + } else { + return err + } +} diff --git a/docker/Dockerfile.docs b/docker/Dockerfile.docs index 9515a32..4b5b64f 100644 --- a/docker/Dockerfile.docs +++ b/docker/Dockerfile.docs @@ -1,14 +1,14 @@ -FROM golang:1.16 - -# Set environment variables for Go -ENV GO111MODULE=on - -WORKDIR /app - -RUN go install golang.org/x/tools/cmd/godoc@latest - -WORKDIR /app - -COPY . ./src - +FROM golang:1.16 + +# Set environment variables for Go +ENV GO111MODULE=on + +WORKDIR /app + +RUN go install golang.org/x/tools/cmd/godoc@latest + +WORKDIR /app + +COPY . ./src + ENTRYPOINT godoc -http=0.0.0.0:6060 -v -goroot=. \ No newline at end of file diff --git a/docker/Dockerfile.test b/docker/Dockerfile.test index dfecb1e..ae9e8f1 100644 --- a/docker/Dockerfile.test +++ b/docker/Dockerfile.test @@ -1,31 +1,31 @@ -# Start with the golang v1.16 image -FROM golang:1.16 - -# Setting environment variables for Go -ENV GO111MODULE=on \ - CGO_ENABLED=0 \ - GOOS=linux \ - GOARCH=amd64 - # GOPRIVATE=github.com/pip-services3-go/* - -# Copy local ssh keys -COPY docker/id_rsa /root/.ssh/ - -# Setup ssh access to git repositories -RUN chmod 600 /root/.ssh/id_rsa* \ - && ssh-keyscan github.com >> ~/.ssh/known_hosts \ - && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts \ - && git config --global --add url."git@github.com:".insteadOf "https://github.com/" - -# Set a working directory -WORKDIR /app - -# Copy the entire project -COPY . . - -# Install all go_modules -RUN go mod tidy -RUN go mod download - -# Specify the command from running tests -CMD go clean -testcache && go test -v ./test/... +# Start with the golang v1.16 image +FROM golang:1.16 + +# Setting environment variables for Go +ENV GO111MODULE=on \ + CGO_ENABLED=0 \ + GOOS=linux \ + GOARCH=amd64 + # GOPRIVATE=github.com/pip-services3-go/* + +# Copy local ssh keys +COPY docker/id_rsa /root/.ssh/ + +# Setup ssh access to git repositories +RUN chmod 600 /root/.ssh/id_rsa* \ + && ssh-keyscan github.com >> ~/.ssh/known_hosts \ + && ssh-keyscan gitlab.com >> ~/.ssh/known_hosts \ + && git config --global --add url."git@github.com:".insteadOf "https://github.com/" + +# Set a working directory +WORKDIR /app + +# Copy the entire project +COPY . . + +# Install all go_modules +RUN go mod tidy +RUN go mod download + +# Specify the command from running tests +CMD go clean -testcache && go test -v ./test/... diff --git a/docs/index.html b/docs/index.html index e95f81c..825032a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ - + diff --git a/docs/lib/godoc/godocs.js b/docs/lib/godoc/godocs.js index 7f02ba2..76f8127 100644 --- a/docs/lib/godoc/godocs.js +++ b/docs/lib/godoc/godocs.js @@ -1,688 +1,688 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* A little code to ease navigation of these documents. - * - * On window load we: - * + Generate a table of contents (generateTOC) - * + Bind foldable sections (bindToggles) - * + Bind links to foldable sections (bindToggleLinks) - */ - -(function() { - 'use strict'; - - // Mobile-friendly topbar menu - $(function() { - var menu = $('#menu'); - var menuButton = $('#menu-button'); - var menuButtonArrow = $('#menu-button-arrow'); - menuButton.click(function(event) { - menu.toggleClass('menu-visible'); - menuButtonArrow.toggleClass('vertical-flip'); - event.preventDefault(); - return false; - }); - }); - - /* Generates a table of contents: looks for h2 and h3 elements and generates - * links. "Decorates" the element with id=="nav" with this table of contents. - */ - function generateTOC() { - if ($('#manual-nav').length > 0) { - return; - } - - // For search, we send the toc precomputed from server-side. - // TODO: Ideally, this should always be precomputed for all pages, but then - // we need to do HTML parsing on the server-side. - if (location.pathname === '/search') { - return; - } - - var nav = $('#nav'); - if (nav.length === 0) { - return; - } - - var toc_items = []; - $(nav) - .nextAll('h2, h3') - .each(function() { - var node = this; - if (node.id == '') node.id = 'tmp_' + toc_items.length; - var link = $('') - .attr('href', '#' + node.id) - .text($(node).text()); - var item; - if ($(node).is('h2')) { - item = $('
'); - } else { - // h3 - item = $('
'); - } - item.append(link); - toc_items.push(item); - }); - if (toc_items.length <= 1) { - return; - } - var dl1 = $('
'); - var dl2 = $('
'); - - var split_index = toc_items.length / 2 + 1; - if (split_index < 8) { - split_index = toc_items.length; - } - for (var i = 0; i < split_index; i++) { - dl1.append(toc_items[i]); - } - for (; /* keep using i */ i < toc_items.length; i++) { - dl2.append(toc_items[i]); - } - - var tocTable = $('').appendTo(nav); - var tocBody = $('').appendTo(tocTable); - var tocRow = $('').appendTo(tocBody); - - // 1st column - $('
') - .appendTo(tocRow) - .append(dl1); - // 2nd column - $('') - .appendTo(tocRow) - .append(dl2); - } - - function bindToggle(el) { - $('.toggleButton', el).click(function() { - if ($(this).closest('.toggle, .toggleVisible')[0] != el) { - // Only trigger the closest toggle header. - return; - } - - if ($(el).is('.toggle')) { - $(el) - .addClass('toggleVisible') - .removeClass('toggle'); - } else { - $(el) - .addClass('toggle') - .removeClass('toggleVisible'); - } - }); - } - - function bindToggles(selector) { - $(selector).each(function(i, el) { - bindToggle(el); - }); - } - - function bindToggleLink(el, prefix) { - $(el).click(function() { - var href = $(el).attr('href'); - var i = href.indexOf('#' + prefix); - if (i < 0) { - return; - } - var id = '#' + prefix + href.slice(i + 1 + prefix.length); - if ($(id).is('.toggle')) { - $(id) - .find('.toggleButton') - .first() - .click(); - } - }); - } - function bindToggleLinks(selector, prefix) { - $(selector).each(function(i, el) { - bindToggleLink(el, prefix); - }); - } - - function setupDropdownPlayground() { - if (!$('#page').is('.wide')) { - return; // don't show on front page - } - var button = $('#playgroundButton'); - var div = $('#playground'); - var setup = false; - button.toggle( - function() { - button.addClass('active'); - div.show(); - if (setup) { - return; - } - setup = true; - playground({ - codeEl: $('.code', div), - outputEl: $('.output', div), - runEl: $('.run', div), - fmtEl: $('.fmt', div), - shareEl: $('.share', div), - shareRedirect: '//play.golang.org/p/', - }); - }, - function() { - button.removeClass('active'); - div.hide(); - } - ); - $('#menu').css('min-width', '+=60'); - - // Hide inline playground if we click somewhere on the page. - // This is needed in mobile devices, where the "Play" button - // is not clickable once the playground opens up. - $('#page').click(function() { - if (button.hasClass('active')) { - button.click(); - } - }); - } - - function setupInlinePlayground() { - 'use strict'; - // Set up playground when each element is toggled. - $('div.play').each(function(i, el) { - // Set up playground for this example. - var setup = function() { - var code = $('.code', el); - playground({ - codeEl: code, - outputEl: $('.output', el), - runEl: $('.run', el), - fmtEl: $('.fmt', el), - shareEl: $('.share', el), - shareRedirect: '//play.golang.org/p/', - }); - - // Make the code textarea resize to fit content. - var resize = function() { - code.height(0); - var h = code[0].scrollHeight; - code.height(h + 20); // minimize bouncing. - code.closest('.input').height(h); - }; - code.on('keydown', resize); - code.on('keyup', resize); - code.keyup(); // resize now. - }; - - // If example already visible, set up playground now. - if ($(el).is(':visible')) { - setup(); - return; - } - - // Otherwise, set up playground when example is expanded. - var built = false; - $(el) - .closest('.toggle') - .click(function() { - // Only set up once. - if (!built) { - setup(); - built = true; - } - }); - }); - } - - // fixFocus tries to put focus to div#page so that keyboard navigation works. - function fixFocus() { - var page = $('div#page'); - var topbar = $('div#topbar'); - page.css('outline', 0); // disable outline when focused - page.attr('tabindex', -1); // and set tabindex so that it is focusable - $(window) - .resize(function(evt) { - // only focus page when the topbar is at fixed position (that is, it's in - // front of page, and keyboard event will go to the former by default.) - // by focusing page, keyboard event will go to page so that up/down arrow, - // space, etc. will work as expected. - if (topbar.css('position') == 'fixed') page.focus(); - }) - .resize(); - } - - function toggleHash() { - var id = window.location.hash.substring(1); - // Open all of the toggles for a particular hash. - var els = $( - document.getElementById(id), - $('a[name]').filter(function() { - return $(this).attr('name') == id; - }) - ); - - while (els.length) { - for (var i = 0; i < els.length; i++) { - var el = $(els[i]); - if (el.is('.toggle')) { - el.find('.toggleButton') - .first() - .click(); - } - } - els = el.parent(); - } - } - - function personalizeInstallInstructions() { - var prefix = '?download='; - var s = window.location.search; - if (s.indexOf(prefix) != 0) { - // No 'download' query string; detect "test" instructions from User Agent. - if (navigator.platform.indexOf('Win') != -1) { - $('.testUnix').hide(); - $('.testWindows').show(); - } else { - $('.testUnix').show(); - $('.testWindows').hide(); - } - return; - } - - var filename = s.substr(prefix.length); - var filenameRE = /^go1\.\d+(\.\d+)?([a-z0-9]+)?\.([a-z0-9]+)(-[a-z0-9]+)?(-osx10\.[68])?\.([a-z.]+)$/; - var m = filenameRE.exec(filename); - if (!m) { - // Can't interpret file name; bail. - return; - } - $('.downloadFilename').text(filename); - $('.hideFromDownload').hide(); - - var os = m[3]; - var ext = m[6]; - if (ext != 'tar.gz') { - $('#tarballInstructions').hide(); - } - if (os != 'darwin' || ext != 'pkg') { - $('#darwinPackageInstructions').hide(); - } - if (os != 'windows') { - $('#windowsInstructions').hide(); - $('.testUnix').show(); - $('.testWindows').hide(); - } else { - if (ext != 'msi') { - $('#windowsInstallerInstructions').hide(); - } - if (ext != 'zip') { - $('#windowsZipInstructions').hide(); - } - $('.testUnix').hide(); - $('.testWindows').show(); - } - - var download = 'https://dl.google.com/go/' + filename; - - var message = $( - '

' + - 'Your download should begin shortly. ' + - 'If it does not, click this link.

' - ); - message.find('a').attr('href', download); - message.insertAfter('#nav'); - - window.location = download; - } - - function updateVersionTags() { - var v = window.goVersion; - if (/^go[0-9.]+$/.test(v)) { - $('.versionTag') - .empty() - .text(v); - $('.whereTag').hide(); - } - } - - function addPermalinks() { - function addPermalink(source, parent) { - var id = source.attr('id'); - if (id == '' || id.indexOf('tmp_') === 0) { - // Auto-generated permalink. - return; - } - if (parent.find('> .permalink').length) { - // Already attached. - return; - } - parent - .append(' ') - .append($("").attr('href', '#' + id)); - } - - $('#page .container') - .find('h2[id], h3[id]') - .each(function() { - var el = $(this); - addPermalink(el, el); - }); - - $('#page .container') - .find('dl[id]') - .each(function() { - var el = $(this); - // Add the anchor to the "dt" element. - addPermalink(el, el.find('> dt').first()); - }); - } - - $('.js-expandAll').click(function() { - if ($(this).hasClass('collapsed')) { - toggleExamples('toggle'); - $(this).text('(Collapse All)'); - } else { - toggleExamples('toggleVisible'); - $(this).text('(Expand All)'); - } - $(this).toggleClass('collapsed'); - }); - - function toggleExamples(className) { - // We need to explicitly iterate through divs starting with "example_" - // to avoid toggling Overview and Index collapsibles. - $("[id^='example_']").each(function() { - // Check for state and click it only if required. - if ($(this).hasClass(className)) { - $(this) - .find('.toggleButton') - .first() - .click(); - } - }); - } - - $(document).ready(function() { - generateTOC(); - addPermalinks(); - bindToggles('.toggle'); - bindToggles('.toggleVisible'); - bindToggleLinks('.exampleLink', 'example_'); - bindToggleLinks('.overviewLink', ''); - bindToggleLinks('.examplesLink', ''); - bindToggleLinks('.indexLink', ''); - setupDropdownPlayground(); - setupInlinePlayground(); - fixFocus(); - setupTypeInfo(); - setupCallgraphs(); - toggleHash(); - personalizeInstallInstructions(); - updateVersionTags(); - - // godoc.html defines window.initFuncs in the tag, and root.html and - // codewalk.js push their on-page-ready functions to the list. - // We execute those functions here, to avoid loading jQuery until the page - // content is loaded. - for (var i = 0; i < window.initFuncs.length; i++) window.initFuncs[i](); - }); - - // -- analysis --------------------------------------------------------- - - // escapeHTML returns HTML for s, with metacharacters quoted. - // It is safe for use in both elements and attributes - // (unlike the "set innerText, read innerHTML" trick). - function escapeHTML(s) { - return s - .replace(/&/g, '&') - .replace(/\"/g, '"') - .replace(/\'/g, ''') - .replace(//g, '>'); - } - - // makeAnchor returns HTML for an element, given an anchorJSON object. - function makeAnchor(json) { - var html = escapeHTML(json.Text); - if (json.Href != '') { - html = "" + html + ''; - } - return html; - } - - function showLowFrame(html) { - var lowframe = document.getElementById('lowframe'); - lowframe.style.height = '200px'; - lowframe.innerHTML = - "

" + - html + - '

\n' + - "
"; - } - - document.hideLowFrame = function() { - var lowframe = document.getElementById('lowframe'); - lowframe.style.height = '0px'; - }; - - // onClickCallers is the onclick action for the 'func' tokens of a - // function declaration. - document.onClickCallers = function(index) { - var data = document.ANALYSIS_DATA[index]; - if (data.Callers.length == 1 && data.Callers[0].Sites.length == 1) { - document.location = data.Callers[0].Sites[0].Href; // jump to sole caller - return; - } - - var html = - 'Callers of ' + escapeHTML(data.Callee) + ':
\n'; - for (var i = 0; i < data.Callers.length; i++) { - var caller = data.Callers[i]; - html += '' + escapeHTML(caller.Func) + ''; - var sites = caller.Sites; - if (sites != null && sites.length > 0) { - html += ' at line '; - for (var j = 0; j < sites.length; j++) { - if (j > 0) { - html += ', '; - } - html += '' + makeAnchor(sites[j]) + ''; - } - } - html += '
\n'; - } - showLowFrame(html); - }; - - // onClickCallees is the onclick action for the '(' token of a function call. - document.onClickCallees = function(index) { - var data = document.ANALYSIS_DATA[index]; - if (data.Callees.length == 1) { - document.location = data.Callees[0].Href; // jump to sole callee - return; - } - - var html = 'Callees of this ' + escapeHTML(data.Descr) + ':
\n'; - for (var i = 0; i < data.Callees.length; i++) { - html += '' + makeAnchor(data.Callees[i]) + '
\n'; - } - showLowFrame(html); - }; - - // onClickTypeInfo is the onclick action for identifiers declaring a named type. - document.onClickTypeInfo = function(index) { - var data = document.ANALYSIS_DATA[index]; - var html = - 'Type ' + - data.Name + - ': ' + - '      (size=' + - data.Size + - ', align=' + - data.Align + - ')
\n'; - html += implementsHTML(data); - html += methodsetHTML(data); - showLowFrame(html); - }; - - // implementsHTML returns HTML for the implements relation of the - // specified TypeInfoJSON value. - function implementsHTML(info) { - var html = ''; - if (info.ImplGroups != null) { - for (var i = 0; i < info.ImplGroups.length; i++) { - var group = info.ImplGroups[i]; - var x = '' + escapeHTML(group.Descr) + ' '; - for (var j = 0; j < group.Facts.length; j++) { - var fact = group.Facts[j]; - var y = '' + makeAnchor(fact.Other) + ''; - if (fact.ByKind != null) { - html += escapeHTML(fact.ByKind) + ' type ' + y + ' implements ' + x; - } else { - html += x + ' implements ' + y; - } - html += '
\n'; - } - } - } - return html; - } - - // methodsetHTML returns HTML for the methodset of the specified - // TypeInfoJSON value. - function methodsetHTML(info) { - var html = ''; - if (info.Methods != null) { - for (var i = 0; i < info.Methods.length; i++) { - html += '' + makeAnchor(info.Methods[i]) + '
\n'; - } - } - return html; - } - - // onClickComm is the onclick action for channel "make" and "<-" - // send/receive tokens. - document.onClickComm = function(index) { - var ops = document.ANALYSIS_DATA[index].Ops; - if (ops.length == 1) { - document.location = ops[0].Op.Href; // jump to sole element - return; - } - - var html = 'Operations on this channel:
\n'; - for (var i = 0; i < ops.length; i++) { - html += - makeAnchor(ops[i].Op) + - ' by ' + - escapeHTML(ops[i].Fn) + - '
\n'; - } - if (ops.length == 0) { - html += '(none)
\n'; - } - showLowFrame(html); - }; - - $(window).load(function() { - // Scroll window so that first selection is visible. - // (This means we don't need to emit id='L%d' spans for each line.) - // TODO(adonovan): ideally, scroll it so that it's under the pointer, - // but I don't know how to get the pointer y coordinate. - var elts = document.getElementsByClassName('selection'); - if (elts.length > 0) { - elts[0].scrollIntoView(); - } - }); - - // setupTypeInfo populates the "Implements" and "Method set" toggle for - // each type in the package doc. - function setupTypeInfo() { - for (var i in document.ANALYSIS_DATA) { - var data = document.ANALYSIS_DATA[i]; - - var el = document.getElementById('implements-' + i); - if (el != null) { - // el != null => data is TypeInfoJSON. - if (data.ImplGroups != null) { - el.innerHTML = implementsHTML(data); - el.parentNode.parentNode.style.display = 'block'; - } - } - - var el = document.getElementById('methodset-' + i); - if (el != null) { - // el != null => data is TypeInfoJSON. - if (data.Methods != null) { - el.innerHTML = methodsetHTML(data); - el.parentNode.parentNode.style.display = 'block'; - } - } - } - } - - function setupCallgraphs() { - if (document.CALLGRAPH == null) { - return; - } - document.getElementById('pkg-callgraph').style.display = 'block'; - - var treeviews = document.getElementsByClassName('treeview'); - for (var i = 0; i < treeviews.length; i++) { - var tree = treeviews[i]; - if (tree.id == null || tree.id.indexOf('callgraph-') != 0) { - continue; - } - var id = tree.id.substring('callgraph-'.length); - $(tree).treeview({ collapsed: true, animated: 'fast' }); - document.cgAddChildren(tree, tree, [id]); - tree.parentNode.parentNode.style.display = 'block'; - } - } - - document.cgAddChildren = function(tree, ul, indices) { - if (indices != null) { - for (var i = 0; i < indices.length; i++) { - var li = cgAddChild(tree, ul, document.CALLGRAPH[indices[i]]); - if (i == indices.length - 1) { - $(li).addClass('last'); - } - } - } - $(tree).treeview({ animated: 'fast', add: ul }); - }; - - // cgAddChild adds an
  • element for document.CALLGRAPH node cgn to - // the parent