Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

first spike of #125 to add a discovery mechanism to jolokia; which defau... #126

Closed
wants to merge 4 commits into from

2 participants

James Strachan Roland Huß
James Strachan
Collaborator

...lts to using files on the local machine (with keep-alive and tidying up of old files), a little JMX API and an experimental zeroconf plugin implementation.

currently only the JVM agent is supported; the challenge for the servlet/osgi agents is figuring out the jolokia URL before the servlet's been invoked...

James Strachan jstrachan first spike of #125 to add a discovery mechanism to jolokia; which de…
…faults to using files on the local machine (with keep-alive and tidying up of old files), a little JMX API and an experimental zeroconf plugin implementation.

currently only the JVM agent is supported; the challenge for the servlet/osgi agents is figuring out the jolokia URL before the servlet's been invoked...
9486b89
James Strachan

whoops - didn't mean to change that! Just about to remove this fix!

Roland Huß
Owner

I'll close that one and let's continue at #127. Snapshot is out, I target the weekend for a final 1.2.0 release with multicast support.

Roland Huß rhuss closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jan 23, 2014
  1. James Strachan

    first spike of #125 to add a discovery mechanism to jolokia; which de…

    jstrachan authored
    …faults to using files on the local machine (with keep-alive and tidying up of old files), a little JMX API and an experimental zeroconf plugin implementation.
    
    currently only the JVM agent is supported; the challenge for the servlet/osgi agents is figuring out the jolokia URL before the servlet's been invoked...
  2. James Strachan
  3. James Strachan

    added missing pom.xml

    jstrachan authored
  4. James Strachan
This page is out of date. Refresh to see the latest.
75 agent/core/src/main/java/org/jolokia/discovery/AgentDetails.java
View
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery;
+
+/**
+ * a DTO used for discovery
+ */
+public class AgentDetails {
+ private String location;
+ private String name;
+
+ public AgentDetails(String location) {
+ this(location, null);
+ }
+
+ /**
+ * The location cannot be null; if no name is specified then a default value is used
+ */
+ public AgentDetails(String location, String name) {
+ if (name == null) {
+ name = "Joloika Agent";
+ }
+ this.location = location;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ AgentDetails that = (AgentDetails) o;
+
+ if (!location.equals(that.location)) return false;
+ if (!name.equals(that.name)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = name.hashCode();
+ result = 31 * result + location.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "AgentDetails{" +
+ "name='" + name + '\'' +
+ ", location='" + location + '\'' +
+ '}';
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getLocation() {
+ return location;
+ }
+}
31 agent/core/src/main/java/org/jolokia/discovery/DiscoveryListener.java
View
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery;
+
+/**
+ * Listener interface for services which wish to register an interest in agents coming and going.
+ */
+public interface DiscoveryListener {
+ /**
+ * Invoked when an agent is started with the given details
+ */
+ void onAgentStarted(AgentDetails details);
+
+ /**
+ * Invoked when an agent is stopped
+ */
+ void onAgentStopped(AgentDetails details);
+}
32 agent/core/src/main/java/org/jolokia/discovery/DiscoveryMXBean.java
View
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery;
+
+import java.util.List;
+
+/**
+ * Provides the common API to all discovery mbeans so they work consistently across JMX
+ */
+public interface DiscoveryMXBean {
+
+ /**
+ * Uses the underlying discovery mechanism (e.g. files on the file system or ZeroConf etc) to discover
+ * all the Jolokia Agents that can be found
+ *
+ * @return the found details (name and location URL) of the found jolokia agents
+ */
+ List<AgentDetails> findAgents();
+}
159 agent/core/src/main/java/org/jolokia/discovery/JolokiaDiscovery.java
View
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A little helper class so that we can broadcast the details of jolokia agents so its easier to
+ * auto-discover them on a machine, such as via files or zeroconf etc
+ */
+public class JolokiaDiscovery {
+ protected static JolokiaDiscovery instance = new JolokiaDiscovery();
+ private List<DiscoveryListener> listeners = new CopyOnWriteArrayList<DiscoveryListener>();
+ private AtomicBoolean loaded = new AtomicBoolean(false);
+
+ /**
+ * Returns the single instance
+ */
+ public static JolokiaDiscovery getInstance() {
+ return instance;
+ }
+
+ /**
+ * Invoked when an agent is started on a given URL
+ */
+ public void agentStarted(AgentDetails details) {
+ onStartupFindClassPathDiscoveryAgents();
+ for (DiscoveryListener listener : listeners) {
+ listener.onAgentStarted(details);
+ }
+ }
+
+ /**
+ * Invoked when an agent is stopped on a given URL
+ */
+ public void agentStopped(AgentDetails details) {
+ onStartupFindClassPathDiscoveryAgents();
+ for (DiscoveryListener listener : listeners) {
+ listener.onAgentStopped(details);
+ }
+ }
+
+ public void addListener(DiscoveryListener listener) {
+ listeners.add(listener);
+ }
+
+ public void removeListener(DiscoveryListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Lets attempt to dynamically load a discovery agent if one is available on the classpath
+ */
+ protected void onStartupFindClassPathDiscoveryAgents() {
+ if (loaded.compareAndSet(false, true)) {
+ Set<String> classNames = new HashSet<String>();
+
+ loadDiscoveryAgentClassNames(classNames, Thread.currentThread().getContextClassLoader());
+ loadDiscoveryAgentClassNames(classNames, getClass().getClassLoader());
+
+
+ for (String className : classNames) {
+ Class clazz = loadClass(className);
+ if (clazz != null) {
+ Object instance = null;
+ try {
+ instance = clazz.newInstance();
+ } catch (Exception e) {
+ System.out.println("Failed to instantiate class: " + clazz + ". " + e);
+ e.printStackTrace();
+ }
+ if (instance instanceof DiscoveryListener) {
+ addListener((DiscoveryListener) instance);
+ }
+ }
+ }
+ }
+ }
+
+ protected void loadDiscoveryAgentClassNames(Set<String> classNames, ClassLoader classLoader) {
+ String path = "META-INF/services/org/jolokia/discovery/DiscoveryListener";
+ try {
+ Enumeration<URL> iter = classLoader.getResources(path);
+ while (iter.hasMoreElements()) {
+ URL url = iter.nextElement();
+ if (url != null) {
+ InputStream in = url.openStream();
+ if (in != null) {
+ try {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ while (true) {
+ String line = reader.readLine();
+ if (line != null) {
+ line = line.trim();
+ if (!line.startsWith("#") || line.length() > 0) {
+ classNames.add(line);
+ }
+ } else {
+ break;
+ }
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+
+ }
+ }
+ }
+ } catch (IOException e) {
+ System.out.println("Failed to discover services at " + path + ". " + e);
+ }
+ }
+
+ protected Class loadClass(String className) {
+ if (className != null && className.length() > 0) {
+ try {
+ return Class.forName(className);
+ } catch (Throwable e) {
+ try {
+ return Thread.currentThread().getContextClassLoader().loadClass(className);
+ } catch (Throwable e1) {
+ try {
+ return getClass().getClassLoader().loadClass(className);
+ } catch (Throwable e2) {
+ System.out.println("Failed to load class '" + className + "' on the classpath");
+ }
+ }
+ }
+ }
+ return null;
+ }
+}
339 agent/core/src/main/java/org/jolokia/discovery/file/FileDiscovery.java
View
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery.file;
+
+import org.jolokia.discovery.AgentDetails;
+import org.jolokia.discovery.DiscoveryListener;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A simple file based discovery implementation which just writes a file per agent into
+ * a jolokia discovery folder on the disk
+ */
+public class FileDiscovery implements FileDiscoveryMXBean, DiscoveryListener {
+ public static final String DEFAULT_TMP_DIR = "/tmp";
+ public static final String JOLOKIA_DISCOVERY_FOLDER = "jolokiaDiscovery";
+ public static final String JOLOKIA_FILE_EXTENSION = ".jolokia";
+
+ private static FileDiscovery instance;
+
+ private final File jolokiaDiscoverDirectory;
+ private AtomicBoolean started = new AtomicBoolean(false);
+ private boolean keepAlive;
+ private Timer timer;
+ private boolean ownTimer;
+ private Map<AgentDetails, File> detailsToFileMap = new ConcurrentHashMap<AgentDetails, File>();
+ private Map<AgentDetails, TimerTask> timerTasks = new ConcurrentHashMap<AgentDetails, TimerTask>();
+ private long keepAlivePeriod = 90 * 1000;
+ private long updateFilePeriod = 30 * 1000;
+ private TimerTask keepAliveTask;
+ private boolean registerInJmx = true;
+ private MBeanServer mBeanServer;
+ private ObjectName objectName;
+
+ /**
+ * Returns the singleton instance if its available
+ */
+ public static FileDiscovery getInstance() {
+ return instance;
+ }
+
+ public FileDiscovery() {
+ instance = this;
+ String tmpDir = DEFAULT_TMP_DIR;
+ try {
+ System.getProperty("java.io.tmpdir", DEFAULT_TMP_DIR);
+ } catch (Exception e) {
+ // ignore
+ }
+ jolokiaDiscoverDirectory = new File(tmpDir, JOLOKIA_DISCOVERY_FOLDER);
+ jolokiaDiscoverDirectory.mkdirs();
+ }
+
+ public void onAgentStarted(final AgentDetails details) {
+ final File file = createJolokiaFile(details);
+ if (file != null) {
+ checkStarted();
+ file.deleteOnExit();
+ detailsToFileMap.put(details, file);
+ writeAgentDetailsFile(file, details);
+
+ if (isKeepAlive()) {
+ if (updateFilePeriod > 0) {
+ TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ writeAgentDetailsFile(file, details);
+ }
+ };
+ timerTasks.put(details, task);
+ getTimer().scheduleAtFixedRate(task, updateFilePeriod, updateFilePeriod);
+ }
+ if (keepAlivePeriod > 0 && keepAliveTask == null) {
+ keepAliveTask = new TimerTask() {
+ @Override
+ public void run() {
+ removeOldFiles();
+ }
+ };
+ getTimer().scheduleAtFixedRate(keepAliveTask, keepAlivePeriod, keepAlivePeriod);
+ }
+ }
+ }
+ }
+
+ public void onAgentStopped(AgentDetails details) {
+ File file = detailsToFileMap.remove(details);
+ if (file == null) {
+ file = createJolokiaFile(details);
+ }
+ if (file != null) {
+ file.delete();
+ }
+ if (detailsToFileMap.isEmpty()) {
+ // lets stop the timer
+ stop();
+ }
+ }
+
+ protected void checkStarted() {
+ // TODO we may wish to add a more explicit start/stop lifecycle for this bean
+ // to take part of the usual JMX registration code?
+ if (started.compareAndSet(false, true)) {
+ // lets register in JMX
+ if (mBeanServer == null) {
+ mBeanServer = ManagementFactory.getPlatformMBeanServer();
+ }
+ try {
+ objectName = new ObjectName(FileDiscoveryMXBean.OBJECT_NAME);
+ if (!mBeanServer.isRegistered(objectName)) {
+ mBeanServer.registerMBean(this, objectName);
+ }
+ } catch (Exception e) {
+ System.out.println("Failed to register " + this + " in JMX: " + e);
+ }
+ }
+ }
+
+
+ protected void stop() {
+ try {
+ if (keepAliveTask != null) {
+ keepAliveTask.cancel();
+ }
+ for (TimerTask timerTask : timerTasks.values()) {
+ timerTask.cancel();
+ }
+ if (ownTimer) {
+ timer.cancel();
+ }
+ if (objectName != null && mBeanServer != null) {
+ try {
+ mBeanServer.unregisterMBean(objectName);
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ } finally {
+ timer = null;
+ keepAliveTask = null;
+ ownTimer = false;
+ timerTasks.clear();
+ started.set(false);
+ }
+ }
+
+ public List<AgentDetails> findAgents() {
+ List<AgentDetails> answer = new ArrayList<AgentDetails>();
+ File[] files = getJolokiaFiles();
+ for (File file : files) {
+ if (file.isFile() && file.length() > 0) {
+ AgentDetails details = readAgentDetailsFile(file);
+ if (details != null) {
+ answer.add(details);
+ }
+ }
+ }
+ return answer;
+ }
+
+ /**
+ * Returns all the current jolokia agent files
+ */
+ protected File[] getJolokiaFiles() {
+ File[] answer = jolokiaDiscoverDirectory.listFiles(new FileFilter() {
+ public boolean accept(File pathname) {
+ return pathname.getName().endsWith(JOLOKIA_FILE_EXTENSION);
+ }
+ });
+ if (answer == null) {
+ answer = new File[0];
+ }
+ return answer;
+ }
+
+ /**
+ * Removes any jolokia files which are too old (modified before the keepalive timer period
+ */
+ protected void removeOldFiles() {
+ long oldModifiedTime = System.currentTimeMillis() - getKeepAlivePeriod();
+ File[] files = getJolokiaFiles();
+ for (File file : files) {
+ if (file.isFile()) {
+ long modified = file.lastModified();
+ if (modified > 0 && modified < oldModifiedTime && !detailsToFileMap.containsValue(file)) {
+ System.out.println("Removing old jolokia file: " + file.getName()
+ + " as modified at " + new Date(modified));
+
+ file.delete();
+ }
+ }
+ }
+ }
+
+ protected File createJolokiaFile(AgentDetails details) {
+ String location = details.getLocation();
+ try {
+ URL url = new URL(location);
+ String fileName = url.getHost() + "." + url.getPort() + JOLOKIA_FILE_EXTENSION;
+ return new File(jolokiaDiscoverDirectory, fileName);
+ } catch (MalformedURLException e) {
+ System.out.println("Failed to parse location: " + location);
+ return null;
+ }
+ }
+
+ protected AgentDetails readAgentDetailsFile(File file) {
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(file));
+ try {
+ String location = reader.readLine();
+ if (location == null) {
+ return null;
+ }
+ String name = reader.readLine();
+ return new AgentDetails(location, name);
+ } finally {
+ try {
+ reader.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to read file: " + file);
+ }
+ }
+
+ protected void writeAgentDetailsFile(File file, AgentDetails details) {
+ try {
+ FileWriter writer = new FileWriter(file);
+ try {
+ writer.append(details.getLocation());
+ writer.append("\n");
+ writer.append(details.getName());
+ writer.append("\n");
+ } finally {
+ try {
+ writer.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write file: " + file);
+ }
+ }
+
+ public boolean isKeepAlive() {
+ return keepAlive;
+ }
+
+ /**
+ * Enables or disables the keep alive logic (whereby the jolokia files are updated
+ * periodically and old files are removed
+ */
+ public void setKeepAlive(boolean keepAlive) {
+ this.keepAlive = keepAlive;
+ }
+
+ /**
+ * Returns the current timer, lazy creating a new one if required
+ */
+ public Timer getTimer() {
+ if (timer == null) {
+ boolean daemon = true;
+ timer = new Timer("Jolokia FileDiscovery KeepAlive", daemon);
+ ownTimer = true;
+ }
+ return timer;
+ }
+
+ public void setTimer(Timer timer) {
+ this.timer = timer;
+ }
+
+ public long getKeepAlivePeriod() {
+ return keepAlivePeriod;
+ }
+
+ public void setKeepAlivePeriod(long keepAlivePeriod) {
+ this.keepAlivePeriod = keepAlivePeriod;
+ }
+
+ public boolean isRegisterInJmx() {
+ return registerInJmx;
+ }
+
+ public void setRegisterInJmx(boolean registerInJmx) {
+ this.registerInJmx = registerInJmx;
+ }
+
+ public long getUpdateFilePeriod() {
+ return updateFilePeriod;
+ }
+
+ public void setUpdateFilePeriod(long updateFilePeriod) {
+ this.updateFilePeriod = updateFilePeriod;
+ }
+
+ public MBeanServer getmBeanServer() {
+ return mBeanServer;
+ }
+
+ public void setmBeanServer(MBeanServer mBeanServer) {
+ this.mBeanServer = mBeanServer;
+ }
+}
26 agent/core/src/main/java/org/jolokia/discovery/file/FileDiscoveryMXBean.java
View
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2009-2013 Roland Huss
+ *
+ * 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 org.jolokia.discovery.file;
+
+import org.jolokia.discovery.DiscoveryMXBean;
+
+/**
+ * The JMX API for accessing the file discovery capability
+ */
+public interface FileDiscoveryMXBean extends DiscoveryMXBean {
+ // Name under which this bean gets registered
+ String OBJECT_NAME = "jolokia:type=FileDiscovery";
+}
1  agent/core/src/main/resources/META-INF/services/org/jolokia/discovery/DiscoveryListener
View
@@ -0,0 +1 @@
+org.jolokia.discovery.file.FileDiscovery
17 agent/jvm/src/main/java/org/jolokia/jvmagent/JolokiaServer.java
View
@@ -26,6 +26,7 @@
import javax.net.ssl.*;
import com.sun.net.httpserver.*;
+import org.jolokia.discovery.AgentDetails;
/**
* Factory for creating the HttpServer used for exporting
@@ -55,6 +56,9 @@
// Agent URL
private String url;
+ /// Agent details (URL and name mostly, for discovery)
+ private AgentDetails details;
+
// Handler for jolokia requests
private JolokiaHttpHandler jolokiaHttpHandler;
@@ -140,6 +144,16 @@ public String getUrl() {
}
/**
+ * Returns the details of this agent (the name and URL) for how this agent
+ * will appear in discovery JMX calls or tools
+ *
+ * @return the details of the agent (such as its name and URL)
+ */
+ public AgentDetails getDetails() {
+ return details;
+ }
+
+ /**
* Get configuration for this server
*
* @return server configuration
@@ -199,6 +213,9 @@ protected final void init(HttpServer pServer, JolokiaServerConfig pConfig, boole
}
url = String.format("%s://%s:%d%s",
pConfig.getProtocol(),realAddress.getCanonicalHostName(),port,contextPath);
+
+ String name = pConfig.getName();
+ details = new AgentDetails(url, name);
}
/**
11 agent/jvm/src/main/java/org/jolokia/jvmagent/JolokiaServerConfig.java
View
@@ -51,6 +51,7 @@
private boolean useSslClientAuthentication;
private char[] keystorePassword;
private Authenticator authenticator;
+ private String name;
/**
* Constructor which prepares the server configuration from a map
@@ -130,6 +131,15 @@ public int getPort() {
}
/**
+ * Returns the name of this agent when used with discovery
+ *
+ * @return name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
* Return a basic authenticator if user or password is given in the configuration. You can override
* this method if you want to provide an own authenticator.
*
@@ -218,6 +228,7 @@ protected void initConfigAndValidate(Map<String,String> agentConfig) {
String password = agentConfig.get("keystorePassword");
keystorePassword = password != null ? password.toCharArray() : new char[0];
+ name = agentConfig.get("name");
}
private void initAuthenticator() {
11 agent/jvm/src/main/java/org/jolokia/jvmagent/JvmAgent.java
View
@@ -16,6 +16,9 @@
* limitations under the License.
*/
+import org.jolokia.discovery.AgentDetails;
+import org.jolokia.discovery.JolokiaDiscovery;
+
import java.io.IOException;
@@ -89,7 +92,10 @@ private static void startAgent(JvmAgentConfig pConfig,boolean pLazy) {
server.start();
setStateMarker();
- System.out.println("Jolokia: Agent started with URL " + server.getUrl());
+ AgentDetails details = server.getDetails();
+ JolokiaDiscovery.getInstance().agentStarted(details);
+ System.out.println("Jolokia: Agent started with URL " + details.getLocation()
+ + " and name: " + details.getName());
} catch (RuntimeException exp) {
System.err.println("Could not start Jolokia agent: " + exp);
} catch (IOException exp) {
@@ -98,11 +104,14 @@ private static void startAgent(JvmAgentConfig pConfig,boolean pLazy) {
}
private static void stopAgent() {
+ AgentDetails details = server.getDetails();
try {
server.stop();
clearStateMarker();
} catch (RuntimeException exp) {
System.err.println("Could not stop Jolokia agent: " + exp);
+ } finally {
+ JolokiaDiscovery.getInstance().agentStopped(details);
}
}
24 agent/jvm/src/test/java/org/jolokia/jvmagent/JvmAgentTest.java
View
@@ -17,11 +17,16 @@
*/
import java.io.IOException;
+import java.util.List;
-import org.jolokia.jvmagent.JvmAgent;
+import org.jolokia.discovery.AgentDetails;
+import org.jolokia.discovery.file.FileDiscovery;
import org.jolokia.test.util.EnvTestUtil;
import org.testng.annotations.Test;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
/**
* @author roland
* @since 28.09.11
@@ -36,8 +41,23 @@ public void premain() throws IOException {
@Test
public void agentmain() throws IOException {
- JvmAgent.agentmain("mode=start,port=" + EnvTestUtil.getFreePort());
+ JvmAgent.agentmain("mode=start,name=Test Jolokia Agent,port=" + EnvTestUtil.getFreePort());
+
+ // now we should be able to discover the available agent URLs
+ FileDiscovery discovery = FileDiscovery.getInstance();
+ assertNotNull(discovery, "should have found an discovery");
+ List<AgentDetails> agents = discovery.findAgents();
+ assertTrue(agents.size() > 0, "Should have found at least one agent");
+ System.out.println("Found agents: " + agents);
+
JvmAgent.agentmain("mode=stop");
+
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ System.out.println("Now has agents: " + discovery.findAgents());
}
@Test
Something went wrong with that request. Please try again.