Skip to content

Commit def6661

Browse files
Added remote jmx flag for jBoss6 (#175)
* Added remote jmx flag for jBoss6 * using optional paramters * removed bool value for remote flag command parameter * Changelog * removed deprecated methods Open and OpenWithSSL * changelog * Added documentation
1 parent 95160f9 commit def6661

File tree

4 files changed

+94
-29
lines changed

4 files changed

+94
-29
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## Next Release
99

10+
### Changed
11+
12+
- New JMX option for remote URL protocol connections.
13+
- Changed JMX open method. New `jmx.OpenWithParameters` accepts optionals parameters like SSL, remote connections, etc. Old integrations using old methods `jmx.OpenWithSSL` and `jmx.Open` should use this new `jmx.OpenWithParameters` method instead.
14+
15+
## 3.1.2
16+
1017
### Added
1118

1219
- Protocol v3: See full [documentation](docs/protocol-v3.md).

docs/toolset/jmx.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ the [SDK JMX GoDoc page]([http.New GoDoc](https://godoc.org/github.com/newrelic/
3030

3131
* `jmx.Open` ([GoDoc]([http.New GoDoc](https://godoc.org/github.com/newrelic/infra-integrations-sdk/jmx#Open)))
3232
- Instantiates a JMX client. It requires a `hostname` and a `port` as arguments. `username` and
33-
`password` are optional (pass empty strings `""` if no user/password).
33+
`password` are optional (pass empty strings `""` if no user/password). There is also the possibility to configure
34+
the JMX agent with SSL or configure the remote URL connection using the [Option](https://godoc.org/github.com/newrelic/infra-integrations-sdk/jmx#Option) type.
35+
See example below using the SSL configuration.
3436
- By default, the generated client will look for the [NRJMX tool](#installing-nr-jmx) in the path `/usr/bin/nrjmx`,
3537
but this location can be overriden by means of the `NR_JMX_TOOL` environment variable.
3638
- This function will return the global `ErrJmxCmdRunning` error, if there is already another instance of NRJMX
@@ -42,7 +44,7 @@ the [SDK JMX GoDoc page]([http.New GoDoc](https://godoc.org/github.com/newrelic/
4244
MBean Object Name (in the `domain:key-property-list` form) and the value is the sample value for this metric
4345
at the given moment.
4446

45-
## Basic usage example
47+
## Example 1: Basic usage
4648

4749
```go
4850
jmx.Open("127.0.0.1", "9010", "", "")
@@ -74,3 +76,23 @@ java.lang:type=OperatingSystem,attr=AvailableProcessors -> 8
7476
java.lang:type=OperatingSystem,attr=FreeSwapSpaceSize -> 977272832
7577
java.lang:type=OperatingSystem,attr=ProcessCpuTime -> 1039197000
7678
```
79+
80+
# Example 2: Open connection with SSL
81+
```go
82+
ssl := WithSSL(
83+
"/etc/pki/JMXClientKeyStore.key",
84+
"password_key",
85+
"/etc/pki/JMXClientTrustStore.key",
86+
"password_trust",
87+
)
88+
jmx.Open("127.0.0.1", "9010", "", "", ssl)
89+
```
90+
91+
# Example 3: Remoting protocol for JMX
92+
Some jBoss versions need the `remoting-jmx` protocol URL. Use `WithRemoteProtocol()` for using this remoting URL.
93+
- **URL without remoting protocol** `service:jmx:rmi:///jndi/rmi://host:port/jmxrmi`
94+
- **Remoting URL** `service:jmx:remoting-jmx://host:port`
95+
96+
```go
97+
jmx.Open("127.0.0.1", "9010", "", "", WithRemoteProtocol())
98+
```

jmx/jmx.go

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,38 +39,82 @@ 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) (c []string) {
42+
// connectionConfig is the configuration for the nrjmx command.
43+
type connectionConfig struct {
44+
hostname string
45+
port string
46+
username string
47+
password string
48+
keyStore string
49+
keyStorePassword string
50+
trustStore string
51+
trustStorePassword string
52+
remote bool
53+
}
54+
55+
func (cfg *connectionConfig) isSSL() bool {
56+
return cfg.keyStore != "" && cfg.keyStorePassword != "" && cfg.trustStore != "" && cfg.trustStorePassword != ""
57+
}
58+
59+
func (cfg *connectionConfig) command() []string {
60+
c := make([]string, 0)
4361
if os.Getenv("NR_JMX_TOOL") != "" {
4462
c = strings.Split(os.Getenv("NR_JMX_TOOL"), " ")
4563
} else {
4664
c = []string{jmxCommand}
4765
}
4866

49-
c = append(c, "--hostname", hostname, "--port", port)
50-
if username != "" && password != "" {
51-
c = append(c, "--username", username, "--password", password)
67+
c = append(c, "--hostname", cfg.hostname, "--port", cfg.port)
68+
if cfg.username != "" && cfg.password != "" {
69+
c = append(c, "--username", cfg.username, "--password", cfg.password)
70+
}
71+
if cfg.remote {
72+
c = append(c, "--remote")
73+
}
74+
if cfg.isSSL() {
75+
c = append(c, "--keyStore", cfg.keyStore, "--keyStorePassword", cfg.keyStorePassword, "--trustStore", cfg.trustStore, "--trustStorePassword", cfg.trustStorePassword)
5276
}
5377

54-
return
78+
return c
5579
}
5680

57-
func getCommandWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword string) []string {
58-
c := getCommand(hostname, port, username, password)
81+
// Open executes a nrjmx command using the given options.
82+
func Open(hostname, port, username, password string, opts ...Option) error {
83+
config := &connectionConfig{
84+
hostname: hostname,
85+
port: port,
86+
username: username,
87+
password: password,
88+
}
5989

60-
if keyStore != "" && keyStorePassword != "" && trustStore != "" && trustStorePassword != "" {
61-
c = append(c, "--keyStore", keyStore, "--keyStorePassword", keyStorePassword, "--trustStore", trustStore, "--trustStorePassword", trustStorePassword)
90+
for _, opt := range opts {
91+
opt(config)
6292
}
6393

64-
return c
94+
return openConnection(config)
6595
}
6696

67-
// Open will start the nrjmx command with the provided connection parameters.
68-
func Open(hostname, port, username, password string) error {
69-
return OpenWithSSL(hostname, port, username, password, "", "", "", "")
97+
// Option sets an option on integration level.
98+
type Option func(config *connectionConfig)
99+
100+
// WithSSL for SSL connection configuration.
101+
func WithSSL(keyStore, keyStorePassword, trustStore, trustStorePassword string) Option {
102+
return func(config *connectionConfig) {
103+
config.keyStore = keyStore
104+
config.keyStorePassword = keyStorePassword
105+
config.trustStore = trustStore
106+
config.trustStorePassword = trustStorePassword
107+
}
108+
}
109+
110+
// WithRemoteProtocol uses the remote JMX protocol URL.
111+
func WithRemoteProtocol() Option {
112+
return func(config *connectionConfig) {
113+
config.remote = true
114+
}
70115
}
71116

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 {
117+
func openConnection(config *connectionConfig) error {
74118
lock.Lock()
75119
defer lock.Unlock()
76120

@@ -88,7 +132,7 @@ func OpenWithSSL(hostname, port, username, password, keyStore, keyStorePassword,
88132
var err error
89133
var ctx context.Context
90134

91-
cliCommand := getCommandWithSSL(hostname, port, username, password, keyStore, keyStorePassword, trustStore, trustStorePassword)
135+
cliCommand := config.command()
92136

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

jmx/jmx_test.go

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestMain(m *testing.M) {
6060
}
6161
}
6262

63-
func TestOpen_OnlyWorksWhenClosed(t *testing.T) {
63+
func TestOpenWithParameters_OnlyWorksWhenClosed(t *testing.T) {
6464
defer Close()
6565

6666
assert.NoError(t, Open("", "", "", ""))
@@ -69,15 +69,6 @@ func TestOpen_OnlyWorksWhenClosed(t *testing.T) {
6969
assert.NoError(t, Open("", "", "", ""))
7070
}
7171

72-
func TestOpenWithSSL_OnlyWorksWhenClosed(t *testing.T) {
73-
defer Close()
74-
75-
assert.NoError(t, OpenWithSSL("", "", "", "", "", "", "", ""))
76-
assert.Error(t, OpenWithSSL("", "", "", "", "", "", "", ""))
77-
Close()
78-
assert.NoError(t, OpenWithSSL("", "", "", "", "", "", "", ""))
79-
}
80-
8172
func TestQuery(t *testing.T) {
8273
for q, isErr := range query2IsErr {
8374
assert.NoError(t, openWait("", "", "", "", openAttempts), "error on opening for query %s", q)
@@ -160,7 +151,8 @@ func openWait(hostname, port, username, password string, attempts int) error {
160151
}
161152

162153
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)
154+
ssl := WithSSL(keyStore, keyStorePassword, trustStore, trustStorePassword)
155+
err := Open(hostname, port, username, password, ssl)
164156
if err == ErrJmxCmdRunning && attempts > 0 {
165157
attempts--
166158
time.Sleep(10 * time.Millisecond)

0 commit comments

Comments
 (0)