diff --git a/src/main/java/org/vertx/java/core/Vertx.java b/src/main/java/org/vertx/java/core/Vertx.java index 17744afb5a7..c545f8f8713 100644 --- a/src/main/java/org/vertx/java/core/Vertx.java +++ b/src/main/java/org/vertx/java/core/Vertx.java @@ -38,7 +38,7 @@ * * @author Tim Fox */ -public abstract class Vertx { +public abstract class Vertx implements VertxMXBean { private static VertxFactory loadFactory() { ServiceLoader factories = ServiceLoader.load(VertxFactory.class); diff --git a/src/main/java/org/vertx/java/core/VertxMXBean.java b/src/main/java/org/vertx/java/core/VertxMXBean.java new file mode 100644 index 00000000000..cda527e334d --- /dev/null +++ b/src/main/java/org/vertx/java/core/VertxMXBean.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.core; + +/** + * @author pidster + * + */ +public interface VertxMXBean { + + int getBackgroundPoolSize(); + + int getCorePoolSize(); +} diff --git a/src/main/java/org/vertx/java/core/eventbus/EventBus.java b/src/main/java/org/vertx/java/core/eventbus/EventBus.java index b580d36b02b..87950682937 100644 --- a/src/main/java/org/vertx/java/core/eventbus/EventBus.java +++ b/src/main/java/org/vertx/java/core/eventbus/EventBus.java @@ -48,7 +48,7 @@ * * @author Tim Fox */ -public interface EventBus { +public interface EventBus extends EventBusMXBean { /** * Send a JSON object as a message diff --git a/src/main/java/org/vertx/java/core/eventbus/EventBusMXBean.java b/src/main/java/org/vertx/java/core/eventbus/EventBusMXBean.java new file mode 100644 index 00000000000..3af6caafca2 --- /dev/null +++ b/src/main/java/org/vertx/java/core/eventbus/EventBusMXBean.java @@ -0,0 +1,28 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.core.eventbus; + +/** + * @author pidster + * + */ +public interface EventBusMXBean { + + long getSent(); + + long getReceived(); + +} diff --git a/src/main/java/org/vertx/java/core/eventbus/impl/BaseMessage.java b/src/main/java/org/vertx/java/core/eventbus/impl/BaseMessage.java index 3bdc1655eb6..ccf083b744b 100644 --- a/src/main/java/org/vertx/java/core/eventbus/impl/BaseMessage.java +++ b/src/main/java/org/vertx/java/core/eventbus/impl/BaseMessage.java @@ -80,15 +80,15 @@ protected BaseMessage(Buffer readBuff) { } protected void write(NetSocket socket) { - int length = 1 + 4 + address.length() + 1 + 4 * sender.host.length() + + int length = 1 + 4 + address.length() + 1 + 4 * sender.getHost().length() + 4 + (replyAddress == null ? 0 : replyAddress.length()) + getBodyLength(); Buffer totBuff = new Buffer(length); totBuff.appendInt(0); totBuff.appendByte(type()); writeString(totBuff, address); - totBuff.appendInt(sender.port); - writeString(totBuff, sender.host); + totBuff.appendInt(sender.getPort()); + writeString(totBuff, sender.getHost()); if (replyAddress != null) { writeString(totBuff, replyAddress); } else { diff --git a/src/main/java/org/vertx/java/core/eventbus/impl/DefaultEventBus.java b/src/main/java/org/vertx/java/core/eventbus/impl/DefaultEventBus.java index 8576578edd8..5333f119d34 100644 --- a/src/main/java/org/vertx/java/core/eventbus/impl/DefaultEventBus.java +++ b/src/main/java/org/vertx/java/core/eventbus/impl/DefaultEventBus.java @@ -35,6 +35,7 @@ import org.vertx.java.core.net.impl.ServerID; import org.vertx.java.core.parsetools.RecordParser; +import java.beans.ConstructorProperties; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.Map; @@ -43,6 +44,9 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.atomic.AtomicLong; + +import javax.management.NotificationBroadcasterSupport; /** * @@ -52,6 +56,8 @@ public class DefaultEventBus implements EventBus { private static final Logger log = LoggerFactory.getLogger(DefaultEventBus.class); + private final NotificationBroadcasterSupport notificationBroadcasterSupport = new NotificationBroadcasterSupport(); + private static final Buffer PONG = new Buffer(new byte[] { (byte)1 }); private static final long PING_INTERVAL = 20000; private static final long PING_REPLY_INTERVAL = 20000; @@ -64,7 +70,12 @@ public class DefaultEventBus implements EventBus { private final ConcurrentMap> handlers = new ConcurrentHashMap<>(); private final Map replyAddressCache = new ConcurrentHashMap<>(); private final Map handlersByID = new ConcurrentHashMap<>(); + + private final AtomicLong sent = new AtomicLong(0); + + private final AtomicLong received = new AtomicLong(0); + @ConstructorProperties("vertx") public DefaultEventBus(VertxInternal vertx) { // Just some dummy server ID this.vertx = vertx; @@ -73,17 +84,29 @@ public DefaultEventBus(VertxInternal vertx) { this.subs = null; } + @ConstructorProperties({"vertx", "hostname"}) public DefaultEventBus(VertxInternal vertx, String hostname) { this(vertx, DEFAULT_CLUSTER_PORT, hostname); } + @ConstructorProperties({"vertx", "port", "hostname"}) public DefaultEventBus(VertxInternal vertx, int port, String hostname) { this.vertx = vertx; this.serverID = new ServerID(port, hostname); ClusterManager mgr = new HazelcastClusterManager(vertx); - subs = mgr.getSubsMap("subs"); + this.subs = mgr.getSubsMap("subs"); this.server = setServer(); } + + @Override + public long getSent() { + return sent.get(); + } + + @Override + public long getReceived() { + return received.get(); + } public void send(String address, JsonObject message, final Handler> replyHandler) { send(new JsonMessage(address, message), replyHandler); @@ -274,7 +297,7 @@ public void handle(Buffer buff) { parser.setOutput(handler); socket.dataHandler(parser); } - }).listen(serverID.port, serverID.host); + }).listen(serverID.getPort(), serverID.getHost()); } private void sendToSubs(Collection subs, BaseMessage message) { @@ -440,6 +463,7 @@ private void sendRemote(final ServerID serverID, final BaseMessage message) { holder.connect(client, serverID, message.address); } } + sent.incrementAndGet(); holder.writeMessage(message); } @@ -485,6 +509,7 @@ private void receiveMessage(BaseMessage msg) { replyAddressCache.put(msg.replyAddress, msg.sender); } msg.bus = this; + received.incrementAndGet(); final Map map = handlers.get(msg.address); if (map != null) { boolean replyHandler = false; @@ -590,7 +615,7 @@ public void handle(Buffer data) { } void connect(NetClient client, final ServerID serverID, final String address) { - client.connect(serverID.port, serverID.host, new Handler() { + client.connect(serverID.getPort(), serverID.getHost(), new Handler() { public void handle(final NetSocket socket) { connected(socket, address); } diff --git a/src/main/java/org/vertx/java/core/eventbus/impl/hazelcast/HazelcastServerID.java b/src/main/java/org/vertx/java/core/eventbus/impl/hazelcast/HazelcastServerID.java index 2483ee5a9c0..892c0a7a73d 100644 --- a/src/main/java/org/vertx/java/core/eventbus/impl/hazelcast/HazelcastServerID.java +++ b/src/main/java/org/vertx/java/core/eventbus/impl/hazelcast/HazelcastServerID.java @@ -39,8 +39,8 @@ public HazelcastServerID(ServerID serverID) { @Override public void writeData(DataOutput dataOutput) throws IOException { - dataOutput.writeInt(serverID.port); - dataOutput.writeUTF(serverID.host); + dataOutput.writeInt(serverID.getPort()); + dataOutput.writeUTF(serverID.getHost()); } @Override diff --git a/src/main/java/org/vertx/java/core/http/HttpServer.java b/src/main/java/org/vertx/java/core/http/HttpServer.java index f520115f625..e818b19d07f 100644 --- a/src/main/java/org/vertx/java/core/http/HttpServer.java +++ b/src/main/java/org/vertx/java/core/http/HttpServer.java @@ -29,7 +29,7 @@ * * @author Tim Fox */ -public interface HttpServer { +public interface HttpServer extends HttpServerMXBean { /** * Set the request handler for the server to {@code requestHandler}. As HTTP requests are received by the server, diff --git a/src/main/java/org/vertx/java/core/http/HttpServerMXBean.java b/src/main/java/org/vertx/java/core/http/HttpServerMXBean.java new file mode 100644 index 00000000000..3c4882c1ebe --- /dev/null +++ b/src/main/java/org/vertx/java/core/http/HttpServerMXBean.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.core.http; + +/** + * @author pidster + * + */ +public interface HttpServerMXBean { + + int getPort(); + + String getHost(); + + boolean isSSL(); + + Boolean isTCPNoDelay(); + + Integer getSendBufferSize(); + + Integer getReceiveBufferSize(); + + Boolean isTCPKeepAlive(); + + Boolean isReuseAddress(); + + Boolean isSoLinger(); + + Integer getTrafficClass(); + + Integer getAcceptBacklog(); + +} diff --git a/src/main/java/org/vertx/java/core/http/impl/DefaultHttpServer.java b/src/main/java/org/vertx/java/core/http/impl/DefaultHttpServer.java index 3eb965567d4..81bf98863a3 100644 --- a/src/main/java/org/vertx/java/core/http/impl/DefaultHttpServer.java +++ b/src/main/java/org/vertx/java/core/http/impl/DefaultHttpServer.java @@ -59,6 +59,7 @@ import org.vertx.java.core.http.impl.ws.hybi17.HandshakeRFC6455; import org.vertx.java.core.impl.Context; import org.vertx.java.core.impl.VertxInternal; +import org.vertx.java.core.jmx.JMXUtil; import org.vertx.java.core.logging.Logger; import org.vertx.java.core.logging.impl.LoggerFactory; import org.vertx.java.core.net.impl.HandlerHolder; @@ -68,6 +69,8 @@ import org.vertx.java.core.net.impl.VertxWorkerPool; import javax.net.ssl.SSLEngine; + +import java.beans.ConstructorProperties; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.URI; @@ -109,6 +112,7 @@ public class DefaultHttpServer implements HttpServer { private HandlerManager reqHandlerManager = new HandlerManager<>(availableWorkers); private HandlerManager wsHandlerManager = new HandlerManager<>(availableWorkers); + @ConstructorProperties("vertx") public DefaultHttpServer(VertxInternal vertx) { this.vertx = vertx; ctx = vertx.getOrAssignContext(); @@ -123,6 +127,9 @@ public void run() { } public HttpServer requestHandler(Handler requestHandler) { + + String simpleName = requestHandler.getClass().getSimpleName(); + JMXUtil.register(requestHandler, "org.vertx:type=Handler,type=HTTP,name=%s", simpleName); this.requestHandler = requestHandler; return this; } @@ -132,6 +139,8 @@ public Handler requestHandler() { } public HttpServer websocketHandler(Handler wsHandler) { + String simpleName = requestHandler.getClass().getSimpleName(); + JMXUtil.register(requestHandler, "org.vertx:type=Handler,type=WebSocket,name=%s", simpleName); this.wsHandler = wsHandler; return this; } @@ -139,6 +148,18 @@ public HttpServer websocketHandler(Handler wsHandler) { public Handler websocketHandler() { return wsHandler; } + + public ServerID getServerID() { + return id; + } + + public int getPort() { + return id.getPort(); + } + + public String getHost() { + return id.getHost(); + } public HttpServer listen(int port) { return listen(port, "0.0.0.0"); @@ -206,7 +227,7 @@ public ChannelPipeline getPipeline() { } catch (UnknownHostException e) { log.error("Failed to bind", e); } - vertx.sharedHttpServers().put(id, this); + vertx.registerSharedHttpServer(id, this); actualServer = this; } else { // Server already exists with that host/port - we will use that @@ -385,7 +406,7 @@ public String getTrustStorePassword() { private void actualClose(final Context closeContext, final Handler done) { if (id != null) { - vertx.sharedHttpServers().remove(id); + vertx.unregisterSharedHttpServer(id); } for (ServerConnection conn : connectionMap.values()) { diff --git a/src/main/java/org/vertx/java/core/impl/DefaultVertx.java b/src/main/java/org/vertx/java/core/impl/DefaultVertx.java index 11de8e6c47c..ee60bcb6fde 100644 --- a/src/main/java/org/vertx/java/core/impl/DefaultVertx.java +++ b/src/main/java/org/vertx/java/core/impl/DefaultVertx.java @@ -30,6 +30,7 @@ import org.vertx.java.core.http.HttpServer; import org.vertx.java.core.http.impl.DefaultHttpClient; import org.vertx.java.core.http.impl.DefaultHttpServer; +import org.vertx.java.core.jmx.JMXUtil; import org.vertx.java.core.logging.Logger; import org.vertx.java.core.logging.impl.LoggerFactory; import org.vertx.java.core.net.NetClient; @@ -41,6 +42,7 @@ import org.vertx.java.core.sockjs.SockJSServer; import org.vertx.java.core.sockjs.impl.DefaultSockJSServer; +import java.beans.ConstructorProperties; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -82,18 +84,50 @@ public class DefaultVertx extends VertxInternal { public DefaultVertx() { this.eventBus = new DefaultEventBus(this); + registerSelf(this); } + @ConstructorProperties({"hostname"}) public DefaultVertx(String hostname) { this.eventBus = new DefaultEventBus(this, hostname); + registerSelf(this); } + @ConstructorProperties({"port", "hostname"}) public DefaultVertx(int port, String hostname) { this.eventBus = new DefaultEventBus(this, port, hostname); + registerSelf(this); + } + + @Override + public int getBackgroundPoolSize() { + return backgroundPoolSize; + } + + @Override + public int getCorePoolSize() { + return corePoolSize; + } + + private void registerSelf(DefaultVertx vertx) { + JMXUtil.register(vertx, "org.vertx:type=Vertx"); + JMXUtil.register(vertx.eventBus, "org.vertx:type=EventBus"); + } + + public void registerSharedNetServer(ServerID id, DefaultNetServer server) { + sharedNetServers.put(id, server); + String name = String.format("org.vertx:type=NetServer,host=%s,port=%d", id.getHost(), id.getPort()); + JMXUtil.register(server, name); + } + + public void unregisterSharedNetServer(ServerID id) { + sharedNetServers.remove(id); + String name = String.format("org.vertx:type=NetServer,host=%s,port=%d", id.getHost(), id.getPort()); + JMXUtil.unregister(name); } public NetServer createNetServer() { - return new DefaultNetServer(this); + return new DefaultNetServer(this); } public NetClient createNetClient() { @@ -108,8 +142,20 @@ public SharedData sharedData() { return sharedData; } + public void registerSharedHttpServer(ServerID id, DefaultHttpServer server) { + sharedHttpServers.put(id, server); + String name = String.format("org.vertx:type=HttpServer,host=%s,port=%d", id.getHost(), id.getPort()); + JMXUtil.register(server, name); + } + + public void unregisterSharedHttpServer(ServerID id) { + sharedHttpServers.remove(id); + String name = String.format("org.vertx:type=HttpServer,host=%s,port=%d", id.getHost(), id.getPort()); + JMXUtil.unregister(name); + } + public HttpServer createHttpServer() { - return new DefaultHttpServer(this); + return new DefaultHttpServer(this); } public HttpClient createHttpClient() { @@ -117,7 +163,9 @@ public HttpClient createHttpClient() { } public SockJSServer createSockJSServer(HttpServer httpServer) { - return new DefaultSockJSServer(this, httpServer); + SockJSServer server = new DefaultSockJSServer(this, httpServer); + // JMXUtil.register(server, "org.vertx:type=SockJSServer"); + return server; } public EventBus eventBus() { diff --git a/src/main/java/org/vertx/java/core/impl/VertxInternal.java b/src/main/java/org/vertx/java/core/impl/VertxInternal.java index 471466afbad..b126fac5e41 100644 --- a/src/main/java/org/vertx/java/core/impl/VertxInternal.java +++ b/src/main/java/org/vertx/java/core/impl/VertxInternal.java @@ -48,6 +48,14 @@ public abstract class VertxInternal extends Vertx { public abstract Map sharedHttpServers(); + public abstract void registerSharedHttpServer(ServerID id, DefaultHttpServer server); + + public abstract void unregisterSharedHttpServer(ServerID id); + public abstract Map sharedNetServers(); + + public abstract void registerSharedNetServer(ServerID id, DefaultNetServer server); + + public abstract void unregisterSharedNetServer(ServerID id); } diff --git a/src/main/java/org/vertx/java/core/jmx/JMXUtil.java b/src/main/java/org/vertx/java/core/jmx/JMXUtil.java new file mode 100644 index 00000000000..4a88bb5e2bd --- /dev/null +++ b/src/main/java/org/vertx/java/core/jmx/JMXUtil.java @@ -0,0 +1,93 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.core.jmx; + +import java.lang.management.ManagementFactory; + +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MBeanServer; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; + +import org.vertx.java.core.logging.Logger; +import org.vertx.java.core.logging.impl.LoggerFactory; + +/** + * @author pidster + * + */ +public class JMXUtil { + + private static final Logger log = LoggerFactory.getLogger(JMXUtil.class); + + private static MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); + + public static ObjectName newObjectName(String name, Object... args) { + try { + String objName = String.format(name, args); + return new ObjectName(objName); + } catch (MalformedObjectNameException e) { + throw new RuntimeException(e); + } + } + + public static void register(Object mbean, String name, Object... args) { + ObjectName objectName = newObjectName(name, args); + register(mbean, objectName); + } + + public static void register(Object mbean, String name) { + ObjectName objectName = newObjectName(name); + register(mbean, objectName); + } + + public static void register(Object mbean, ObjectName name) { + + try { + mbeanServer.registerMBean(mbean, name); + + } catch (InstanceAlreadyExistsException e) { + log.error(e.getMessage(), e); + + } catch (MBeanRegistrationException e) { + log.error(e.getMessage(), e); + + } catch (NotCompliantMBeanException e) { + log.error(e.getMessage(), e); + } + } + + public static void unregister(String name) { + ObjectName objectName = newObjectName(name); + unregister(objectName); + } + + public static void unregister(ObjectName name) { + + try { + mbeanServer.unregisterMBean(name); + + } catch (InstanceNotFoundException e) { + log.error(e.getMessage(), e); + + } catch (MBeanRegistrationException e) { + log.error(e.getMessage(), e); + } + } +} diff --git a/src/main/java/org/vertx/java/core/net/NetServer.java b/src/main/java/org/vertx/java/core/net/NetServer.java index 53fc55def1c..5bf1cc0a63b 100644 --- a/src/main/java/org/vertx/java/core/net/NetServer.java +++ b/src/main/java/org/vertx/java/core/net/NetServer.java @@ -16,6 +16,8 @@ package org.vertx.java.core.net; +import javax.management.MXBean; + import org.vertx.java.core.Handler; /** @@ -30,7 +32,7 @@ * * @author Tim Fox */ -public interface NetServer { +public interface NetServer extends NetServerMXBean { /** * Supply a connect handler for this server. The server can only have at most one connect handler at any one time. diff --git a/src/main/java/org/vertx/java/core/net/NetServerMXBean.java b/src/main/java/org/vertx/java/core/net/NetServerMXBean.java new file mode 100644 index 00000000000..d8d48c40f06 --- /dev/null +++ b/src/main/java/org/vertx/java/core/net/NetServerMXBean.java @@ -0,0 +1,46 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.core.net; + +/** + * @author pidster + * + */ +public interface NetServerMXBean { + + int getPort(); + + String getHost(); + + boolean isSSL(); + + Boolean isTCPNoDelay(); + + Integer getSendBufferSize(); + + Integer getReceiveBufferSize(); + + Boolean isTCPKeepAlive(); + + Boolean isReuseAddress(); + + Boolean isSoLinger(); + + Integer getTrafficClass(); + + Integer getAcceptBacklog(); + +} diff --git a/src/main/java/org/vertx/java/core/net/impl/DefaultNetServer.java b/src/main/java/org/vertx/java/core/net/impl/DefaultNetServer.java index 470088f1392..10db610dc9d 100644 --- a/src/main/java/org/vertx/java/core/net/impl/DefaultNetServer.java +++ b/src/main/java/org/vertx/java/core/net/impl/DefaultNetServer.java @@ -67,7 +67,7 @@ public class DefaultNetServer implements NetServer { private final VertxInternal vertx; private final Context ctx; private final TCPSSLHelper tcpHelper = new TCPSSLHelper(); - private final Map socketMap = new ConcurrentHashMap(); + private final Map socketMap = new ConcurrentHashMap<>(); private Handler connectHandler; private ChannelGroup serverChannelGroup; private boolean listening; @@ -161,7 +161,7 @@ public ChannelPipeline getPipeline() { } catch (UnknownHostException e) { log.error("Failed to bind", e); } - vertx.sharedNetServers().put(id, this); + vertx.registerSharedNetServer(id, this); actualServer = this; } else { // Server already exists with that host/port - we will use that @@ -207,7 +207,7 @@ public void close(final Handler done) { private void actualClose(final Context closeContext, final Handler done) { if (id != null) { - vertx.sharedNetServers().remove(id); + vertx.unregisterSharedNetServer(id); } for (DefaultNetSocket sock : socketMap.values()) { @@ -240,6 +240,18 @@ public void run() { } }); } + + public ServerID getServerID() { + return id; + } + + public int getPort() { + return id.getPort(); + } + + public String getHost() { + return id.getHost(); + } public Boolean isTCPNoDelay() { return tcpHelper.isTCPNoDelay(); @@ -380,7 +392,7 @@ public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) { NioWorker worker = ch.getWorker(); //Choose a handler - final HandlerHolder handler = handlerManager.chooseHandler(worker); + final HandlerHolder handler = handlerManager.chooseHandler(worker); if (handler == null) { //Ignore @@ -407,7 +419,7 @@ public void operationComplete(ChannelFuture channelFuture) throws Exception { } } - private void connected(final NioSocketChannel ch, final HandlerHolder handler) { + private void connected(final NioSocketChannel ch, final HandlerHolder handler) { handler.context.execute(new Runnable() { public void run() { DefaultNetSocket sock = new DefaultNetSocket(vertx, ch, handler.context); diff --git a/src/main/java/org/vertx/java/core/net/impl/HandlerManager.java b/src/main/java/org/vertx/java/core/net/impl/HandlerManager.java index f5f1a134388..31342571672 100644 --- a/src/main/java/org/vertx/java/core/net/impl/HandlerManager.java +++ b/src/main/java/org/vertx/java/core/net/impl/HandlerManager.java @@ -23,6 +23,7 @@ import org.vertx.java.core.logging.Logger; import org.vertx.java.core.logging.impl.LoggerFactory; +import java.beans.ConstructorProperties; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -38,6 +39,7 @@ public class HandlerManager { private final VertxWorkerPool availableWorkers; private Map> handlerMap = new ConcurrentHashMap<>(); + @ConstructorProperties({"availableWorkers"}) public HandlerManager(VertxWorkerPool availableWorkers) { this.availableWorkers = availableWorkers; } diff --git a/src/main/java/org/vertx/java/core/net/impl/ServerID.java b/src/main/java/org/vertx/java/core/net/impl/ServerID.java index 4b997887e03..394f0027767 100644 --- a/src/main/java/org/vertx/java/core/net/impl/ServerID.java +++ b/src/main/java/org/vertx/java/core/net/impl/ServerID.java @@ -16,6 +16,7 @@ package org.vertx.java.core.net.impl; +import java.beans.ConstructorProperties; import java.io.Serializable; /** @@ -23,15 +24,24 @@ */ public class ServerID implements Serializable { - public int port; - public String host; + private static final long serialVersionUID = 1L; + private final int port; + + private final String host; + + @ConstructorProperties({"port", "host"}) public ServerID(int port, String host) { this.port = port; this.host = host; } - public ServerID() { + public int getPort() { + return port; + } + + public String getHost() { + return host; } @Override diff --git a/src/main/java/org/vertx/java/deploy/Container.java b/src/main/java/org/vertx/java/deploy/Container.java index 94dc3b8733c..55c6935dd42 100644 --- a/src/main/java/org/vertx/java/deploy/Container.java +++ b/src/main/java/org/vertx/java/deploy/Container.java @@ -21,6 +21,7 @@ import org.vertx.java.core.logging.Logger; import org.vertx.java.deploy.impl.VerticleManager; +import java.beans.ConstructorProperties; import java.io.File; import java.net.URL; @@ -34,12 +35,13 @@ * * @author Tim Fox */ -public class Container { +public class Container implements ContainerMXBean { private final VerticleManager mgr; - public Container(final VerticleManager vertx) { - this.mgr = vertx; + @ConstructorProperties({"mgr"}) + public Container(final VerticleManager mgr) { + this.mgr = mgr; } /** diff --git a/src/main/java/org/vertx/java/deploy/ContainerMXBean.java b/src/main/java/org/vertx/java/deploy/ContainerMXBean.java new file mode 100644 index 00000000000..37907ff6877 --- /dev/null +++ b/src/main/java/org/vertx/java/deploy/ContainerMXBean.java @@ -0,0 +1,33 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.deploy; + +/** + * @author pidster + * + */ +public interface ContainerMXBean { + + String deployWorkerVerticle(String main); + + String deployWorkerVerticle(String main, int instances); + + String deployVerticle(String main); + + String deployVerticle(String main, int instances); + + void undeployVerticle(String deploymentID); +} diff --git a/src/main/java/org/vertx/java/deploy/Verticle.java b/src/main/java/org/vertx/java/deploy/Verticle.java index 0d3f3cefa9a..91f4885cfb0 100644 --- a/src/main/java/org/vertx/java/deploy/Verticle.java +++ b/src/main/java/org/vertx/java/deploy/Verticle.java @@ -23,7 +23,7 @@ * * @author Tim Fox */ -public abstract class Verticle { +public abstract class Verticle implements VerticleMXBean { /** * A reference to the vert.x runtime diff --git a/src/main/java/org/vertx/java/deploy/VerticleMXBean.java b/src/main/java/org/vertx/java/deploy/VerticleMXBean.java new file mode 100644 index 00000000000..5578bbf6b72 --- /dev/null +++ b/src/main/java/org/vertx/java/deploy/VerticleMXBean.java @@ -0,0 +1,34 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.deploy; + +import org.vertx.java.core.VertxMXBean; + +/** + * @author pidster + * + */ +public interface VerticleMXBean { + + void start() throws Exception; + + void stop() throws Exception; + + VertxMXBean getVertx(); + + ContainerMXBean getContainer(); + +} diff --git a/src/main/java/org/vertx/java/deploy/impl/VerticleManager.java b/src/main/java/org/vertx/java/deploy/impl/VerticleManager.java index 4d505a150c8..82bbcd049c5 100644 --- a/src/main/java/org/vertx/java/deploy/impl/VerticleManager.java +++ b/src/main/java/org/vertx/java/deploy/impl/VerticleManager.java @@ -21,6 +21,7 @@ import org.vertx.java.core.impl.Context; import org.vertx.java.core.impl.DeploymentHandle; import org.vertx.java.core.impl.VertxInternal; +import org.vertx.java.core.jmx.JMXUtil; import org.vertx.java.core.json.DecodeException; import org.vertx.java.core.json.JsonObject; import org.vertx.java.core.logging.Logger; @@ -29,6 +30,7 @@ import org.vertx.java.deploy.Verticle; import org.vertx.java.deploy.VerticleFactory; +import java.beans.ConstructorProperties; import java.io.File; import java.io.FileNotFoundException; import java.net.MalformedURLException; @@ -47,7 +49,7 @@ /** * @author Tim Fox */ -public class VerticleManager { +public class VerticleManager implements VerticleManagerMXBean { private static final Logger log = LoggerFactory.getLogger(VerticleManager.class); @@ -63,6 +65,7 @@ public class VerticleManager { private Map factories; + @ConstructorProperties("vertx") public VerticleManager(VertxInternal vertx) { this.vertx = vertx; VertxLocator.vertx = vertx; @@ -178,6 +181,10 @@ public synchronized void undeploy(String name, final Handler doneHandler) } doUndeploy(name, doneHandler); } + + public Map getInstances() { + return listInstances(); + } public synchronized Map listInstances() { Map map = new HashMap<>(); @@ -286,6 +293,9 @@ public void run() { setPathAdjustment(modDir); } verticle.start(); + JMXUtil.register(verticle.getContainer(), "org.vertx:type=Container,deployment=%s", deploymentName); + JMXUtil.register(verticle, "org.vertx:type=Verticle,deployment=%s", deploymentName); + } catch (Throwable t) { vertx.reportException(t); doUndeploy(deploymentName, doneHandler); @@ -403,7 +413,7 @@ private void doUndeploy(String name, final Handler doneHandler) { } } - private void doUndeploy(String name, final UndeployCount count) { + private void doUndeploy(final String name, final UndeployCount count) { final Deployment deployment = deployments.remove(name); @@ -420,6 +430,11 @@ private void doUndeploy(String name, final UndeployCount count) { public void run() { try { holder.verticle.stop(); + String verticleName = String.format("org.vertx:type=Verticle,deployment=%s", deployment.name); + JMXUtil.unregister(verticleName); + String containerName = String.format("org.vertx:type=Container,deployment=%s", deployment.name); + JMXUtil.unregister(containerName); + } catch (Throwable t) { vertx.reportException(t); } diff --git a/src/main/java/org/vertx/java/deploy/impl/VerticleManagerMXBean.java b/src/main/java/org/vertx/java/deploy/impl/VerticleManagerMXBean.java new file mode 100644 index 00000000000..32314cab3f2 --- /dev/null +++ b/src/main/java/org/vertx/java/deploy/impl/VerticleManagerMXBean.java @@ -0,0 +1,32 @@ +/* + * Copyright 2012 the original author or authors. + * + * 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.vertx.java.deploy.impl; + +import java.util.Map; + +/** + * @author pidster + * + */ +public interface VerticleManagerMXBean { + + Map getInstances(); + + String getDeploymentName(); + + // TODO Set getLanguageFactories(); + +} diff --git a/src/main/java/org/vertx/java/deploy/impl/cli/VertxMgr.java b/src/main/java/org/vertx/java/deploy/impl/cli/VertxMgr.java index 1eb12189d58..b93b9b04ca8 100644 --- a/src/main/java/org/vertx/java/deploy/impl/cli/VertxMgr.java +++ b/src/main/java/org/vertx/java/deploy/impl/cli/VertxMgr.java @@ -21,6 +21,7 @@ import org.vertx.java.core.buffer.Buffer; import org.vertx.java.core.impl.DefaultVertx; import org.vertx.java.core.impl.VertxInternal; +import org.vertx.java.core.jmx.JMXUtil; import org.vertx.java.core.json.DecodeException; import org.vertx.java.core.json.JsonObject; import org.vertx.java.core.logging.Logger; @@ -262,6 +263,7 @@ private boolean startCluster(Args args) { vertx = new DefaultVertx(clusterPort, clusterHost); } mgr = new VerticleManager(vertx); + JMXUtil.register(mgr, "org.vertx:type=VerticleManager"); if (clustered) { System.out.println("Started"); }