Skip to content

Commit eead011

Browse files
authored
feat(nroci): Initial implementation for oci-go-sdk (#1117)
* fix: Change example * feat: Initial OCI Wrapper/Queries * test: extractRequestFieldsOCI and refactor * fix: Wrapper no longer passed through * fix: No more request and response wrappers * fix: Example takes in req * fix: Add go.mod and README * fix: Rename to clientWrapper * fix: Typo fix
1 parent 1401b37 commit eead011

File tree

5 files changed

+712
-0
lines changed

5 files changed

+712
-0
lines changed

v3/integrations/nroci/README.md

Whitespace-only changes.
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
"os/user"
8+
"path/filepath"
9+
"time"
10+
11+
"github.com/newrelic/go-agent/v3/integrations/nroci"
12+
"github.com/newrelic/go-agent/v3/newrelic"
13+
"github.com/oracle/oci-go-sdk/common"
14+
"github.com/oracle/oci-go-sdk/nosql"
15+
)
16+
17+
func main() {
18+
app, err := newrelic.NewApplication(
19+
newrelic.ConfigAppName("Basic NOSQLOCI App"),
20+
newrelic.ConfigLicense(os.Getenv("NEW_RELIC_LICENSE_KEY")),
21+
newrelic.ConfigDebugLogger(os.Stdout),
22+
)
23+
if err != nil {
24+
panic(err)
25+
}
26+
app.WaitForConnection(10 * time.Second) // for short lived processes in apps
27+
defer app.Shutdown(10 * time.Second)
28+
29+
usr, _ := user.Current()
30+
configPath := filepath.Join(usr.HomeDir, ".oci/config")
31+
configProvider, err := common.ConfigurationProviderFromFile(configPath, "")
32+
33+
clientWrapper, err := nroci.NRNewNoSQLClientWithConfigurationProvider(configProvider)
34+
if err != nil {
35+
panic(err)
36+
}
37+
38+
txn := app.StartTransaction("OCI NoSQL Transaction")
39+
40+
ctx := newrelic.NewContext(context.Background(), txn)
41+
42+
compartmentID := os.Getenv("COMPARTMENT_OCID")
43+
statement := "SELECT * FROM audienceData1"
44+
tableName := "audienceData1"
45+
46+
putReq := nosql.UpdateRowRequest{
47+
TableNameOrId: &tableName,
48+
UpdateRowDetails: nosql.UpdateRowDetails{
49+
Value: map[string]interface{}{
50+
"cookie_id": 123,
51+
"audience_data": map[string]interface{}{
52+
"ipaddr": "10.0.0.3",
53+
"audience_segment": map[string]interface{}{
54+
"sports_lover": "2018-11-30",
55+
"book_reader": "2018-12-01",
56+
},
57+
},
58+
},
59+
CompartmentId: &compartmentID,
60+
},
61+
}
62+
queryReq := nosql.QueryRequest{
63+
QueryDetails: nosql.QueryDetails{
64+
CompartmentId: &compartmentID,
65+
Statement: &statement,
66+
},
67+
}
68+
putRes, err := clientWrapper.UpdateRow(ctx, putReq)
69+
if err != nil {
70+
panic(err)
71+
}
72+
fmt.Printf("UpdateRow row: %v\nresult\n", putRes)
73+
74+
queryRes, err := clientWrapper.Query(ctx, queryReq)
75+
76+
if err != nil {
77+
panic(err)
78+
}
79+
fmt.Printf("QueryRow row: %v\nresult\n", queryRes)
80+
81+
txn.End()
82+
}

v3/integrations/nroci/go.mod

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/newrelic/go-agent/v3/integrations/nroci
2+
3+
go 1.24
4+
5+
require (
6+
github.com/newrelic/go-agent/v3 v3.42.0
7+
github.com/oracle/oci-go-sdk v24.3.0+incompatible
8+
)
9+
10+
replace github.com/newrelic/go-agent/v3 => ../..
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package nroci
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/newrelic/go-agent/v3/newrelic"
8+
"github.com/oracle/oci-go-sdk/common"
9+
"github.com/oracle/oci-go-sdk/nosql"
10+
)
11+
12+
func init() {
13+
14+
}
15+
16+
type NoSQLClient interface {
17+
Query(ctx context.Context, req nosql.QueryRequest) (nosql.QueryResponse, error)
18+
UpdateRow(ctx context.Context, req nosql.UpdateRowRequest) (nosql.UpdateRowResponse, error)
19+
CreateTable(ctx context.Context, req nosql.CreateTableRequest) (nosql.CreateTableResponse, error)
20+
DeleteRow(ctx context.Context, req nosql.DeleteRowRequest) (nosql.DeleteRowResponse, error)
21+
DeleteTable(ctx context.Context, req nosql.DeleteTableRequest) (nosql.DeleteTableResponse, error)
22+
GetRow(ctx context.Context, req nosql.GetRowRequest) (nosql.GetRowResponse, error)
23+
GetTable(ctx context.Context, req nosql.GetTableRequest) (nosql.GetTableResponse, error)
24+
UpdateTable(ctx context.Context, req nosql.UpdateTableRequest) (nosql.UpdateTableResponse, error)
25+
}
26+
27+
type NoSQLClientWrapper struct {
28+
Client NoSQLClient
29+
}
30+
31+
func NRNewNoSQLClientWithConfigurationProvider(configProvider common.ConfigurationProvider) (*NoSQLClientWrapper, error) {
32+
ociNoSQLClient, err := nosql.NewNosqlClientWithConfigurationProvider(configProvider)
33+
if err != nil {
34+
return nil, err
35+
}
36+
return &NoSQLClientWrapper{
37+
Client: ociNoSQLClient,
38+
}, nil
39+
}
40+
41+
func extractRequestFieldsOCI(req any) (string, string, string) {
42+
43+
requestNilCheck := func(value *string) string {
44+
if value != nil {
45+
return *value
46+
}
47+
return ""
48+
}
49+
50+
var collection, statement, compartmentID string
51+
switch r := req.(type) {
52+
case nosql.QueryRequest:
53+
// Could do FROM <table-name> type of parse?
54+
compartmentID = requestNilCheck(r.QueryDetails.CompartmentId)
55+
statement = requestNilCheck(r.QueryDetails.Statement)
56+
case nosql.UpdateRowRequest:
57+
collection = requestNilCheck(r.TableNameOrId)
58+
compartmentID = requestNilCheck(r.UpdateRowDetails.CompartmentId)
59+
case nosql.CreateTableRequest:
60+
collection = requestNilCheck(r.CreateTableDetails.Name)
61+
compartmentID = requestNilCheck(r.CreateTableDetails.CompartmentId)
62+
statement = requestNilCheck(r.CreateTableDetails.DdlStatement)
63+
case nosql.DeleteRowRequest:
64+
collection = requestNilCheck(r.TableNameOrId)
65+
compartmentID = requestNilCheck(r.CompartmentId)
66+
case nosql.DeleteTableRequest:
67+
collection = requestNilCheck(r.TableNameOrId)
68+
compartmentID = requestNilCheck(r.CompartmentId)
69+
case nosql.GetRowRequest:
70+
collection = requestNilCheck(r.TableNameOrId)
71+
compartmentID = requestNilCheck(r.CompartmentId)
72+
case nosql.GetTableRequest:
73+
collection = requestNilCheck(r.TableNameOrId)
74+
compartmentID = requestNilCheck(r.CompartmentId)
75+
case nosql.UpdateTableRequest:
76+
collection = requestNilCheck(r.TableNameOrId)
77+
compartmentID = requestNilCheck(r.UpdateTableDetails.CompartmentId)
78+
statement = requestNilCheck(r.UpdateTableDetails.DdlStatement)
79+
default:
80+
// keep strings empty
81+
}
82+
return collection, statement, compartmentID
83+
}
84+
85+
func executeWithDatastoreSegmentOCI[T any, R any](
86+
ctx context.Context,
87+
req R,
88+
fn func() (T, error),
89+
operation string,
90+
) (*T, error) {
91+
92+
txn := newrelic.FromContext(ctx)
93+
if txn == nil {
94+
return nil, fmt.Errorf("error executing OCI request, no transaction")
95+
}
96+
97+
collection, statement, compartmentID := extractRequestFieldsOCI(req)
98+
sgmt := newrelic.DatastoreSegment{
99+
StartTime: txn.StartSegmentNow(),
100+
Product: newrelic.DatastoreOracle,
101+
ParameterizedQuery: statement,
102+
Collection: collection,
103+
DatabaseName: compartmentID,
104+
Operation: operation,
105+
}
106+
res, err := fn()
107+
if err != nil {
108+
return nil, fmt.Errorf("error executing OCI requestL %s", err.Error())
109+
}
110+
111+
var response T = res
112+
sgmt.End()
113+
return &response, nil
114+
}
115+
116+
func (cw *NoSQLClientWrapper) Query(ctx context.Context, req nosql.QueryRequest) (*nosql.QueryResponse, error) {
117+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.QueryResponse, error) {
118+
return cw.Client.Query(ctx, req)
119+
}, "Query")
120+
}
121+
122+
func (cw *NoSQLClientWrapper) UpdateRow(ctx context.Context, req nosql.UpdateRowRequest) (*nosql.UpdateRowResponse, error) {
123+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.UpdateRowResponse, error) {
124+
return cw.Client.UpdateRow(ctx, req)
125+
}, "UpdateRow")
126+
}
127+
128+
func (cw *NoSQLClientWrapper) CreateTable(ctx context.Context, req nosql.CreateTableRequest) (*nosql.CreateTableResponse, error) {
129+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.CreateTableResponse, error) {
130+
return cw.Client.CreateTable(ctx, req)
131+
}, "CreateTable")
132+
}
133+
134+
func (cw *NoSQLClientWrapper) DeleteRow(ctx context.Context, req nosql.DeleteRowRequest) (*nosql.DeleteRowResponse, error) {
135+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.DeleteRowResponse, error) {
136+
return cw.Client.DeleteRow(ctx, req)
137+
}, "DeleteRow")
138+
}
139+
140+
func (cw *NoSQLClientWrapper) DeleteTable(ctx context.Context, req nosql.DeleteTableRequest) (*nosql.DeleteTableResponse, error) {
141+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.DeleteTableResponse, error) {
142+
return cw.Client.DeleteTable(ctx, req)
143+
}, "DeleteTable")
144+
}
145+
146+
func (cw *NoSQLClientWrapper) GetRow(ctx context.Context, req nosql.GetRowRequest) (*nosql.GetRowResponse, error) {
147+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.GetRowResponse, error) {
148+
return cw.Client.GetRow(ctx, req)
149+
}, "GetRow")
150+
}
151+
152+
func (cw *NoSQLClientWrapper) GetTable(ctx context.Context, req nosql.GetTableRequest) (*nosql.GetTableResponse, error) {
153+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.GetTableResponse, error) {
154+
return cw.Client.GetTable(ctx, req)
155+
}, "GetTable")
156+
}
157+
158+
func (cw *NoSQLClientWrapper) UpdateTable(ctx context.Context, req nosql.UpdateTableRequest) (*nosql.UpdateTableResponse, error) {
159+
return executeWithDatastoreSegmentOCI(ctx, req, func() (nosql.UpdateTableResponse, error) {
160+
return cw.Client.UpdateTable(ctx, req)
161+
}, "UpdateTable")
162+
}

0 commit comments

Comments
 (0)