You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/09/19 18:27:27 UTC
svn commit: r1387669 - in
/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb:
assembler/classic/Assembler.java core/stateless/StatelessContainer.java
monitoring/remote/ monitoring/remote/RemoteResourceMonitor.java
Author: rmannibucau
Date: Wed Sep 19 16:27:26 2012
New Revision: 1387669
URL: http://svn.apache.org/viewvc?rev=1387669&view=rev
Log:
TOMEE-421 ping of datasources from JMX
Added:
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/RemoteResourceMonitor.java
Modified:
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1387669&r1=1387668&r2=1387669&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java Wed Sep 19 16:27:26 2012
@@ -82,6 +82,7 @@ import org.apache.openejb.loader.SystemI
import org.apache.openejb.monitoring.DynamicMBeanWrapper;
import org.apache.openejb.monitoring.LocalMBeanServer;
import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.apache.openejb.monitoring.remote.RemoteResourceMonitor;
import org.apache.openejb.observer.Observes;
import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.persistence.PersistenceClassLoaderHandler;
@@ -150,6 +151,8 @@ import java.lang.instrument.Instrumentat
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
+import java.sql.Connection;
+import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -194,7 +197,8 @@ public class Assembler extends Assembler
protected OpenEjbConfigurationFactory configFactory;
private final Map<String, AppInfo> deployedApplications = new HashMap<String, AppInfo>();
private final Set<String> moduleIds = new HashSet<String>();
- private final Set<ObjectName> containersObjectNames = new HashSet<ObjectName>();
+ private final Set<ObjectName> containerObjectNames = new HashSet<ObjectName>();
+ private final RemoteResourceMonitor remoteResourceMonitor = new RemoteResourceMonitor();
@Override
@@ -1092,7 +1096,7 @@ public class Assembler extends Assembler
}
}
- final Iterator<ObjectName> it = containersObjectNames.iterator();
+ final Iterator<ObjectName> it = containerObjectNames.iterator();
final MBeanServer server = LocalMBeanServer.get();
while (it.hasNext()) {
try {
@@ -1102,6 +1106,11 @@ public class Assembler extends Assembler
}
it.remove();
}
+ try {
+ remoteResourceMonitor.unregister();
+ } catch (Exception ignored) {
+ // no-op
+ }
NamingEnumeration<Binding> namingEnumeration = null;
try {
@@ -1514,7 +1523,7 @@ public class Assembler extends Assembler
final ObjectName objectName = ObjectNameBuilder.uniqueName("containers", serviceInfo.id, service);
try {
LocalMBeanServer.get().registerMBean(new DynamicMBeanWrapper(new JMXContainer(serviceInfo, (Container) service)), objectName);
- containersObjectNames.add(objectName);
+ containerObjectNames.add(objectName);
} catch (Exception e) {
// no-op
} catch (NoClassDefFoundError ncdfe) { // OSGi
@@ -1739,17 +1748,32 @@ public class Assembler extends Assembler
// service becomes a ConnectorReference which merges connection manager and mcf
service = new ConnectorReference(connectionManager, managedConnectionFactory);
} else if (service instanceof DataSource) {
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- if (classLoader == null) {
- classLoader = getClass().getClassLoader();
- }
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ if (classLoader == null) {
+ classLoader = getClass().getClassLoader();
+ }
- final ImportSql importer = new ImportSql(classLoader, serviceInfo.id, (DataSource) service);
- if (importer.hasSomethingToImport()) {
- importer.doImport();
- }
+ final ImportSql importer = new ImportSql(classLoader, serviceInfo.id, (DataSource) service);
+ if (importer.hasSomethingToImport()) {
+ importer.doImport();
+ }
logUnusedProperties(DataSourceFactory.forgetRecipe(service, serviceRecipe), serviceInfo);
+
+ final Properties prop = serviceInfo.properties;
+ String url = prop.getProperty("JdbcUrl", prop.getProperty("url"));
+ if (url == null) {
+ url = prop.getProperty("jdbcUrl");
+ }
+ if (url == null) {
+ logger.info("can't find url for " + serviceInfo.id + " will not monitor it");
+ } else {
+ final String host = extractHost(url);
+ if (host != null) {
+ remoteResourceMonitor.addHost(host);
+ remoteResourceMonitor.registerIfNot();
+ }
+ }
} else {
logUnusedProperties(serviceRecipe, serviceInfo);
}
@@ -1775,6 +1799,27 @@ public class Assembler extends Assembler
logger.getChildLogger("service").debug("createService.success", serviceInfo.service, serviceInfo.id, serviceInfo.className);
}
+ private static String extractHost(final String url) { // can be enhanced
+ if (url == null || !url.contains("://")) {
+ return null;
+ }
+
+ final int idx = url.indexOf("://");
+ final String subUrl = url.substring(idx + 3);
+ final int port = subUrl.indexOf(':');
+ final int slash = subUrl.indexOf('/');
+
+ int end = port;
+ if (end < 0 || (slash > 0 && slash < end)) {
+ end = slash;
+ }
+ if (end > 0) {
+ return subUrl.substring(0, end);
+ }
+
+ return subUrl;
+ }
+
private int getIntProperty(Properties properties, String propertyName, int defaultValue) {
String propertyValue = getStringProperty(properties, propertyName, Integer.toString(defaultValue));
if (propertyValue == null) {
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java?rev=1387669&r1=1387668&r2=1387669&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/core/stateless/StatelessContainer.java Wed Sep 19 16:27:26 2012
@@ -32,7 +32,6 @@ import javax.ejb.EJBLocalHome;
import javax.ejb.EJBLocalObject;
import javax.ejb.EJBObject;
import javax.interceptor.AroundInvoke;
-import javax.management.ObjectName;
import org.apache.openejb.ApplicationException;
import org.apache.openejb.BeanContext;
Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/RemoteResourceMonitor.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/RemoteResourceMonitor.java?rev=1387669&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/RemoteResourceMonitor.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/monitoring/remote/RemoteResourceMonitor.java Wed Sep 19 16:27:26 2012
@@ -0,0 +1,166 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.openejb.monitoring.remote;
+
+import org.apache.openejb.OpenEJBRuntimeException;
+import org.apache.openejb.monitoring.LocalMBeanServer;
+import org.apache.openejb.monitoring.ObjectNameBuilder;
+import org.fusesource.mqtt.codec.PINGREQ;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.TimeUnit;
+
+public class RemoteResourceMonitor implements DynamicMBean {
+ private static final String PING = "ping";
+ private static final AttributeList ATTRIBUTE_LIST = new AttributeList();
+ private static final MBeanAttributeInfo[] EMPTY_ATTRIBUTES = new MBeanAttributeInfo[0];
+ private static final MBeanNotificationInfo[] EMPTY_NOTIFICATIONS = new MBeanNotificationInfo[0];
+ private static final MBeanParameterInfo[] EMPTY_PARAMETERS = new MBeanParameterInfo[0];
+ private static final MBeanOperationInfo PING_INFO = new MBeanOperationInfo("ping", "ping the parameter host", new MBeanParameterInfo[] {
+ new MBeanParameterInfo("host", String.class.getName(), "the host to ping")
+ }, String.class.getName(), MBeanOperationInfo.INFO);
+
+ private final Collection<String> hosts = new CopyOnWriteArraySet<String>();
+ private ObjectName objectName = null;
+ private MBeanInfo info = null;
+
+ public synchronized void addHost(final String host) {
+ hosts.add(host);
+ buildMBeanInfo();
+ }
+
+ public synchronized void removeHost(final String host) {
+ hosts.remove(host);
+ buildMBeanInfo();
+ }
+
+ public void registerIfNot() { // do it lazily
+ if (objectName != null) {
+ return;
+ }
+
+ final ObjectNameBuilder jmxName = new ObjectNameBuilder("openejb.management");
+ jmxName.set("ObjectType", "hosts");
+ objectName = jmxName.build();
+
+ try {
+ LocalMBeanServer.get().registerMBean(this, objectName);
+ } catch (Exception e) {
+ throw new OpenEJBRuntimeException(e);
+ }
+ }
+
+ public void unregister() {
+ try {
+ LocalMBeanServer.get().unregisterMBean(objectName);
+ } catch (Exception e) {
+ throw new OpenEJBRuntimeException(e);
+ }
+ }
+
+ @Override
+ public Object invoke(final String actionName, final Object[] params, final String[] signature) throws MBeanException, ReflectionException {
+ if (hosts.contains(actionName)) {
+ return ping(actionName);
+ } else if (PING.equals(actionName) && params != null && params.length == 1) {
+ return ping((String) params[0]);
+ }
+ throw new MBeanException(new IllegalArgumentException(), actionName + " doesn't exist");
+ }
+
+ @Override
+ public MBeanInfo getMBeanInfo() {
+ if (info == null) {
+ buildMBeanInfo();
+ }
+ return info;
+ }
+
+ @Override
+ public Object getAttribute(final String attribute) throws AttributeNotFoundException, MBeanException, ReflectionException {
+ throw new AttributeNotFoundException();
+ }
+
+ @Override
+ public void setAttribute(final Attribute attribute) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
+ throw new AttributeNotFoundException();
+ }
+
+ @Override
+ public AttributeList getAttributes(String[] attributes) {
+ return ATTRIBUTE_LIST;
+ }
+
+ @Override
+ public AttributeList setAttributes(AttributeList attributes) {
+ return ATTRIBUTE_LIST;
+ }
+
+ private void buildMBeanInfo() {
+ final List<MBeanOperationInfo> operationInfos = new ArrayList<MBeanOperationInfo>();
+ for (String host: hosts) {
+ operationInfos.add(new MBeanOperationInfo(host, "ping host " + host, EMPTY_PARAMETERS, String.class.getName(), MBeanOperationInfo.INFO));
+ }
+ operationInfos.add(PING_INFO);
+ info = new MBeanInfo(RemoteResourceMonitor.class.getName(),
+ "Monitor remote resources",
+ EMPTY_ATTRIBUTES,
+ null,
+ operationInfos.toArray(new MBeanOperationInfo[operationInfos.size()]),
+ EMPTY_NOTIFICATIONS);
+ }
+
+ private static String ping(final String host) {
+ try {
+ final InetAddress address = InetAddress.getByName(host);
+ final long start = System.nanoTime();
+ boolean ok = address.isReachable(30000);
+ final long end = System.nanoTime();
+ if (!ok) {
+ return "Can't ping host, timeout (30s)";
+ }
+ return Long.toString(TimeUnit.NANOSECONDS.toMillis(end - start));
+ } catch (UnknownHostException e) {
+ return "Can't find host: " + e.getMessage();
+ } catch (IOException e) {
+ return "Can't ping host: " + e.getMessage();
+ }
+ }
+}