Skip to content

Commit 96a6c2b

Browse files
authored
Merge pull request #165 from newrelic/rc-ssl
SSL support for JMX
2 parents e6b5f50 + b48fde3 commit 96a6c2b

File tree

3 files changed

+66
-45
lines changed

3 files changed

+66
-45
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ You can easily fetch it using:
125125
### JMX support
126126

127127
The Integrations Go lang SDK supports getting metrics through JMX by calling the
128-
`jmx.Open()`, `jmx.Query()` and `jmx.Close()` functions. This JMX support relies
128+
`jmx.Open()`, `jmx.OpenWithSSL`, `jmx.Query()` and `jmx.Close()` functions. This JMX support relies
129129
on the nrjmx tool. Follow the steps in
130130
the [nrjmx](https://github.com/newrelic/nrjmx) repository to build it and set
131131
the `NR_JMX_TOOL` environment variable to point to the location of the nrjmx

jmx/jmx.go

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,25 +39,38 @@ const (
3939
jmxLineBuffer = 4 * 1024 * 1024 // Max 4MB per line. If single lines are outputting more JSON than that, we likely need smaller-scoped JMX queries
4040
)
4141

42-
func getCommand(hostname, port, username, password string) []string {
43-
var cliCommand []string
44-
42+
func getCommand(hostname, port, username, password string) (c []string) {
4543
if os.Getenv("NR_JMX_TOOL") != "" {
46-
cliCommand = strings.Split(os.Getenv("NR_JMX_TOOL"), " ")
44+
c = strings.Split(os.Getenv("NR_JMX_TOOL"), " ")
4745
} else {
48-
cliCommand = []string{jmxCommand}
46+
c = []string{jmxCommand}
4947
}
5048

51-
cliCommand = append(cliCommand, "--hostname", hostname, "--port", port)
49+
c = append(c, "--hostname", hostname, "--port", port)
5250
if username != "" && password != "" {
53-
cliCommand = append(cliCommand, "--username", username, "--password", password)
51+
c = append(c, "--username", username, "--password", password)
52+
}
53+
54+
return
55+
}
56+
57+
func getCommandWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword string) []string {
58+
c := getCommand(hostname, port, username, password)
59+
60+
if keyStore != "" && keyStorePassword != "" && trustStore != "" && trustStorePassword != "" {
61+
c = append(c, "--keyStore", keyStore, "--keyStorePassword", keyStorePassword, "--trustStore", trustStore, "--trustStorePassword", trustStorePassword)
5462
}
5563

56-
return cliCommand
64+
return c
5765
}
5866

5967
// Open will start the nrjmx command with the provided connection parameters.
6068
func Open(hostname, port, username, password string) error {
69+
return OpenWithSSL(hostname, port, username, password, "", "", "", "")
70+
}
71+
72+
// OpenWithSSL will start the nrjmx command with the provided SSL connection parameters
73+
func OpenWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword string) error {
6174
lock.Lock()
6275
defer lock.Unlock()
6376

@@ -75,7 +88,7 @@ func Open(hostname, port, username, password string) error {
7588
var err error
7689
var ctx context.Context
7790

78-
cliCommand := getCommand(hostname, port, username, password)
91+
cliCommand := getCommandWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword)
7992

8093
ctx, cancel = context.WithCancel(context.Background())
8194
cmd = exec.CommandContext(ctx, cliCommand[0], cliCommand[1:]...)

jmx/jmx_test.go

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ const (
1818
openAttempts = 5
1919
)
2020

21+
var query2IsErr = map[string]bool{
22+
"empty": false,
23+
"crash": true,
24+
"invalid": true,
25+
}
26+
2127
func TestMain(m *testing.M) {
2228
var testType string
2329
flag.StringVar(&testType, "test.type", "", "")
@@ -54,55 +60,53 @@ func TestMain(m *testing.M) {
5460
}
5561
}
5662

57-
func TestJmxOpen(t *testing.T) {
63+
func TestOpen_OnlyWorksWhenClosed(t *testing.T) {
5864
defer Close()
5965

60-
if err := Open("", "", "", ""); err != nil {
61-
t.Error(err)
62-
}
63-
64-
if Open("", "", "", "") == nil {
65-
t.Error()
66-
}
66+
assert.NoError(t, Open("", "", "", ""))
67+
assert.Error(t, Open("", "", "", ""))
68+
Close()
69+
assert.NoError(t, Open("", "", "", ""))
6770
}
6871

69-
func TestJmxQuery(t *testing.T) {
72+
func TestOpenWithSSL_OnlyWorksWhenClosed(t *testing.T) {
7073
defer Close()
7174

72-
if err := openWait("", "", "", "", openAttempts); err != nil {
73-
t.Error(err)
74-
}
75-
76-
if _, err := Query("empty", timeout); err != nil {
77-
t.Error(err)
78-
}
75+
assert.NoError(t, OpenWithSSL("", "", "", "", "", "", "", ""))
76+
assert.Error(t, OpenWithSSL("", "", "", "", "", "", "", ""))
77+
Close()
78+
assert.NoError(t, OpenWithSSL("", "", "", "", "", "", "", ""))
7979
}
8080

81-
func TestJmxCrashQuery(t *testing.T) {
82-
defer Close()
81+
func TestQuery(t *testing.T) {
82+
for q, isErr := range query2IsErr {
83+
assert.NoError(t, openWait("", "", "", "", openAttempts), "error on opening for query %s", q)
8384

84-
if err := openWait("", "", "", "", openAttempts); err != nil {
85-
t.Error(err)
86-
}
87-
88-
if _, err := Query("crash", timeout); err == nil {
89-
t.Error()
85+
_, err := Query(q, timeout)
86+
if isErr {
87+
assert.Error(t, err)
88+
} else {
89+
assert.NoError(t, err)
90+
}
91+
Close()
9092
}
9193
}
9294

93-
func TestJmxInvalidQuery(t *testing.T) {
94-
defer Close()
95-
96-
if err := openWait("", "", "", "", openAttempts); err != nil {
97-
t.Error(err)
98-
}
95+
func TestQuery_WithSSL(t *testing.T) {
96+
for q, isErr := range query2IsErr {
97+
assert.NoError(t, openWaitWithSSL("", "", "", "", "", "", "", "", openAttempts))
9998

100-
if _, err := Query("invalid", timeout); err == nil {
101-
t.Error()
99+
_, err := Query(q, timeout)
100+
if isErr {
101+
assert.Error(t, err)
102+
} else {
103+
assert.NoError(t, err)
104+
}
105+
Close()
102106
}
103107
}
104108

105-
func TestJmxTimeoutQuery(t *testing.T) {
109+
func TestQuery_TimeoutReturnsError(t *testing.T) {
106110
defer Close()
107111

108112
if err := openWait("", "", "", "", openAttempts); err != nil {
@@ -152,12 +156,16 @@ func TestJmxTimeoutBigQuery(t *testing.T) {
152156

153157
// tests can overlap, and as jmx-cmd is a singleton, waiting for it to be closed is mandatory
154158
func openWait(hostname, port, username, password string, attempts int) error {
155-
err := Open(hostname, port, username, password)
159+
return openWaitWithSSL(hostname, port, username, password, "", "", "", "", attempts)
160+
}
161+
162+
func openWaitWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword string, attempts int) error {
163+
err := OpenWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword)
156164
if err == ErrJmxCmdRunning && attempts > 0 {
157165
attempts--
158166
time.Sleep(10 * time.Millisecond)
159167

160-
return openWait(hostname, port, username, password, attempts)
168+
return openWaitWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword, attempts)
161169
}
162170

163171
return err

0 commit comments

Comments
 (0)