Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
SylvainJuge committed Sep 16, 2024
1 parent 5a82aac commit 1619595
Show file tree
Hide file tree
Showing 5 changed files with 446 additions and 0 deletions.
24 changes: 24 additions & 0 deletions jmx-scrapper/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,22 @@ dependencies {
implementation("io.opentelemetry:opentelemetry-sdk-testing")

implementation("io.opentelemetry.instrumentation:opentelemetry-jmx-metrics")

}

testing {
suites {
val integrationTest by registering(JvmTestSuite::class) {
dependencies {
implementation("org.testcontainers:junit-jupiter")
implementation("org.slf4j:slf4j-simple")
}
}
}
}

tasks {

shadowJar {
mergeServiceFiles()

Expand All @@ -38,7 +51,9 @@ tasks {

withType<Test>().configureEach {
dependsOn(shadowJar)
dependsOn(named("appJar"))
systemProperty("shadow.jar.path", shadowJar.get().archiveFile.get().asFile.absolutePath)
systemProperty("app.jar.path", named<Jar>("appJar").get().archiveFile.get().asFile.absolutePath)
systemProperty("gradle.project.version", "${project.version}")
}

Expand All @@ -50,6 +65,15 @@ tasks {
}
}

tasks.register<Jar>("appJar") {
from(sourceSets.get("integrationTest").output)
archiveClassifier.set("app")
manifest {
attributes["Main-Class"] = "io.opentelemetry.contrib.jmxscraper.TestApp"
}
}


// Don't publish non-shadowed jar (shadowJar is in shadowRuntimeElements)
with(components["java"] as AdhocComponentWithVariants) {
configurations.forEach {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package io.opentelemetry.contrib.jmxscraper;

import java.io.IOException;
import java.net.MalformedURLException;
import java.security.Provider;
import java.security.Security;
import java.util.HashMap;
import java.util.Map;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.RealmCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class JmxRemoteClient {

private static final Logger logger = LoggerFactory.getLogger(JmxRemoteClient.class);

private final String host;
private final int port;
private String userName;
private String password;
private String profile;
private String realm;
private boolean sslRegistry;

private JmxRemoteClient(String host, int port) {
this.host = host;
this.port = port;
}

public static JmxRemoteClient createNew(String host, int port) {
return new JmxRemoteClient(host, port);
}

public JmxRemoteClient userCredentials(String userName, String password) {
this.userName = userName;
this.password = password;
return this;
}

public JmxRemoteClient withRemoteProfile(String profile) {
this.profile = profile;
return this;
}

public JmxRemoteClient withRealm(String realm) {
this.realm = realm;
return this;
}

public JmxRemoteClient withSSLRegistry() {
this.sslRegistry = true;
return this;
}

public JMXConnector connect() throws IOException {
Map<String, Object> env = new HashMap<>();
if (userName != null && password != null) {
env.put(JMXConnector.CREDENTIALS, new String[] {userName, password});
}

if (profile != null) {
env.put("jmx.remote.profile", profile);
}

try {
// Not all supported versions of Java contain this Provider
Class<?> klass = Class.forName("com.sun.security.sasl.Provider");
Provider provider = (Provider) klass.getDeclaredConstructor().newInstance();
Security.addProvider(provider);

env.put(
"jmx.remote.sasl.callback.handler",
(CallbackHandler) callbacks -> {
for (Callback callback : callbacks) {
if (callback instanceof NameCallback) {
((NameCallback) callback).setName(userName);
} else if (callback instanceof PasswordCallback) {
char[] pwd = password == null ? null : password.toCharArray();
((PasswordCallback) callback).setPassword(pwd);
} else if (callback instanceof RealmCallback) {
((RealmCallback) callback).setText(realm);
} else {
throw new UnsupportedCallbackException(callback);
}
}
});
} catch (final ReflectiveOperationException e) {
logger.warn("SASL unsupported in current environment: " + e.getMessage(), e);
}

JMXServiceURL url = buildUrl(host, port);
try {
if (sslRegistry) {
return connectSSLRegistry(url, env);
} else {
return JMXConnectorFactory.connect(url, env);
}
} catch (IOException e) {
throw new IOException("Unable to connect to " + url.getHost() + ":" + url.getPort(), e);
}
}

public JMXConnector connectSSLRegistry(JMXServiceURL url, Map<String, Object> env) {
throw new IllegalStateException("TODO");
}

private static JMXServiceURL buildUrl(String host, int port) {
StringBuilder sb = new StringBuilder("service:jmx:rmi:///jndi/rmi://");
if (host != null) {
sb.append(host);
}
sb.append(":")
.append(port)
.append("/jmxrmi");

try {
return new JMXServiceURL(sb.toString());
} catch (MalformedURLException e) {
throw new IllegalArgumentException("invalid url", e);
}
}

}
Loading

0 comments on commit 1619595

Please sign in to comment.