You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by sf...@apache.org on 2006/07/20 11:35:21 UTC
svn commit: r423854 [1/2] - in
/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/felix/ src/main/java/org/apache/felix/mosgi/
src/main/...
Author: sfrenot
Date: Thu Jul 20 02:35:19 2006
New Revision: 423854
URL: http://svn.apache.org/viewvc?rev=423854&view=rev
Log: (empty)
Added:
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/ (with props)
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/pom.xml
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/RmiConnectorActivator.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/AbstractHeartBeat.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ClientProxy.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionNotificationEmitter.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionResolver.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/DefaultRemoteNotificationServerHandler.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/HeartBeat.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteConstants.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteUtils.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/NotificationTuple.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderFactory.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderHelper.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/RemoteNotificationClientHandler.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/RemoteNotificationServerHandler.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/provider/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/provider/RMIClientProvider.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/provider/RMIServerProvider.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/provider/rmi/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/provider/rmi/ServerProvider.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/resolver/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/resolver/rmi/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/resolver/rmi/RMIResolver.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/ClientExceptionCatcher.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/ClientInvoker.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/ClientUnmarshaller.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIConnectionInvoker.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIConnectionProxy.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIConnectionSubjectInvoker.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIHeartBeat.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIMarshaller.java
incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/rmi/RMIRemoteNotificationServerHandler.java
Propchange: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Thu Jul 20 02:35:19 2006
@@ -0,0 +1,17 @@
+classes
+target
+*.log
+*.ipr
+*.iws
+*.iml
+lib
+bundle
+dist
+.project
+.classpath
+bin
+build
+.settings
+.wtpmodules
+.deployables
+
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/pom.xml
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/pom.xml?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/pom.xml (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/pom.xml Thu Jul 20 02:35:19 2006
@@ -0,0 +1,75 @@
+<project>
+ <parent>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>felix</artifactId>
+ <version>0.8.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+ <packaging>osgi-bundle</packaging>
+ <name>MOSGi JMX rmiconnector</name>
+ <artifactId>org.apache.felix.mosgi.jmx.rmiconnector</artifactId>
+ <dependencies>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.mosgi.jmx.agent</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.mosgi.jmx.registry</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>${pom.groupId}</groupId>
+ <artifactId>org.apache.felix.framework</artifactId>
+ <version>${pom.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix.plugins</groupId>
+ <artifactId>maven-osgi-plugin</artifactId>
+ <version>${pom.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <osgiManifest>
+ <bundleName>MOSGi JMX-MX4J RMI Connector</bundleName>
+ <bundleDescription>MOSGi JMX-MX4J RMI Connector</bundleDescription>
+ <bundleActivator>auto-detect</bundleActivator>
+ <bundleDocUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/</bundleDocUrl>
+ <bundleUrl>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}.jar</bundleUrl>
+ <bundleSource>http://oscar-osgi.sf.net/obr2/${pom.artifactId}/${pom.artifactId}-${pom.version}-src.jar</bundleSource>
+ <bundleSymbolicName>${pom.artifactId}</bundleSymbolicName>
+ <exportPackage>
+ org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.provider.rmi;specification-version="1.0.0"
+ </exportPackage>
+ <importPackage>
+ org.osgi.service.log;specification-version="1.0.0",
+ org.osgi.framework;specification-version="1.0.0",
+ org.apache.felix.mosgi.jmx.registry.mx4j.tools.naming;specification-version="1.0.0",
+ org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.provider.rmi;specification-version="1.0.0",
+ javax.management;specification-version="1.0.0",
+ javax.management.remote;specification-version="1.0.0"
+ </importPackage>
+ </osgiManifest>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/RmiConnectorActivator.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/RmiConnectorActivator.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/RmiConnectorActivator.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/RmiConnectorActivator.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceEvent;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.framework.cache.BundleCache;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.felix.mosgi.jmx.registry.mx4j.tools.naming.NamingServiceIfc;
+
+import java.net.InetAddress;
+
+public class RmiConnectorActivator implements BundleActivator, ServiceListener{
+ public static BundleContext bc;
+
+ private ObjectName connectorServerName=new ObjectName("RmiConnector:name=RMIConnector");
+
+ private JMXConnectorServer connectorServer;
+ private MBeanServer mbs;
+ private NamingServiceIfc nsi;
+ private ServiceReference mBeanServerSR, namingServiceIfcSR;
+
+ private String version=null;
+
+ public RmiConnectorActivator() throws javax.management.MalformedObjectNameException {}
+
+ ////////////////////////////////////////////////////
+ // BundleActivator //
+ ////////////////////////////////////////////////////
+ public void start(BundleContext bc) throws Exception{
+ this.version=(String)bc.getBundle().getHeaders().get(Constants.BUNDLE_VERSION);
+ RmiConnectorActivator.bc=bc;
+ this.mBeanServerSR=bc.getServiceReference(MBeanServer.class.getName());
+ this.namingServiceIfcSR=bc.getServiceReference(NamingServiceIfc.class.getName());
+ RmiConnectorActivator. bc.addServiceListener(this, "(|(objectClass="+NamingServiceIfc.class.getName()+")"+"(objectClass="+MBeanServer.class.getName()+"))");
+ if (this.mBeanServerSR!=null && this.namingServiceIfcSR!=null){
+ this.startRmiConnector();
+ } else {
+ if (this.mBeanServerSR == null){
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"No JMX Agent found",null);
+ }else if (this.namingServiceIfcSR==null){
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"No RMI Registry found", null);
+ }
+ }
+ }
+
+ public void stop(BundleContext bc) throws Exception {
+ this.stopRmiConnector();
+ RmiConnectorActivator.bc=null;
+ }
+
+ //////////////////////////////////////////////////////
+ // ServiceListener //
+ //////////////////////////////////////////////////////
+ public void serviceChanged(ServiceEvent serviceevent) {
+ ServiceReference servicereference= serviceevent.getServiceReference();
+ String [] ast=(String[])(servicereference.getProperty("objectClass"));
+ String as=ast[0];
+ switch (serviceevent.getType()) {
+ case ServiceEvent.REGISTERED :
+ if (as.equals(NamingServiceIfc.class.getName())){
+ this.namingServiceIfcSR=servicereference;
+ }else if (as.equals(MBeanServer.class.getName())){
+ this.mBeanServerSR=servicereference;
+ }
+ if (this.namingServiceIfcSR!=null && this.mBeanServerSR!=null){
+ try{
+ this.startRmiConnector();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ }
+ break;
+ case ServiceEvent.UNREGISTERING :
+ try{
+ this.stopRmiConnector();
+ }catch (Exception e){
+ e.printStackTrace();
+ }
+ break;
+ }
+ }
+
+ public static void log(int prio, String message, Throwable t){
+ if (RmiConnectorActivator.bc!=null){
+ ServiceReference logSR=RmiConnectorActivator.bc.getServiceReference(LogService.class.getName());
+ if (logSR!=null){
+ ((LogService)RmiConnectorActivator.bc.getService(logSR)).log(prio, message, t);
+ }else{
+ System.out.println("No Log Service");
+ }
+ }else{
+ System.out.println(RmiConnectorActivator.class.getName()+": No bundleContext");
+ }
+ }
+
+ private void startRmiConnector() throws Exception{
+ String profile=bc.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ if (profile==null){
+ profile=System.getProperty(BundleCache.CACHE_PROFILE_PROP);
+ }
+ String rmiPort=bc.getProperty("insa.jmxconsole.rmiport."+profile);
+ if (rmiPort==null){
+ rmiPort="1099";
+ }
+ String url="service:jmx:rmi:///jndi/rmi://"+ InetAddress.getLocalHost().getHostAddress()+":"+rmiPort+"/"+profile;
+ RmiConnectorActivator.log(LogService.LOG_INFO, "insa.jmx.rmiconnector.url ==> "+url, null);
+
+ RmiConnectorActivator.log(LogService.LOG_INFO, "Starting JMX Rmi Connector "+version,null);
+ this.mbs=(MBeanServer)bc.getService(this.mBeanServerSR);
+ this.nsi=(NamingServiceIfc)bc.getService(this.namingServiceIfcSR);
+ JMXServiceURL address=new JMXServiceURL(url);
+/*
+ Map environment = new HashMap();
+ environment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory");
+ environment.put(Context.PROVIDER_URL, "rmi://localhost:"+rmiPort);
+ environment.put(JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER,this.getClass().getClassLoader());
+ */
+
+/* Loggin
+Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
+java.util.logging.ConsoleHandler ch=new java.util.logging.ConsoleHandler();
+ch.setLevel(java.util.logging.Level.FINEST);
+java.util.logging.Logger.getLogger("javax.management.remote.misc").setLevel(java.util.logging.Level.FINEST);
+java.util.logging.Logger.getLogger("javax.management.remote.rmi").setLevel(java.util.logging.Level.FINEST);
+java.util.logging.Logger.getLogger("javax.management.remote.rmi").addHandler(ch);
+java.util.logging.Logger.getLogger("javax.management.remote.misc").addHandler(ch);
+*/
+
+ /*
+ java.util.Map env = new java.util.HashMap();
+ env.put(JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER, this.getClass().getClassLoader());
+ env.put("jmx.remote.protocol.provider.pkgs", "mx4j.remote.provider");
+ */
+
+ this.connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(address, null, this.mbs);
+
+ RmiConnectorActivator.log(LogService.LOG_DEBUG, "===> "+this.connectorServer, null);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG, "======> "+this.connectorServer.getMBeanServer(), null);
+
+// this.mbs.registerMBean(this.connectorServer, this.connectorServerName);
+// this.connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(address, null, java.lang.management.ManagementFactory.getPlatformMBeanServer());
+ this.connectorServer.start();
+
+ RmiConnectorActivator.log(LogService.LOG_INFO, "JMX Rmi Connector started "+version,null);
+ }
+
+ private void stopRmiConnector() throws Exception {
+ RmiConnectorActivator.log(LogService.LOG_INFO, "Stopping JMX Rmi connector "+version,null);
+ if (this.connectorServer!=null){
+ this.connectorServer.stop();
+ this.connectorServer=null;
+ }
+
+ if (this.mbs!=null){
+//SFR this.mbs.unregisterMBean(this.connectorServerName);
+ this.mbs=null;
+ }
+
+ this.nsi=null;
+
+ if (this.mBeanServerSR!=null){
+ RmiConnectorActivator.bc.ungetService(this.mBeanServerSR);
+ this.mBeanServerSR=null;
+ }
+ if (this.namingServiceIfcSR!=null){
+ RmiConnectorActivator.bc.ungetService(this.namingServiceIfcSR);
+ this.namingServiceIfcSR=null;
+ }
+ this.connectorServerName=null;
+ RmiConnectorActivator.log(LogService.LOG_INFO, "Rmi Connector stopped "+version,null);
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/AbstractHeartBeat.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/AbstractHeartBeat.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/AbstractHeartBeat.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/AbstractHeartBeat.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public abstract class AbstractHeartBeat implements HeartBeat, Runnable
+{
+ private final ConnectionNotificationEmitter emitter;
+ private long pulsePeriod;
+ private int maxRetries;
+ private Thread thread;
+ private volatile boolean stopped;
+
+ protected AbstractHeartBeat(ConnectionNotificationEmitter emitter, Map environment)
+ {
+ this.emitter = emitter;
+ if (environment != null)
+ {
+ try
+ {
+ pulsePeriod = ((Long)environment.get(MX4JRemoteConstants.CONNECTION_HEARTBEAT_PERIOD)).longValue();
+ }
+ catch (Exception ignored)
+ {
+ }
+ try
+ {
+ maxRetries = ((Integer)environment.get(MX4JRemoteConstants.CONNECTION_HEARTBEAT_RETRIES)).intValue();
+ }
+ catch (Exception ignored)
+ {
+ }
+ }
+ if (pulsePeriod <= 0) pulsePeriod = 5000;
+ if (maxRetries <= 0) maxRetries = 3;
+ }
+
+ protected abstract void pulse() throws IOException;
+
+ public void start() throws IOException
+ {
+ thread = new Thread(this, "Connection HeartBeat");
+ thread.setDaemon(true);
+ thread.start();
+ }
+
+ public void stop() throws IOException
+ {
+ if (stopped) return;
+ stopped = true;
+ thread.interrupt();
+ }
+
+ public void run()
+ {
+ int retries = 0;
+ while (!stopped && !thread.isInterrupted())
+ {
+ try
+ {
+ Thread.sleep(pulsePeriod);
+
+ try
+ {
+ pulse();
+ retries = 0;
+ }
+ catch (IOException x)
+ {
+ if (retries++ == maxRetries)
+ {
+ // The connection has died
+ sendConnectionNotificationFailed();
+ // And go on
+ }
+ }
+ }
+ catch (InterruptedException x)
+ {
+ Thread.currentThread().interrupt();
+ return;
+ }
+ }
+ }
+
+ protected void sendConnectionNotificationFailed()
+ {
+ emitter.sendConnectionNotificationFailed();
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ClientProxy.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ClientProxy.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ClientProxy.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ClientProxy.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.management.MBeanServerConnection;
+
+/**
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class ClientProxy implements InvocationHandler
+{
+ private final MBeanServerConnection target;
+
+ protected ClientProxy(MBeanServerConnection target)
+ {
+ this.target = target;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
+ {
+ try
+ {
+ return method.invoke(target, args);
+ }
+ catch (InvocationTargetException x)
+ {
+ throw x.getTargetException();
+ }
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionNotificationEmitter.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionNotificationEmitter.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionNotificationEmitter.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionNotificationEmitter.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.IOException;
+
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.rmi.RMIConnector;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class ConnectionNotificationEmitter extends NotificationBroadcasterSupport
+{
+ private static long sequenceNumber;
+
+ private JMXConnector connector;
+
+ public ConnectionNotificationEmitter(JMXConnector connector)
+ {
+ this.connector = connector;
+ }
+
+ private long getNextNotificationNumber()
+ {
+ synchronized (RMIConnector.class)
+ {
+ return sequenceNumber++;
+ }
+ }
+
+ private String getConnectionId()
+ {
+ try
+ {
+ return connector.getConnectionId();
+ }
+ catch (IOException x)
+ {
+ return null;
+ }
+ }
+
+ public void sendConnectionNotificationOpened()
+ {
+ JMXConnectionNotification notification = new JMXConnectionNotification(JMXConnectionNotification.OPENED, connector, getConnectionId(), getNextNotificationNumber(), "Connection opened", null);
+ sendNotification(notification);
+ }
+
+ public void sendConnectionNotificationClosed()
+ {
+ JMXConnectionNotification notification = new JMXConnectionNotification(JMXConnectionNotification.CLOSED, connector, getConnectionId(), getNextNotificationNumber(), "Connection closed", null);
+ sendNotification(notification);
+ }
+
+ public void sendConnectionNotificationFailed()
+ {
+ JMXConnectionNotification notification = new JMXConnectionNotification(JMXConnectionNotification.FAILED, connector, getConnectionId(), getNextNotificationNumber(), "Connection failed", null);
+ sendNotification(notification);
+ }
+
+ public void sendConnectionNotificationLost(long howMany)
+ {
+ JMXConnectionNotification notification = new JMXConnectionNotification(JMXConnectionNotification.NOTIFS_LOST, connector, getConnectionId(), getNextNotificationNumber(), "Some notification (" + howMany + ") was lost", null);
+ sendNotification(notification);
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionResolver.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionResolver.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionResolver.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ConnectionResolver.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.management.remote.JMXServiceURL;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.MX4JRemoteConstants;
+import org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.ProviderHelper;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.RmiConnectorActivator;
+
+/**
+ * ConnectionResolver handles the details of creating connections for different protocols.
+ * Subclasses for the specific protocol are found using a mechanism very similar to the
+ * one specified by {@link javax.management.remote.JMXConnectorFactory}. Here a subclass
+ * has a fully qualified name specified like this:
+ * <package>.resolver.<protocol>.<PROTOCOL>Resolver, for example
+ * {@link mx4j.remote.resolver.rmi.RMIResolver}
+ * This class is used from both the client and the server.
+ * The former uses it to lookup stubs or connections to the server side; the latter uses it
+ * to create server instances and make them availale to clients, for example via JNDI.
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public abstract class ConnectionResolver extends ProviderHelper
+{
+ /**
+ * Returns a subclass of ConnectionResolver for the specified protocol.
+ */
+ public static ConnectionResolver getInstance(String proto) {
+ String protocol = normalizeProtocol(proto);
+ String resolverPackages = findResolverPackageList();
+//sfr return loadResolver(resolverPackages, protocol, Thread.currentThread().getContextClassLoader());
+ return loadResolver(resolverPackages, protocol, ConnectionResolver.class.getClassLoader());
+ }
+
+ private static String findResolverPackageList() {
+ String packages = findSystemPackageList(MX4JRemoteConstants.PROTOCOL_RESOLVER_PACKAGES);
+ if (packages == null)
+ packages = MX4JRemoteConstants.RESOLVER_PACKAGES;
+ else
+ packages += MX4JRemoteConstants.RESOLVER_PACKAGES_SEPARATOR + MX4JRemoteConstants.RESOLVER_PACKAGES;
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Resolver packages list is: " + packages, null);
+ return packages;
+ }
+
+ private static ConnectionResolver loadResolver(String packages, String protocol, ClassLoader loader) {
+ StringTokenizer tokenizer = new StringTokenizer(packages, MX4JRemoteConstants.RESOLVER_PACKAGES_SEPARATOR);
+ while (tokenizer.hasMoreTokens()) {
+ String pkg = tokenizer.nextToken().trim();
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Resolver package: " + pkg,null);
+ if (pkg.length() == 0) continue;
+
+ String className = protocol.toUpperCase() + MX4JRemoteConstants.RESOLVER_CLASS;
+ String resolverClassName = constructClassName(pkg, protocol, className);
+
+ Class resolverClass = null;
+ try
+ {
+ resolverClass = loadClass(resolverClassName, loader);
+ }
+ catch (ClassNotFoundException x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Resolver class " + resolverClassName + " not found, continuing with next package",null);
+ continue;
+ }
+ catch (Exception x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_WARNING, "Cannot load resolver class " + resolverClassName, x);
+ return null;
+ }
+
+ try
+ {
+ return (ConnectionResolver)resolverClass.newInstance();
+ }
+ catch (Exception x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"Cannot instantiate resolver class " + resolverClassName, x);
+ return null;
+ }
+ }
+
+ // Nothing found
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Could not find resolver for protocol " + protocol + " in package list '" + packages + "'", null);
+ return null;
+ }
+
+ /**
+ * Looks up a connection to the server side as specified in the given JMXServiceURL.
+ * This method is used by {@link javax.management.remote.JMXConnector}s.
+ */
+ public abstract Object lookupClient(JMXServiceURL url, Map environment) throws IOException;
+
+ /**
+ * Connects the client returned by {@link #lookupClient} to the server side
+ */
+ public abstract Object bindClient(Object client, Map environment) throws IOException;
+
+ /**
+ * Creates an instance of the server as specified in the given JMXServiceURL.
+ * It is only a factory method, it should just return a fresh instance of the server;
+ * other methods are responsible to make it available to clients (for example exporting it).
+ * This method is used by {@link javax.management.remote.JMXConnectorServer}s.
+ * @see #bindServer
+ */
+ public abstract Object createServer(JMXServiceURL url, Map environment) throws IOException;
+
+ /**
+ * Binds the server created by {@link #createServer} to a place specified in the JMXServiceURL.
+ * @return a new JMXServiceURL that specifies where the server has been bound to.
+ * @see #unbindServer
+ */
+ public abstract JMXServiceURL bindServer(Object server, JMXServiceURL url, Map environment) throws IOException;
+
+ /**
+ * Unbinds the server created by {@link #createServer} from the place specified in the JMXServiceURL.
+ * @see #bindServer
+ */
+ public abstract void unbindServer(Object server, JMXServiceURL address, Map environment) throws IOException;
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/DefaultRemoteNotificationServerHandler.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/DefaultRemoteNotificationServerHandler.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/DefaultRemoteNotificationServerHandler.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/DefaultRemoteNotificationServerHandler.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.NotificationFilter;
+import javax.management.remote.NotificationResult;
+import javax.management.remote.TargetedNotification;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.RmiConnectorActivator;
+
+
+/**
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class DefaultRemoteNotificationServerHandler implements RemoteNotificationServerHandler
+{
+ private static int listenerID;
+
+ private final NotificationListener listener;
+ private final Map tuples = new HashMap();
+ private final NotificationBuffer buffer;
+
+ public DefaultRemoteNotificationServerHandler(Map environment)
+ {
+ listener = new ServerListener();
+ buffer = new NotificationBuffer(environment);
+ }
+
+ public Integer generateListenerID(ObjectName name, NotificationFilter filter)
+ {
+ synchronized (DefaultRemoteNotificationServerHandler.class)
+ {
+ return new Integer(++listenerID);
+ }
+ }
+
+ public NotificationListener getServerNotificationListener()
+ {
+ return listener;
+ }
+
+ public void addNotificationListener(Integer id, NotificationTuple tuple)
+ {
+ synchronized (tuples)
+ {
+ tuples.put(id, tuple);
+ }
+ }
+
+ public void removeNotificationListener(Integer id)
+ {
+ synchronized (tuples)
+ {
+ tuples.remove(id);
+ }
+ }
+
+ public NotificationTuple getNotificationListener(Integer id)
+ {
+ synchronized (tuples)
+ {
+ return (NotificationTuple)tuples.get(id);
+ }
+ }
+
+ public NotificationResult fetchNotifications(long sequenceNumber, int maxNotifications, long timeout)
+ {
+ return buffer.getNotifications(sequenceNumber, maxNotifications, timeout);
+ }
+
+ /**
+ * Called when there are no notifications to send to the client.
+ * It is guaranteed that no notification can be added before this method waits on the given lock.
+ * It should wait on the given lock for the specified timeout, and return true
+ * to send notifications (if no notifications arrived, an empty notification array
+ * will be returned to the client), or false if no notifications should be sent to
+ * the client.
+ * @param lock The object on which {@link #wait} should be called
+ * @param timeout The amount of time to wait (guaranteed to be strictly greater than 0)
+ */
+ protected boolean waitForNotifications(Object lock, long timeout)
+ {
+ synchronized (lock)
+ {
+ try
+ {
+ lock.wait(timeout);
+ }
+ catch (InterruptedException x)
+ {
+ Thread.currentThread().interrupt();
+ }
+ }
+ return true;
+ }
+
+ /**
+ * This method filters the given notification array and returns a possibly smaller array containing
+ * only notifications that passed successfully the filtering.
+ * Default behavior is no filtering, but subclasses may choose to change this bahavior.
+ * For example, for RMI, one can assure that all notifications are truly serializable, and log those
+ * that are not.
+ */
+ protected TargetedNotification[] filterNotifications(TargetedNotification[] notifications)
+ {
+ return notifications;
+ }
+
+ private void addNotification(Integer id, Notification notification)
+ {
+ buffer.add(new TargetedNotification(notification, id));
+ }
+
+ public class ServerListener implements NotificationListener
+ {
+ public void handleNotification(Notification notification, Object handback)
+ {
+ Integer id = (Integer)handback;
+ addNotification(id, notification);
+ }
+ }
+
+ public class NotificationBuffer
+ {
+ private final List buffer = new LinkedList();
+ private int maxCapacity;
+ private int purgeDistance;
+ private long firstSequence;
+ private long lastSequence;
+ private long lowestExpectedSequence;
+
+ public NotificationBuffer(Map environment)
+ {
+ if (environment != null)
+ {
+ try
+ {
+ maxCapacity = ((Integer)environment.get(MX4JRemoteConstants.NOTIFICATION_BUFFER_CAPACITY)).intValue();
+ }
+ catch (Exception ignored)
+ {
+ }
+
+ try
+ {
+ purgeDistance = ((Integer)environment.get(MX4JRemoteConstants.NOTIFICATION_PURGE_DISTANCE)).intValue();
+ }
+ catch (Exception ignored)
+ {
+ }
+ }
+ if (maxCapacity <= 0) maxCapacity = 1024;
+ if (purgeDistance <= 0) purgeDistance = 128;
+ }
+
+ public int getSize()
+ {
+ synchronized (buffer)
+ {
+ return buffer.size();
+ }
+ }
+
+ public void add(TargetedNotification notification)
+ {
+ synchronized (buffer)
+ {
+ if (buffer.size() == maxCapacity)
+ {
+ RmiConnectorActivator.log(LogService.LOG_DEBUG, "Notification buffer full: " + this, null);
+ removeRange(0, 1);
+ }
+ buffer.add(notification);
+ ++lastSequence;
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Notification added to buffer: " + this, null);
+ buffer.notifyAll();
+ }
+ }
+
+ private void removeRange(int start, int end)
+ {
+ synchronized (buffer)
+ {
+ buffer.subList(start, end).clear();
+ firstSequence += end - start;
+ }
+ }
+
+ private long getFirstSequenceNumber()
+ {
+ synchronized (buffer)
+ {
+ return firstSequence;
+ }
+ }
+
+ private long getLastSequenceNumber()
+ {
+ synchronized (buffer)
+ {
+ return lastSequence;
+ }
+ }
+
+ public NotificationResult getNotifications(long sequenceNumber, int maxNotifications, long timeout)
+ {
+ synchronized (buffer)
+ {
+ NotificationResult result = null;
+ int size = 0;
+ if (sequenceNumber < 0)
+ {
+ // We loose the notifications between addNotificationListener() and fetchNotifications(), but c'est la vie.
+ long sequence = getLastSequenceNumber();
+ size = new Long(sequence + 1).intValue();
+ result = new NotificationResult(getFirstSequenceNumber(), sequence, new TargetedNotification[0]);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"First fetchNotification call: " + this + ", returning " + result, null);
+ }
+ else
+ {
+ int start = new Long(sequenceNumber - getFirstSequenceNumber()).intValue();
+
+ List sublist = null;
+ boolean send = false;
+ while (size == 0)
+ {
+ int end = buffer.size();
+ if (end - start > maxNotifications) end = start + maxNotifications;
+
+ sublist = buffer.subList(start, end);
+ size = sublist.size();
+
+ if (send) break;
+
+ if (size == 0)
+ {
+ if (timeout <= 0) break;
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"No notifications to send, waiting " + timeout + " ms", null);
+
+ // We wait for notifications to arrive. Since we release the lock on the buffer
+ // other threads can modify it. To avoid ConcurrentModificationException we compute
+ // again the sublist
+ send = waitForNotifications(buffer, timeout);
+ }
+ }
+
+ TargetedNotification[] notifications = (TargetedNotification[])sublist.toArray(new TargetedNotification[size]);
+ notifications = filterNotifications(notifications);
+ result = new NotificationResult(getFirstSequenceNumber(), sequenceNumber + size, notifications);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Non-first fetchNotification call: " + this + ", returning " + result, null);
+
+ purgeNotifications(sequenceNumber, size);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Purged Notifications: " + this, null);
+ }
+ return result;
+ }
+ }
+
+ private void purgeNotifications(long sequenceNumber, int size)
+ {
+ // Record the lowest expected sequence number sent by the client.
+ // New clients will always have an initial big sequence number
+ // (they're initialized with getLastSequenceNumber()), while old
+ // clients can have lesser sequence numbers.
+ // Here we record the lesser of these sequence numbers, that is the
+ // sequence number of the oldest notification any client may ever ask.
+ // This way we can purge old notifications that have already been
+ // delivered to clients.
+
+ // The worst case is when a client has a long interval between fetchNotifications()
+ // calls, and another client has a short interval. The lowestExpectedSequence will
+ // grow with the second client, until a purge happens, so the first client can
+ // loose notifications. By tuning appropriately the purgeDistance and the interval
+ // between fetchNotifications() calls, it should never happen.
+
+ synchronized (buffer)
+ {
+ if (sequenceNumber <= lowestExpectedSequence)
+ {
+ long lowest = Math.min(lowestExpectedSequence, sequenceNumber);
+
+ if (lowest - getFirstSequenceNumber() > purgeDistance)
+ {
+ // Purge only half of the old notifications, for safety
+ int purgeSize = purgeDistance >> 1;
+ removeRange(0, purgeSize);
+ }
+
+ lowestExpectedSequence = sequenceNumber + size;
+ }
+ }
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer("NotificationBuffer@");
+ buffer.append(Integer.toHexString(hashCode())).append("[");
+ buffer.append("first=").append(getFirstSequenceNumber()).append(", ");
+ buffer.append("last=").append(getLastSequenceNumber()).append(", ");
+ buffer.append("size=").append(getSize()).append(", ");
+ buffer.append("lowest expected=").append(lowestExpectedSequence).append(", ");
+ buffer.append("maxCapacity=").append(maxCapacity).append(", ");
+ buffer.append("purgeDistance=").append(purgeDistance).append("]");
+ return buffer.toString();
+ }
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/HeartBeat.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/HeartBeat.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/HeartBeat.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/HeartBeat.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.IOException;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface HeartBeat
+{
+ public void start() throws IOException;
+ public void stop() throws IOException;
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteConstants.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteConstants.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteConstants.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteConstants.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+/**
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public interface MX4JRemoteConstants
+{
+ /**
+ * A vertical bar '|' as mandated by the spec
+ */
+ public static final String PROVIDER_PACKAGES_SEPARATOR = "|";
+ /**
+ * MX4J provider packages list for JMXConnector and JMXConnectorServer factories
+ */
+ public static final String PROVIDER_PACKAGES = "org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.provider" + PROVIDER_PACKAGES_SEPARATOR + "org.apache.felix.mosgi.jmx.rmiconnector.mx4j.tools.remote.provider";
+ /**
+ * The string 'ClientProvider' as mandated by the spec
+ */
+ public static final String CLIENT_PROVIDER_CLASS = "ClientProvider";
+ /**
+ * The string 'ServerProvider' as mandated by the spec
+ */
+ public static final String SERVER_PROVIDER_CLASS = "ServerProvider";
+
+
+ /**
+ * The key that specifies resolver packages, very much like
+ * {@link javax.management.remote.JMXConnectorFactory#PROTOCOL_PROVIDER_PACKAGES}
+ */
+ public static final String PROTOCOL_RESOLVER_PACKAGES = "mx4j.remote.resolver.pkgs";
+ /**
+ * A vertical bar '|'
+ */
+ public static final String RESOLVER_PACKAGES_SEPARATOR = PROVIDER_PACKAGES_SEPARATOR;
+ /**
+ * MX4J provider packages list for {@link mx4j.remote.ConnectionResolver} subclasses
+ */
+ public static final String RESOLVER_PACKAGES = "org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.resolver" + RESOLVER_PACKAGES_SEPARATOR + "org.apache.felix.mosgi.jmx.rmiconnector.mx4j.tools.remote.resolver";
+ /**
+ * The string 'Resolver'
+ */
+ public static final String RESOLVER_CLASS = "Resolver";
+
+ /**
+ * The reference implementation uses this property to specify the notification fetch timeout (in ms).
+ * MX4J will use the same for compatibility. DO NOT CHANGE IT unless the reference implementation changes it.
+ */
+ public static final String FETCH_NOTIFICATIONS_TIMEOUT = "jmx.remote.x.client.fetch.timeout";
+ /**
+ * The reference implementation uses this property to specify the maximum number of notification to fetch.
+ * MX4J will use the same for compatibility. DO NOT CHANGE IT unless the reference implementation changes it.
+ */
+ public static final String FETCH_NOTIFICATIONS_MAX_NUMBER = "jmx.remote.x.client.max.notifications";
+ /**
+ * The reference implementation uses this property to specify the notification buffer size.
+ * MX4J will use the same for compatibility. DO NOT CHANGE IT unless the reference implementation changes it.
+ */
+ public static final String NOTIFICATION_BUFFER_CAPACITY = "jmx.remote.x.buffer.size";
+ /**
+ * MX4J's implementation uses this property to specify the distance between the lowest expected notification
+ * sequence number (sent by the client via fetchNotifications()) and the minimum sequence number of the
+ * notification buffer. When this difference is greater than the value of this property, old notifications
+ * are eliminated from the notification buffer
+ */
+ public static final String NOTIFICATION_PURGE_DISTANCE = "jmx.remote.x.notification.purge.distance";
+ /**
+ * MX4J's implementation uses this property to specify the amount of time (in ms) the client should sleep
+ * between notification fetches. A value of 0 means there will be no sleep (fetches will be done one
+ * after the other).
+ */
+ public static final String FETCH_NOTIFICATIONS_SLEEP = "jmx.remote.x.notification.fetch.sleep";
+
+ /**
+ * MX4J's implementation uses this property to specify the period (in ms) of the heartbeat pulse for
+ * {@link javax.management.remote.JMXConnector JMXConnectors} that use heartbeat to check if the
+ * connection with {@link javax.management.remote.JMXConnectorServer JMXConnectorServers} is still alive.
+ * @see #CONNECTION_HEARTBEAT_RETRIES
+ */
+ public static final String CONNECTION_HEARTBEAT_PERIOD = "jmx.remote.x.connection.heartbeat.period";
+ /**
+ * MX4J's implementation uses this property to specify the number of retries of heartbeat pulses before
+ * declaring the connection between a {@link javax.management.remote.JMXConnector JMXConnector} and a
+ * {@link javax.management.remote.JMXConnectorServer JMXConnectorServer} failed, at which a
+ * {@link javax.management.remote.JMXConnectionNotification notification failed} is emitted.
+ * @see #CONNECTION_HEARTBEAT_PERIOD
+ */
+ public static final String CONNECTION_HEARTBEAT_RETRIES = "jmx.remote.x.connection.heartbeat.retries";
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteUtils.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteUtils.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteUtils.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/MX4JRemoteUtils.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.DomainCombiner;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import javax.security.auth.AuthPermission;
+import javax.security.auth.Policy;
+import javax.security.auth.Subject;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.remote.SubjectDelegationPermission;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.2 $
+ */
+public class MX4JRemoteUtils
+{
+ private static int connectionNumber;
+
+ /**
+ * Returns a copy of the given Map that does not contain non-serializable entries
+ */
+ public static Map removeNonSerializableEntries(Map map)
+ {
+ Map newMap = new HashMap(map.size());
+ for (Iterator i = map.entrySet().iterator(); i.hasNext();)
+ {
+ Map.Entry entry = (Map.Entry)i.next();
+ if (isSerializable(entry)) newMap.put(entry.getKey(), entry.getValue());
+ }
+ return newMap;
+ }
+
+ private static boolean isSerializable(Object object)
+ {
+ if (object instanceof Map.Entry) return isSerializable(((Map.Entry)object).getKey()) && isSerializable(((Map.Entry)object).getValue());
+ if (object == null) return true;
+ if (object instanceof String) return true;
+ if (object instanceof Number) return true;
+ if (!(object instanceof Serializable)) return false;
+
+ return isTrulySerializable(object);
+ }
+
+ public static boolean isTrulySerializable(Object object)
+ {
+ // Give up and serialize the object
+ try
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(object);
+ oos.close();
+ return true;
+ }
+ catch (IOException ignored)
+ {
+ }
+ return false;
+ }
+
+ public static String createConnectionID(String protocol, String callerAddress, int callerPort, Subject subject)
+ {
+ // See JSR 160 specification at javax/management/remote/package-summary.html
+
+ StringBuffer buffer = new StringBuffer(protocol);
+ buffer.append(':');
+ if (callerAddress != null) buffer.append("//").append(callerAddress);
+ if (callerPort >= 0) buffer.append(':').append(callerPort);
+ buffer.append(' ');
+
+ if (subject != null)
+ {
+ Set principals = subject.getPrincipals();
+ for (Iterator i = principals.iterator(); i.hasNext();)
+ {
+ Principal principal = (Principal)i.next();
+ String name = principal.getName();
+ name = name.replace(' ', '_');
+ buffer.append(name);
+ if (i.hasNext()) buffer.append(';');
+ }
+ }
+ buffer.append(' ');
+
+ buffer.append("0x").append(Integer.toHexString(getNextConnectionNumber()));
+
+ return buffer.toString();
+ }
+
+ private static synchronized int getNextConnectionNumber()
+ {
+ return ++connectionNumber;
+ }
+
+ public static Object subjectInvoke(Subject subject, Subject delegate, AccessControlContext context, PrivilegedExceptionAction action) throws Exception
+ {
+ if (delegate != null)
+ {
+ if (subject == null) throw new SecurityException("There is no authenticated subject to delegate to");
+ checkSubjectDelegationPermission(delegate, getSubjectContext(subject, context));
+ }
+
+ if (subject == null)
+ {
+ if (context == null) return action.run();
+ try
+ {
+ return AccessController.doPrivileged(action, context);
+ }
+ catch (PrivilegedActionException x)
+ {
+ throw x.getException();
+ }
+ }
+
+ try
+ {
+ AccessControlContext subjectContext = getSubjectContext(subject, context);
+ return Subject.doAsPrivileged(subject, action, subjectContext);
+ }
+ catch (PrivilegedActionException x)
+ {
+ throw x.getException();
+ }
+ }
+
+ private static void checkSubjectDelegationPermission(final Subject delegate, AccessControlContext context) throws SecurityException
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ {
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ StringBuffer buffer = new StringBuffer();
+ Set principals = delegate.getPrincipals();
+ for (Iterator i = principals.iterator(); i.hasNext();)
+ {
+ Principal principal = (Principal)i.next();
+ buffer.setLength(0);
+ String permission = buffer.append(principal.getClass().getName()).append(".").append(principal.getName()).toString();
+ sm.checkPermission(new SubjectDelegationPermission(permission));
+ }
+ return null;
+ }
+ }, context);
+ }
+ }
+
+ /**
+ * Returns a suitable AccessControlContext that restricts access in a {@link Subject#doAsPrivileged} call
+ * based on the current JAAS authorization policy, and combined with the given context.
+ *
+ * This is needed because the server stack frames in a call to a JMXConnectorServer are,
+ * for example for RMI, like this:
+ * <pre>
+ * java.lang.Thread.run()
+ * [rmi runtime classes]
+ * javax.management.remote.rmi.RMIConnectionImpl
+ * [mx4j JSR 160 implementation code]
+ * javax.security.auth.Subject.doAsPrivileged()
+ * [mx4j JSR 160 implementation code]
+ * [mx4j JSR 3 implementation code]
+ * </pre>
+ * All protection domains in this stack frames have AllPermission, normally, and the Subject.doAsPrivileged()
+ * call stops the checks very early. <br>
+ *
+ * So we need a restricting context (created at the start() of the connector server), and furthermore we need
+ * to combine the restricting context with a "special" context that does not have the same location as the
+ * JSR 3 and 160 classes and implementation (in particular will have a null location). <br>
+ * The "injection" of this synthetic ProtectionDomain allows to give AllPermission to the JSR 3 and 160 classes
+ * and implementation, but still have the possibility to specify a JAAS policy with MBeanPermissions in this way:
+ * <pre>
+ * grant principal javax.management.remote.JMXPrincipal "mx4j"
+ * {
+ * permission javax.management.MBeanPermission "*", "getAttribute";
+ * };
+ * </pre>
+ */
+ private static AccessControlContext getSubjectContext(final Subject subject, final AccessControlContext context)
+ {
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm == null)
+ {
+ return context;
+ }
+ else
+ {
+ return (AccessControlContext)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ InjectingDomainCombiner combiner = new InjectingDomainCombiner(subject);
+ AccessControlContext acc = new AccessControlContext(context, combiner);
+ AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ // Check this permission, that is required anyway, to combine the domains
+ sm.checkPermission(new AuthPermission("doAsPrivileged"));
+ return null;
+ }
+ }, acc);
+ ProtectionDomain[] combined = combiner.getCombinedDomains();
+ return new AccessControlContext(combined);
+ }
+ });
+ }
+ }
+
+ private static class InjectingDomainCombiner implements DomainCombiner
+ {
+ private static Constructor domainConstructor;
+
+ static
+ {
+ try
+ {
+ domainConstructor = ProtectionDomain.class.getConstructor(new Class[]{CodeSource.class, PermissionCollection.class, ClassLoader.class, Principal[].class});
+ }
+ catch (Exception x)
+ {
+ }
+ }
+
+ private ProtectionDomain domain;
+ private ProtectionDomain[] combined;
+
+ public InjectingDomainCombiner(Subject subject)
+ {
+ if (domainConstructor != null)
+ {
+ Principal[] principals = (Principal[])subject.getPrincipals().toArray(new Principal[0]);
+ try
+ {
+ domain = (ProtectionDomain)domainConstructor.newInstance(new Object[]{new CodeSource(null, (java.security.cert.Certificate[])null), null, null, principals});
+ }
+ catch (Exception x)
+ {
+ }
+ }
+
+ if (domain == null)
+ {
+ // This is done for JDK 1.3 compatibility.
+ domain = new SubjectProtectionDomain(new CodeSource(null, (java.security.cert.Certificate[])null), subject);
+ }
+ }
+
+ public ProtectionDomain[] combine(ProtectionDomain[] current, ProtectionDomain[] assigned)
+ {
+ int length = current.length;
+ ProtectionDomain[] result = null;
+ if (assigned == null || assigned.length == 0)
+ {
+ result = new ProtectionDomain[length + 1];
+ System.arraycopy(current, 0, result, 0, length);
+ }
+ else
+ {
+ result = new ProtectionDomain[length + assigned.length + 1];
+ System.arraycopy(current, 0, result, 0, length);
+ System.arraycopy(assigned, 0, result, length, assigned.length);
+ }
+ result[result.length - 1] = domain;
+ this.combined = result;
+ return result;
+ }
+
+ public ProtectionDomain[] getCombinedDomains()
+ {
+ return combined;
+ }
+
+ private static class SubjectProtectionDomain extends ProtectionDomain
+ {
+ private final Subject subject;
+
+ public SubjectProtectionDomain(CodeSource codesource, Subject subject)
+ {
+ super(codesource, null);
+ this.subject = subject;
+ }
+
+ public boolean implies(Permission permission)
+ {
+ Policy policy = (Policy)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return Policy.getPolicy();
+ }
+ });
+ PermissionCollection permissions = policy.getPermissions(subject, getCodeSource());
+ return permissions.implies(permission);
+ }
+ }
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/NotificationTuple.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/NotificationTuple.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/NotificationTuple.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/NotificationTuple.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import javax.management.NotificationFilter;
+import javax.management.Notification;
+import javax.management.ObjectName;
+import javax.management.NotificationListener;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.1.1.1 $
+ */
+public class NotificationTuple
+{
+ private static final NotificationFilter NO_FILTER = new NotificationFilter()
+ {
+ public boolean isNotificationEnabled(Notification notification)
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return "no filter";
+ }
+ };
+ private static final Object NO_HANDBACK = new Object()
+ {
+ public String toString()
+ {
+ return "no handback";
+ }
+ };
+
+ private final ObjectName observed;
+ private final NotificationListener listener;
+ private final NotificationFilter filter;
+ private final Object handback;
+ private boolean invokeFilter;
+
+ public NotificationTuple(ObjectName observed, NotificationListener listener)
+ {
+ this(observed, listener, NO_FILTER, NO_HANDBACK);
+ }
+
+ public NotificationTuple(ObjectName observed, NotificationListener listener, NotificationFilter filter, Object handback)
+ {
+ this.observed = observed;
+ this.listener = listener;
+ this.filter = filter;
+ this.handback = handback;
+ this.invokeFilter = false;
+ }
+
+ public NotificationListener getNotificationListener()
+ {
+ return listener;
+ }
+
+ public Object getHandback()
+ {
+ if (handback == NO_HANDBACK) return null;
+ return handback;
+ }
+
+ public NotificationFilter getNotificationFilter()
+ {
+ if (filter == NO_FILTER) return null;
+ return filter;
+ }
+
+ public void setInvokeFilter(boolean invoke)
+ {
+ this.invokeFilter = invoke;
+ }
+
+ public boolean getInvokeFilter()
+ {
+ if (!invokeFilter) return false;
+ NotificationFilter filter = getNotificationFilter();
+ if (filter == null) return false;
+ return true;
+ }
+
+ public boolean equals(Object obj)
+ {
+ if (this == obj) return true;
+ if (!(obj instanceof NotificationTuple)) return false;
+
+ final NotificationTuple other = (NotificationTuple)obj;
+
+ if (!observed.equals(other.observed)) return false;
+ if (!listener.equals(other.listener)) return false;
+
+ // Special treatment for special filter
+ if (filter == NO_FILTER) return true;
+ if (other.filter == NO_FILTER) return true;
+
+ if (filter != null ? !filter.equals(other.filter) : other.filter != null) return false;
+ if (handback != null ? !handback.equals(other.handback) : other.handback != null) return false;
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ int result;
+ result = observed.hashCode();
+ result = 29 * result + listener.hashCode();
+ result = 29 * result + (filter != null ? filter.hashCode() : 0);
+ result = 29 * result + (handback != null ? handback.hashCode() : 0);
+ return result;
+ }
+
+ public String toString()
+ {
+ StringBuffer buffer = new StringBuffer("NotificationTuple [");
+ buffer.append(observed).append(", ");
+ buffer.append(listener).append(", ");
+ buffer.append(filter).append(", ");
+ buffer.append(handback).append("]");
+ return buffer.toString();
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderFactory.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderFactory.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderFactory.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderFactory.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) MX4J.
+ * All rights reserved.
+ *
+ * This software is distributed under the terms of the MX4J License version 1.0.
+ * See the terms of the MX4J License in the documentation provided with this software.
+ */
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXConnectorProvider;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXConnectorServerProvider;
+import javax.management.remote.JMXProviderException;
+import javax.management.remote.JMXServiceURL;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.RmiConnectorActivator;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.MX4JRemoteConstants;
+import org.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote.ProviderHelper;
+
+/**
+ *
+ * @author <a href="mailto:biorn_steedom@users.sourceforge.net">Simone Bordet</a>
+ * @version $Revision: 1.2 $
+ */
+public class ProviderFactory extends ProviderHelper
+{
+ public static JMXConnectorProvider newJMXConnectorProvider(JMXServiceURL url, Map env) throws IOException
+ {
+ // Yes, throw NPE if url is null (spec compliant)
+ String protocol = normalizeProtocol(url.getProtocol());
+ String providerPackages = findProviderPackageList(env, JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES);
+ ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
+ JMXConnectorProvider provider = (JMXConnectorProvider)loadProvider(providerPackages, protocol, MX4JRemoteConstants.CLIENT_PROVIDER_CLASS, classLoader);
+ return provider;
+ }
+
+ public static JMXConnectorServerProvider newJMXConnectorServerProvider(JMXServiceURL url, Map env) throws IOException
+ {
+ // Yes, throw NPE if url is null (spec compliant)
+ String protocol = normalizeProtocol(url.getProtocol());
+ String providerPackages = findProviderPackageList(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES);
+ ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER);
+ JMXConnectorServerProvider provider = (JMXConnectorServerProvider)loadProvider(providerPackages, protocol, MX4JRemoteConstants.SERVER_PROVIDER_CLASS, classLoader);
+ return provider;
+ }
+
+ private static String findEnvironmentProviderPackageList(Map environment, String key) throws JMXProviderException
+ {
+ String providerPackages = null;
+ if (environment != null)
+ {
+ Object pkgs = environment.get(key);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG, "Provider packages in the environment: " + pkgs, null);
+ if (pkgs != null && !(pkgs instanceof String)) throw new JMXProviderException("Provider package list must be a string");
+ providerPackages = (String)pkgs;
+ }
+ return providerPackages;
+ }
+
+ private static String findProviderPackageList(Map environment, final String providerPkgsKey) throws JMXProviderException
+ {
+ // 1. Look in the environment
+ // 2. Look for system property
+ // 3. Use implementation's provider
+
+ String providerPackages = findEnvironmentProviderPackageList(environment, providerPkgsKey);
+
+ if (providerPackages == null)
+ {
+ providerPackages = findSystemPackageList(providerPkgsKey);
+ }
+
+ if (providerPackages != null && providerPackages.trim().length() == 0) throw new JMXProviderException("Provider package list cannot be an empty string");
+
+ if (providerPackages == null)
+ providerPackages = MX4JRemoteConstants.PROVIDER_PACKAGES;
+ else
+ providerPackages += MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR + MX4JRemoteConstants.PROVIDER_PACKAGES;
+
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Provider packages list is: " + providerPackages,null);
+
+ return providerPackages;
+ }
+
+ private static ClassLoader findProviderClassLoader(Map environment, String providerLoaderKey)
+ {
+
+ ClassLoader classLoader = null;
+ if (environment != null)
+ {
+ Object loader = environment.get(providerLoaderKey);
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Provider classloader in the environment: " + loader, null);
+ if (loader != null && !(loader instanceof ClassLoader)) throw new IllegalArgumentException("Provider classloader is not a ClassLoader");
+ classLoader = (ClassLoader)loader;
+ }
+
+ if (classLoader == null)
+ {
+ //classLoader = Thread.currentThread().getContextClassLoader();
+ classLoader = ProviderFactory.class.getClassLoader();
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Provider classloader (was null) in the environment: " + classLoader, null);
+ }
+
+ // Add the classloader as required by the spec
+ environment.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, classLoader);
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"Provider classloader added to the environment", null);
+
+ return classLoader;
+ }
+
+ private static Object loadProvider(String packages, String protocol, String className, ClassLoader loader) throws JMXProviderException, MalformedURLException
+ {
+ StringTokenizer tokenizer = new StringTokenizer(packages, MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR);
+ while (tokenizer.hasMoreTokens())
+ {
+ String pkg = tokenizer.nextToken().trim();
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Provider package: " + pkg, null);
+
+ // The spec states the package cannot be empty
+ if (pkg.length() == 0) throw new JMXProviderException("Empty package list not allowed: " + packages);
+
+ String providerClassName = constructClassName(pkg, protocol, className);
+
+ Class providerClass = null;
+ try
+ {
+ providerClass = loadClass(providerClassName, loader);
+ }
+ catch (ClassNotFoundException x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Provider class " + providerClassName + " not found, continuing with next package",null);
+ continue;
+ }
+ catch (Exception x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"Cannot load provider class " + providerClassName, x);
+ throw new JMXProviderException("Cannot load provider class " + providerClassName, x);
+ }
+
+ try
+ {
+ return providerClass.newInstance();
+ }
+ catch (Exception x)
+ {
+ RmiConnectorActivator.log(LogService.LOG_WARNING,"Cannot instantiate provider class " + providerClassName, x);
+ throw new JMXProviderException("Cannot instantiate provider class " + providerClassName, x);
+ }
+ }
+
+ // Nothing found
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Could not find provider for protocol " + protocol + " in package list '" + packages + "'", null);
+ throw new MalformedURLException("Could not find provider for protocol " + protocol + " in package list '" + packages + "'");
+ }
+}
Added: incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderHelper.java
URL: http://svn.apache.org/viewvc/incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderHelper.java?rev=423854&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderHelper.java (added)
+++ incubator/felix/trunk/org.apache.felix.mosgi.jmx.rmiconnector/src/main/java/org/apache/felix/mosgi/jmx/rmiconnector/mx4j/remote/ProviderHelper.java Thu Jul 20 02:35:19 2006
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * 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.apache.felix.mosgi.jmx.rmiconnector.mx4j.remote;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.osgi.service.log.LogService;
+
+import org.apache.felix.mosgi.jmx.rmiconnector.RmiConnectorActivator;
+
+/**
+ *
+ * @version $Revision: 1.2 $
+ */
+public abstract class ProviderHelper
+{
+ protected static String normalizeProtocol(String protocol)
+ {
+ // Replace special chars as required by the spec
+ String normalized = protocol.replace('+', '.');
+ normalized = normalized.replace('-', '_');
+ RmiConnectorActivator.log(LogService.LOG_INFO, "Normalizing protocol: " + protocol + " --> " + normalized, null);
+ return normalized;
+ }
+
+ protected static String findSystemPackageList(final String key)
+ {
+ String providerPackages = (String)AccessController.doPrivileged(new PrivilegedAction()
+ {
+ public Object run()
+ {
+ return System.getProperty(key);
+ }
+ });
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Packages in the system property '" + key + "': " + providerPackages,null);
+ return providerPackages;
+ }
+
+ protected static Class loadClass(String className, ClassLoader loader) throws ClassNotFoundException
+ {
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"Loading class: " + className +" From "+loader,null);
+ if (loader == null){
+ loader= ProviderHelper.class.getClassLoader();
+ RmiConnectorActivator.log(LogService.LOG_DEBUG,"a new loader "+loader,null);
+
+ //Thread.currentThread().getContextClassLoader();
+ }
+ return loader.loadClass(className);
+ }
+
+ protected static String constructClassName(String packageName, String protocol, String className)
+ {
+ return new StringBuffer(packageName).append(".").append(protocol).append(".").append(className).toString();
+ }
+
+}