Merge branch 'main' into main

This commit is contained in:
Mark Fussell 2025-04-25 09:54:09 +01:00 committed by GitHub
commit e4bd92b9dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 287 additions and 48 deletions

View File

@ -9,9 +9,13 @@ services:
shm_size: 1g
ulimits:
core: -1
# Setting nofile to 4096 and hard to 1048576, as recommended by Solace documentation
# Otherwise, the container will have an error and crash with:
# ERROR POST Violation [022]:Required system resource missing, Hard resource limit nofile 1048576 is required, 6592 detected
# https://docs.solace.com/Software-Broker/System-Resource-Requirements.htm#concurrent-open-files-considerations
nofile:
soft: 2448
hard: 6592
soft: 4096
hard: 1048576
deploy:
restart_policy:
condition: on-failure

View File

@ -0,0 +1,8 @@
#!/bin/bash
set -e
FILE="$1"
PROJECT="${2:-$FILE}"
docker compose -f .github/infrastructure/docker-compose-${FILE}.yml -p ${PROJECT} logs

View File

@ -440,6 +440,7 @@ const components = {
'pubsub.solace': {
conformance: true,
conformanceSetup: 'docker-compose.sh solace',
conformanceLogs: 'docker-compose-logs.sh solace',
},
'secretstores.azure.keyvault': {
certification: true,
@ -824,6 +825,7 @@ const components = {
* @property {boolean?} requireTerraform If true, requires Terraform
* @property {boolean?} requireKind If true, requires KinD
* @property {string?} conformanceSetup Setup script for conformance tests
* @property {string?} conformanceLogs Logs script for conformance tests
* @property {string?} conformanceDestroy Destroy script for conformance tests
* @property {string?} certificationSetup Setup script for certification tests
* @property {string?} certificationDestroy Destroy script for certification tests
@ -845,6 +847,7 @@ const components = {
* @property {boolean?} require-kind Requires KinD
* @property {string?} setup-script Setup script
* @property {string?} destroy-script Destroy script
* @property {string?} logs-script Logs script in case of failure
* @property {string?} nodejs-version Install the specified Node.js version if set
* @property {string?} mongodb-version Install the specified MongoDB version if set
* @property {string?} source-pkg Source package
@ -915,6 +918,7 @@ function GenerateMatrix(testKind, enableCloudTests) {
'require-kind': comp.requireKind ? 'true' : undefined,
'setup-script': comp[testKind + 'Setup'] || undefined,
'destroy-script': comp[testKind + 'Destroy'] || undefined,
'logs-script': comp[testKind + 'Logs'] || undefined,
'nodejs-version': comp.nodeJsVersion || undefined,
'mongodb-version': comp.mongoDbVersion || undefined,
'source-pkg': comp.sourcePkg

View File

@ -317,6 +317,10 @@ jobs:
exit 1
fi
- name: Retrieve infrastructure failure logs
if: failure() && matrix.logs-script != ''
run: .github/scripts/components-scripts/${{ matrix.logs-script }}
- name: Prepare test result info
if: always()
run: |

View File

@ -44,6 +44,7 @@ const (
TraceparentHeaderKey = "traceparent"
TracestateHeaderKey = "tracestate"
BaggageHeaderKey = "baggage"
TraceMetadataKey = "traceHeaders"
securityToken = "securityToken"
securityTokenHeader = "securityTokenHeader"
@ -318,6 +319,13 @@ func (h *HTTPSource) Invoke(parentCtx context.Context, req *bindings.InvokeReque
request.Header.Set(TracestateHeaderKey, ts)
}
if baggage, ok := req.Metadata[BaggageHeaderKey]; ok && baggage != "" {
if _, ok := request.Header[http.CanonicalHeaderKey(BaggageHeaderKey)]; ok {
h.logger.Warn("Tracing is enabled. A custom Baggage request header cannot be specified and is ignored.")
}
request.Header.Set(BaggageHeaderKey, baggage)
}
// Send the question
resp, err := h.client.Do(request)

View File

@ -473,7 +473,7 @@ func TestTraceHeadersForwarded(t *testing.T) {
req := TestCase{
input: "GET",
operation: "get",
metadata: map[string]string{"path": "/", "traceparent": "12345", "tracestate": "67890"},
metadata: map[string]string{"path": "/", "traceparent": "12345", "tracestate": "67890", "baggage": "key1=value1"},
path: "/",
err: "",
statusCode: 200,
@ -482,13 +482,14 @@ func TestTraceHeadersForwarded(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "12345", handler.Headers["Traceparent"])
assert.Equal(t, "67890", handler.Headers["Tracestate"])
assert.Equal(t, "key1=value1", handler.Headers["Baggage"])
})
t.Run("trace headers should not be forwarded if empty", func(t *testing.T) {
req := TestCase{
input: "GET",
operation: "get",
metadata: map[string]string{"path": "/", "traceparent": "", "tracestate": ""},
metadata: map[string]string{"path": "/", "traceparent": "", "tracestate": "", "baggage": ""},
path: "/",
err: "",
statusCode: 200,
@ -499,13 +500,15 @@ func TestTraceHeadersForwarded(t *testing.T) {
assert.False(t, traceParentExists)
_, traceStateExists := handler.Headers["Tracestate"]
assert.False(t, traceStateExists)
_, baggageExists := handler.Headers["Baggage"]
assert.False(t, baggageExists)
})
t.Run("trace headers override headers in request metadata", func(t *testing.T) {
req := TestCase{
input: "GET",
operation: "get",
metadata: map[string]string{"path": "/", "Traceparent": "abcde", "Tracestate": "fghijk", "traceparent": "12345", "tracestate": "67890"},
metadata: map[string]string{"path": "/", "Traceparent": "abcde", "Tracestate": "fghijk", "Baggage": "oldvalue", "traceparent": "12345", "tracestate": "67890", "baggage": "key1=value1"},
path: "/",
err: "",
statusCode: 200,
@ -514,6 +517,7 @@ func TestTraceHeadersForwarded(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "12345", handler.Headers["Traceparent"])
assert.Equal(t, "67890", handler.Headers["Tracestate"])
assert.Equal(t, "key1=value1", handler.Headers["Baggage"])
})
}

View File

@ -96,7 +96,7 @@ func (m *SQLServerAuthMetadata) GetConnector(setDatabase bool) (*mssql.Connector
conn, err := mssql.NewSecurityTokenConnector(config, func(ctx context.Context) (string, error) {
at, err := tokenCred.GetToken(ctx, policy.TokenRequestOptions{
Scopes: []string{
m.azureEnv.Cloud.Services[azure.ServiceAzureSQL].Audience,
m.azureEnv.Cloud.Services[azure.ServiceAzureSQL].Audience + "/.default",
},
})
if err != nil {

8
go.mod
View File

@ -73,7 +73,7 @@ require (
github.com/googleapis/gax-go/v2 v2.12.4
github.com/gorilla/mux v1.8.1
github.com/grandcat/zeroconf v1.0.0
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9
github.com/hamba/avro/v2 v2.28.0
github.com/hashicorp/consul/api v1.25.1
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/hazelcast/hazelcast-go-client v0.0.0-20190530123621-6cf767c2f31a
@ -126,7 +126,7 @@ require (
go.uber.org/multierr v1.11.0
go.uber.org/ratelimit v0.3.0
golang.org/x/crypto v0.35.0
golang.org/x/mod v0.18.0
golang.org/x/mod v0.23.0
golang.org/x/net v0.36.0
golang.org/x/oauth2 v0.27.0
google.golang.org/api v0.180.0
@ -304,7 +304,7 @@ require (
github.com/kataras/go-errors v0.0.3 // indirect
github.com/kataras/go-serializer v0.0.4 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/knadh/koanf v1.4.1 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/kubemq-io/protobuf v1.3.1 // indirect
@ -404,7 +404,7 @@ require (
golang.org/x/term v0.29.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.22.0 // indirect
golang.org/x/tools v0.30.0 // indirect
google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect

16
go.sum
View File

@ -901,8 +901,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9 h1:NEoabXt33PDWK4fXryK4e+XX+fSKDmmu9vg3yb9YI2M=
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9/go.mod h1:fQVdB2mFZBhPW1D5Abej41LMvrErARGrrdjOnKbm5yw=
github.com/hamba/avro/v2 v2.28.0 h1:E8J5D27biyAulWKNiEBhV85QPc9xRMCUCGJewS0KYCE=
github.com/hamba/avro/v2 v2.28.0/go.mod h1:9TVrlt1cG1kkTUtm9u2eO5Qb7rZXlYzoKqPt8TSH+TA=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE=
@ -1093,8 +1093,8 @@ github.com/kitex-contrib/obs-opentelemetry/logging/logrus v0.0.0-20220601144657-
github.com/kitex-contrib/tracer-opentracing v0.0.2/go.mod h1:mprt5pxqywFQxlHb7ugfiMdKbABTLI9YrBYs9WmlK5Q=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
@ -1919,8 +1919,8 @@ golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -2258,8 +2258,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -22,17 +22,16 @@ import (
"fmt"
"net/url"
"strconv"
"strings"
"time"
"github.com/google/uuid"
"github.com/dapr/components-contrib/state"
stateutils "github.com/dapr/components-contrib/state/utils"
"github.com/dapr/kit/logger"
"github.com/dapr/kit/metadata"
// Blank import for the underlying Oracle Database driver.
_ "github.com/sijms/go-ora/v2"
"github.com/google/uuid"
goora "github.com/sijms/go-ora/v2"
)
const (
@ -78,23 +77,26 @@ func parseMetadata(meta map[string]string) (oracleDatabaseMetadata, error) {
// Init sets up OracleDatabase connection and ensures that the state table exists.
func (o *oracleDatabaseAccess) Init(ctx context.Context, metadata state.Metadata) error {
meta, err := parseMetadata(metadata.Properties)
o.metadata = meta
if err != nil {
return err
}
if o.metadata.ConnectionString != "" {
o.connectionString = meta.ConnectionString
} else {
o.metadata = meta
if o.metadata.ConnectionString == "" {
o.logger.Error("Missing Oracle Database connection string")
return errors.New(errMissingConnectionString)
}
if o.metadata.OracleWalletLocation != "" {
o.connectionString += "?TRACE FILE=trace.log&SSL=enable&SSL Verify=false&WALLET=" + url.QueryEscape(o.metadata.OracleWalletLocation)
o.connectionString, err = parseConnectionString(meta)
if err != nil {
o.logger.Error(err)
return err
}
db, err := sql.Open("oracle", o.connectionString)
if err != nil {
o.logger.Error(err)
return err
}
@ -105,12 +107,62 @@ func (o *oracleDatabaseAccess) Init(ctx context.Context, metadata state.Metadata
return err
}
err = o.ensureStateTable(o.metadata.TableName)
return o.ensureStateTable(o.metadata.TableName)
}
func parseConnectionString(meta oracleDatabaseMetadata) (string, error) {
username := ""
password := ""
host := ""
port := 0
serviceName := ""
query := url.Values{}
options := make(map[string]string)
connectionStringURL, err := url.Parse(meta.ConnectionString)
if err != nil {
return err
return "", err
}
return nil
isURL := connectionStringURL.Scheme != "" && connectionStringURL.Host != ""
if isURL {
username = connectionStringURL.User.Username()
password, _ = connectionStringURL.User.Password()
query = connectionStringURL.Query()
serviceName = strings.TrimPrefix(connectionStringURL.Path, "/")
if strings.Contains(connectionStringURL.Host, ":") {
host = strings.Split(connectionStringURL.Host, ":")[0]
} else {
host = connectionStringURL.Host
}
} else {
host = connectionStringURL.Path
}
if connectionStringURL.Port() != "" {
port, err = strconv.Atoi(connectionStringURL.Port())
if err != nil {
return "", err
}
}
for k, v := range query {
options[k] = v[0]
}
if meta.OracleWalletLocation != "" {
options["WALLET"] = meta.OracleWalletLocation
options["TRACE FILE"] = "trace.log"
options["SSL"] = "enable"
options["SSL Verify"] = "false"
}
if strings.Contains(host, "(DESCRIPTION") {
// the connection string is a URL that contains the descriptor and authentication info
return goora.BuildJDBC(username, password, host, options), nil
} else {
return goora.BuildUrl(host, port, serviceName, username, password, options), nil
}
}
// Set makes an insert or update to the database.
@ -170,7 +222,7 @@ func (o *oracleDatabaseAccess) doSet(ctx context.Context, db querier, req *state
if req.Options.Concurrency == state.FirstWrite {
stmt = `INSERT INTO ` + o.metadata.TableName + `
(key, value, binary_yn, etag, expiration_time)
VALUES
VALUES
(:key, :value, :binary_yn, :etag, ` + ttlStatement + `) `
} else {
// As per Discord Thread https://discord.com/channels/778680217417809931/901141713089863710/938520959562952735 expiration time is reset in case of an update.

View File

@ -0,0 +1,155 @@
/*
Copyright 2025 The Dapr Authors
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 oracledatabase
import (
"net/url"
"testing"
"github.com/dapr/components-contrib/metadata"
"github.com/dapr/components-contrib/state"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestConnectionString(t *testing.T) {
tests := []struct {
name string
metadata map[string]string
expectedConn string
expectedError string
withWallet bool
walletLocation string
}{
{
name: "Simple URL format",
metadata: map[string]string{
"connectionString": "oracle://system:pass@localhost:1521/FREEPDB1",
},
expectedConn: "oracle://system:pass@localhost:1521/FREEPDB1?",
},
{
name: "Pure descriptor format",
metadata: map[string]string{
"connectionString": "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=FREEPDB1)))",
},
expectedConn: "oracle://:@:0/?connStr=%28DESCRIPTION%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Dlocalhost%29%28PORT%3D1521%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DFREEPDB1%29%29%29",
},
{
name: "URL with descriptor format",
metadata: map[string]string{
"connectionString": "oracle://system:pass@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=FREEPDB1)))",
},
expectedConn: "oracle://system:pass@:0/?connStr=%28DESCRIPTION%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Dlocalhost%29%28PORT%3D1521%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DFREEPDB1%29%29%29",
},
{
name: "Complex descriptor with load balancing and failover",
metadata: map[string]string{
"connectionString": "(DESCRIPTION=(CONNECT_TIMEOUT=30)(RETRY_COUNT=20)(RETRY_DELAY=3)(FAILOVER=ON)(LOAD_BALANCE=OFF)(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=db1.example.com)(PORT=1521)))(ADDRESS_LIST=(LOAD_BALANCE=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=db2.example.com)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=FREEPDB1_service)))",
},
expectedConn: "oracle://:@:0/?connStr=%28DESCRIPTION%3D%28CONNECT_TIMEOUT%3D30%29%28RETRY_COUNT%3D20%29%28RETRY_DELAY%3D3%29%28FAILOVER%3DON%29%28LOAD_BALANCE%3DOFF%29%28ADDRESS_LIST%3D%28LOAD_BALANCE%3DON%29%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Ddb1.example.com%29%28PORT%3D1521%29%29%29%28ADDRESS_LIST%3D%28LOAD_BALANCE%3DON%29%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Ddb2.example.com%29%28PORT%3D1521%29%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DFREEPDB1_service%29%29%29",
},
{
name: "Simple URL with wallet",
metadata: map[string]string{
"connectionString": "oracle://system:pass@localhost:1521/service",
"oracleWalletLocation": "/path/to/wallet",
},
withWallet: true,
walletLocation: "/path/to/wallet",
expectedConn: "oracle://system:pass@localhost:1521/service?WALLET=%2Fpath%2Fto%2Fwallet&TRACE FILE=trace.log&SSL=enable&SSL Verify=false",
},
{
name: "Descriptor with wallet",
metadata: map[string]string{
"connectionString": "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=test.example.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=FREEPDB1)))",
"oracleWalletLocation": "/path/to/wallet",
},
withWallet: true,
walletLocation: "/path/to/wallet",
expectedConn: "oracle://:@:0/?WALLET=%2Fpath%2Fto%2Fwallet&TRACE FILE=trace.log&SSL=enable&SSL Verify=false&connStr=%28DESCRIPTION%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Dtest.example.com%29%28PORT%3D1521%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DFREEPDB1%29%29%29",
},
{
name: "URL with descriptor and existing parameters",
metadata: map[string]string{
"connectionString": "oracle://system:pass@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=test.example.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=FREEPDB1)))?param1=value1",
"oracleWalletLocation": "/path/to/wallet",
},
withWallet: true,
walletLocation: "/path/to/wallet",
expectedConn: "oracle://system:pass@:0/?param1=value1&TRACE FILE=trace.log&SSL=enable&SSL Verify=false&WALLET=%2Fpath%2Fto%2Fwallet&connStr=%28DESCRIPTION%3D%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Dtest.example.com%29%28PORT%3D1521%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DFREEPDB1%29%29%29",
},
{
name: "Compressed descriptor format",
metadata: map[string]string{
"connectionString": "(DESCRIPTION=(CONNECT_TIMEOUT=90)(RETRY_COUNT=20)(RETRY_DELAY=3)(TRANSPORT_CONNECT_TIMEOUT=3)(ADDRESS=(PROTOCOL=TCP)(HOST=db.example.com)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=MYSERVICE)))",
},
expectedConn: "oracle://@:0/?connStr=%28DESCRIPTION%3D%28CONNECT_TIMEOUT%3D90%29%28RETRY_COUNT%3D20%29%28RETRY_DELAY%3D3%29%28TRANSPORT_CONNECT_TIMEOUT%3D3%29%28ADDRESS%3D%28PROTOCOL%3DTCP%29%28HOST%3Ddb.example.com%29%28PORT%3D1521%29%29%28CONNECT_DATA%3D%28SERVICE_NAME%3DMYSERVICE%29%29%29",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create metadata
metadata := state.Metadata{
Base: metadata.Base{
Properties: tt.metadata,
},
}
meta, err := parseMetadata(metadata.Properties)
require.NoError(t, err)
actualConnectionString, err := parseConnectionString(meta)
require.NoError(t, err)
if tt.expectedError != "" {
require.Error(t, err)
assert.Contains(t, err.Error(), tt.expectedError)
return
} else {
require.NoError(t, err)
}
expectedURL, err := url.Parse(tt.expectedConn)
require.NoError(t, err)
actualURL, err := url.Parse(actualConnectionString)
require.NoError(t, err)
assert.Equal(t, expectedURL.Scheme, actualURL.Scheme)
assert.Equal(t, expectedURL.Host, actualURL.Host)
assert.Equal(t, expectedURL.Path, actualURL.Path)
assert.Equal(t, expectedURL.User.Username(), actualURL.User.Username())
ep, _ := expectedURL.User.Password()
ap, _ := actualURL.User.Password()
assert.Equal(t, ep, ap)
query, err := url.ParseQuery(expectedURL.RawQuery)
require.NoError(t, err)
for k, v := range query {
assert.Equal(t, v, actualURL.Query()[k])
}
if tt.withWallet {
assert.Equal(t, tt.walletLocation, meta.OracleWalletLocation)
assert.Contains(t, actualConnectionString, "WALLET=")
assert.Contains(t, actualConnectionString, "SSL=enable")
}
})
}
}

View File

@ -182,7 +182,7 @@ require (
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9 // indirect
github.com/hamba/avro/v2 v2.28.0 // indirect
github.com/hashicorp/consul/api v1.25.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@ -210,7 +210,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/k0kubun/pp v3.0.1+incompatible // indirect
github.com/klauspost/compress v1.17.10 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/knadh/koanf v1.4.1 // indirect
github.com/kylelemons/godebug v1.1.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
@ -312,7 +312,7 @@ require (
golang.org/x/arch v0.10.0 // indirect
golang.org/x/crypto v0.35.0 // indirect
golang.org/x/exp v0.0.0-20241204233417-43b7b7cde48d // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.36.0 // indirect
golang.org/x/oauth2 v0.27.0 // indirect
golang.org/x/sync v0.11.0 // indirect
@ -320,7 +320,7 @@ require (
golang.org/x/term v0.29.0 // indirect
golang.org/x/text v0.22.0 // indirect
golang.org/x/time v0.6.0 // indirect
golang.org/x/tools v0.28.0 // indirect
golang.org/x/tools v0.30.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
google.golang.org/api v0.196.0 // indirect
google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61 // indirect

View File

@ -783,8 +783,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8
github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9 h1:NEoabXt33PDWK4fXryK4e+XX+fSKDmmu9vg3yb9YI2M=
github.com/hamba/avro/v2 v2.22.2-0.20240625062549-66aad10411d9/go.mod h1:fQVdB2mFZBhPW1D5Abej41LMvrErARGrrdjOnKbm5yw=
github.com/hamba/avro/v2 v2.28.0 h1:E8J5D27biyAulWKNiEBhV85QPc9xRMCUCGJewS0KYCE=
github.com/hamba/avro/v2 v2.28.0/go.mod h1:9TVrlt1cG1kkTUtm9u2eO5Qb7rZXlYzoKqPt8TSH+TA=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE=
@ -951,8 +951,8 @@ github.com/kitex-contrib/monitor-prometheus v0.0.0-20210817080809-024dd7bd51e1/g
github.com/kitex-contrib/obs-opentelemetry v0.0.0-20220601144657-c60210e3c928/go.mod h1:VvMzPMfgL7iUG92eVZGuRybGVMKzuSrsfMvHHpL7/Ac=
github.com/kitex-contrib/obs-opentelemetry/logging/logrus v0.0.0-20220601144657-c60210e3c928/go.mod h1:Eml/0Z+CqgGIPf9JXzLGu+N9NJoy2x5pqypN+hmKArE=
github.com/kitex-contrib/tracer-opentracing v0.0.2/go.mod h1:mprt5pxqywFQxlHb7ugfiMdKbABTLI9YrBYs9WmlK5Q=
github.com/klauspost/compress v1.17.10 h1:oXAz+Vh0PMUvJczoi+flxpnBEPxoER1IaAnU/NMPtT0=
github.com/klauspost/compress v1.17.10/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.1.0/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY=
@ -1633,8 +1633,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -1922,8 +1922,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -15,7 +15,7 @@ require (
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect

View File

@ -27,8 +27,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=