You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@etch.apache.org by sc...@apache.org on 2009/02/27 17:37:19 UTC
svn commit: r748580 [2/5] - in /incubator/etch/branches/router: ./
services/router/ services/router/scripts/ services/router/src/main/etch/
services/router/src/main/java/cisco/ services/router/src/main/java/org/
services/router/src/main/java/org/apache...
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,854 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.etch.bindings.java.msg.Direction;
+import org.apache.etch.bindings.java.msg.Field;
+import org.apache.etch.bindings.java.msg.Message;
+import org.apache.etch.bindings.java.msg.StructValue;
+import org.apache.etch.bindings.java.msg.Type;
+import org.apache.etch.bindings.java.support.DeliveryService;
+import org.apache.etch.bindings.java.support.Mailbox;
+import org.apache.etch.bindings.java.support.ServerFactory;
+import org.apache.etch.services.router.ConnectionStackInfo.ConnectionType;
+import org.apache.etch.services.router.EtchRouter.EtchRouterException;
+import org.apache.etch.services.router.EtchRouter.PluginServiceState;
+import org.apache.etch.services.router.plugin.PluginGroup;
+import org.apache.etch.services.router.plugin.PluginMemberConnection;
+import org.apache.etch.services.router.plugin.PluginStateMonitor;
+import org.apache.etch.services.router.utils.LocalTypeImportExportHelper;
+import org.apache.etch.services.router.utils.StructValueImportExportHelper;
+import org.apache.etch.services.router.utils.XmlBindingData;
+import org.apache.etch.services.router.utils.XmlBindingDataParser;
+import org.apache.etch.util.core.Who;
+import org.apache.etch.util.core.io.Session;
+import org.apache.etch.util.core.io.Transport;
+
+/**
+ * Main class for the Etch Router service
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class EtchRouterManager
+{
+ /**
+ * Key in the resources map for this EtchRouterManager
+ */
+ public static final String _ETCH_ROUTER_MANAGER = "EtchRouterManager";
+
+ private static final Logger _LOGGER = Logger.getLogger( EtchRouterManager.class.getName());
+
+ private Properties _properties = null;
+
+ private File _homeDir = null;
+
+ private File _appsRoot = null;
+
+ private File _pluginsRoot = null;
+
+ private String _url = null;
+
+ private final Object _syncObj = new Object();
+
+ private DynamicValueFactory _valueFactory = null;
+
+ private Map<String, PluginGroup> _pluginMap = null;
+
+ private Map<Type, PluginGroup> _method2PluginMap = null;
+
+ private Map<String, ApplicationInstallInfo> _appMap = null;
+
+ // all methods defined by the EtchRouter's own XML binding file:
+ private Map<Type, Boolean> _localMethodsMap = null;
+
+ private Map<EtchRouterMessageFilter, ConnectionStackInfo> _connectionInfoMapByFilter = null;
+
+ private Map<DeliveryService, ConnectionStackInfo> _connInfoMapByDs = null;
+
+ private ERStubHelper _stubHelper = new ERStubHelper();
+
+ private Map<ConnectionStackInfo, ApplicationConnectionInfo> _appConnectionInfoMap = null;
+
+ private Map<ConnectionStackInfo, ApplicationConnectionInfo> _pluginServerConn2AppConnMap = null;
+
+ private static final String _REGISTER_ROUTER_APP_METHOD_NAME = "registerRouterApplication";
+
+ private static final String _ROUTER_PLUGIN_SERVICE_STATE_CHANGE_METHOD_NAME = "routerPluginServiceStateChange";
+
+ private Type _registerApplicationMethodType = null;
+
+ private Field _mf_applicationName = new Field("applicationName");
+ private Field _mf_applicationParam = new Field("applicationParam");
+
+ private Type _pluginServiceStateChangeMethodType = null;
+ private Field _mf_pluginGroupName = new Field("pluginGroupName");
+ private Field _mf_state = new Field("state");
+ private Field _mf_detail = new Field("detail");
+
+ //number of miliseconds
+ private int _connStartMaxDelay = 4000;
+
+ // number of miliseconds
+ private int _connStopMaxDelay = 4000;
+
+ /**
+ * Constructor
+ *
+ * @param properties
+ * @throws Exception
+ */
+ public EtchRouterManager(Properties properties) throws Exception
+ {
+ _properties = properties;
+ initProperties();
+
+ _pluginMap = Collections.synchronizedMap( new HashMap<String, PluginGroup>() );
+ _method2PluginMap = Collections.synchronizedMap( new HashMap<Type, PluginGroup>() );
+ _appMap = Collections.synchronizedMap( new HashMap<String, ApplicationInstallInfo>() );
+ _valueFactory = new DynamicValueFactory(_url);
+ _localMethodsMap = new HashMap<Type, Boolean>();
+ _connectionInfoMapByFilter = Collections.synchronizedMap( new HashMap<EtchRouterMessageFilter, ConnectionStackInfo>() );
+ _connInfoMapByDs = Collections.synchronizedMap( new HashMap<DeliveryService, ConnectionStackInfo>() );
+ _appConnectionInfoMap = Collections.synchronizedMap( new HashMap<ConnectionStackInfo, ApplicationConnectionInfo>() );
+ _pluginServerConn2AppConnMap = Collections.synchronizedMap( new HashMap<ConnectionStackInfo, ApplicationConnectionInfo>() );
+ }
+
+ private void initProperties() throws Exception
+ {
+ _url = _properties.getProperty( "listener.url" );
+ _homeDir = new File(_properties.getProperty( "etch.router.home", "." ));
+ if (_url==null)
+ throw new Exception("The property 'listener.url' is not specified in properties");
+ if (!(_homeDir.exists() && _homeDir.isDirectory()))
+ throw new Exception(String.format( "Invalid home directory: %s", _homeDir.getPath() ));
+ String appsRoot = _properties.getProperty( "applications.root.dir" );
+ _appsRoot = appsRoot==null ? new File(_homeDir, "applications") : new File(appsRoot);
+ if ((!_appsRoot.exists()) || (!_appsRoot.isDirectory()))
+ throw new Exception(String.format( "The applications root directory does not exist: %s", _appsRoot.getAbsolutePath()));
+ String pluginsRoot = _properties.getProperty( "plugins.root.dir" );
+ _pluginsRoot = pluginsRoot==null ? new File(_homeDir, "plugins") : new File(pluginsRoot);
+ if ((!_pluginsRoot.exists()) || (!_pluginsRoot.isDirectory()))
+ throw new Exception(String.format( "The plugins root directory does not exist: %s", _pluginsRoot.getAbsolutePath()));
+
+ try
+ {
+ _connStartMaxDelay = Integer.parseInt( _properties.getProperty( "connection.start.max.delay" ) );
+ }
+ catch (Exception e)
+ {
+
+ }
+ try
+ {
+ _connStopMaxDelay = Integer.parseInt( _properties.getProperty( "connection.stop.max.delay" ) );
+ }
+ catch (Exception e)
+ {
+
+ }
+ }
+
+ public String getProperty(String key, String defaultValue)
+ {
+ return _properties.getProperty( key, defaultValue );
+ }
+
+ /**
+ * Max delay time when calling _startAndWaitUp
+ *
+ * @return
+ */
+ public int getConnectionStartMaxDelay()
+ {
+ return _connStartMaxDelay;
+ }
+
+ /**
+ * Max delay time when calling _stopAndWaitDown
+ *
+ * @return
+ */
+ public int getConnectionStopMaxDelay()
+ {
+ return _connStopMaxDelay;
+ }
+
+ /**
+ * Call back method
+ *
+ * @param svc
+ * @param sender
+ * @param msg
+ */
+ public void handleStubHelperCall(DeliveryService svc, Who sender, Message msg)
+ {
+ _LOGGER.log( Level.FINEST, "Method called, msg's type name is \"{0}\"", msg.type().getName());
+ }
+
+ /**
+ *
+ * @param event
+ * @param connStackInfo
+ * @throws Exception
+ */
+ public void sessionNotify(Object event, ConnectionStackInfo connStackInfo) throws Exception
+ {
+ if (event != Session.DOWN) return;
+ _LOGGER.log( Level.INFO, "Method starts, event is: {0}, connection is: {1}",
+ new Object[] { event, connStackInfo } );
+ ConnectionType connType = connStackInfo.getConnectionType();
+ if (connType==null)
+ {
+ removeConnectionStackInfo( connStackInfo );
+ }
+ else if (connType==ConnectionType.APP_CLIENT_CONN)
+ {
+ ApplicationConnectionInfo appConnInfo = this.getAppConnectionInfoByAppClientStackInfo( connStackInfo );
+ if (appConnInfo!=null)
+ {
+ appConnInfo.stopAllPluginConnections();
+ _appConnectionInfoMap.remove( connStackInfo );
+ Collection<PluginGroup> pluginGrps = appConnInfo.getReferencedPluginGroups();
+ for (PluginGroup pluginGrp : pluginGrps)
+ {
+ pluginGrp.removeApplicationConnection( appConnInfo );
+ }
+ }
+ removeConnectionStackInfo( connStackInfo );
+ }
+ else if (connType==ConnectionType.PLUGIN_MONITOR_CONN)
+ {
+ PluginGroup pluginGroup = this.getPluginGroup( connStackInfo.getPluginOrAppName() );
+ pluginGroup.onPluginMemberConnectionDown( connStackInfo );
+ removeConnectionStackInfo( connStackInfo );
+ }
+ else if (connType==ConnectionType.PLUGIN_SERVER_CONN)
+ {
+ ApplicationConnectionInfo appConnInfo = this.getAppConnectionInfoByPluginServerStackInfo( connStackInfo );
+ if (appConnInfo!=null)
+ {
+ PluginGroup pluginGrp = appConnInfo.getPluginGroupByName( connStackInfo.getPluginOrAppName() );
+ PluginMemberConnection instConn = appConnInfo.getPluginConnectionByPluginGroup( pluginGrp );
+ //remove the corresponding plugin instance from available list before re-init:
+ pluginGrp.onPluginMemberConnectionDown( instConn.getMember().getConnInfo() );
+ appConnInfo.stopPluginConnection( pluginGrp, true );
+ appConnInfo.initPluginConnection( pluginGrp );
+ }
+ removeConnectionStackInfo( connStackInfo );
+ }
+ }
+
+
+ /**
+ * This is called by ERMessagizer.sessionPacket
+ *
+ * @param sender
+ * @param connStackInfo
+ * @param msg
+ */
+ public void handleLocalMethodMessage( Who sender, ConnectionStackInfo connStackInfo, Message msg)
+ {
+ ConnectionType connType = connStackInfo.getConnectionType();
+ Type methodType = msg.type();
+ Message rmsg = (methodType.getResult()==null) ? null : msg.reply();
+ Object result = null;
+ try
+ {
+ if (_registerApplicationMethodType.equals( methodType ))
+ {
+ if (connType==null)
+ {
+ result = registerApplication( sender, connStackInfo, msg );
+ }
+ else
+ throw new EtchRouterException(2, String.format( "Cannot register application because the connection was already established as type %s", connType.name() ));
+ }
+ else
+ {
+ result = handleOtherLocalMessage( sender, connStackInfo, msg );
+ }
+ }
+ catch (Throwable e)
+ {
+ if (e instanceof EtchRouterException) result = e;
+ else if ( e instanceof RuntimeException ) result = e;
+ else result = new RuntimeException(e);
+ }
+ if (rmsg!=null)
+ {
+ if (result!=null) rmsg.put( DynamicValueFactory._mf_result, result);
+ try
+ {
+ connStackInfo.getDeliveryService().transportMessage( sender, rmsg );
+ }
+ catch (Exception ee)
+ {
+ _LOGGER.log( Level.SEVERE, "Got Exception: ", ee);
+ }
+ }
+ if (result instanceof Throwable)
+ _LOGGER.log( Level.SEVERE, "Got Exception: ", (Throwable)result);
+
+ }
+
+ private Object handleOtherLocalMessage( Who sender, ConnectionStackInfo connStackInfo, Message msg ) throws Exception
+ {
+ throw new EtchRouterException(1, String.format( "Etch-router API is not implemented: %s", msg.type().getName() ));
+ }
+
+ private String registerApplication( Who sender, ConnectionStackInfo connStackInfo, Message msg ) throws Exception
+ {
+ String applicationName = (String)msg.get( _mf_applicationName );
+ String applicationParam = (String)msg.get( _mf_applicationParam );
+ return registerApplication(applicationName, applicationParam, connStackInfo);
+ }
+
+ /**
+ *
+ * @param connStackInfo
+ * @param pluginMethod
+ * @throws Exception
+ */
+ public void registerAnonymousApplication( ConnectionStackInfo connStackInfo, Type pluginMethod ) throws Exception
+ {
+ synchronized (_syncObj)
+ {
+ ApplicationConnectionInfo connInfo = _appConnectionInfoMap.get( connStackInfo );
+ if (connInfo==null)
+ {
+ connStackInfo.setConnectionType( ConnectionType.APP_CLIENT_CONN, null );
+ connInfo = new ApplicationConnectionInfo( connStackInfo, this, pluginMethod );
+ _appConnectionInfoMap.put( connStackInfo, connInfo );
+ }
+ }
+ }
+
+ /**
+ *
+ * @param applicationName
+ * @param appConnInfo
+ * @throws Exception
+ */
+ private String registerApplication( String applicationName, String applicationParam, ConnectionStackInfo appConnInfo )
+ throws Exception
+ {
+ //allow lazy loading of the application install directory
+ ApplicationInstallInfo appInstallInfo = null;
+ try
+ {
+ loadApplicationInstallInfo(applicationName);
+ }
+ catch (Exception ee)
+ {
+ //_LOGGER.log( Level.FINE, "Registering anonymous app connection as application \"{0}\": {1}", new Object[]{ applicationName, appConnInfo} );
+ }
+ synchronized (_syncObj)
+ {
+ ApplicationConnectionInfo connInfo = _appConnectionInfoMap.get( appConnInfo );
+ if (connInfo==null)
+ {
+ appConnInfo.setConnectionType( ConnectionType.APP_CLIENT_CONN, appInstallInfo==null ? null : applicationName );
+ connInfo = new ApplicationConnectionInfo( applicationParam, appInstallInfo, appConnInfo, this);
+ _appConnectionInfoMap.put( appConnInfo, connInfo );
+ }
+ else
+ {
+ if (connInfo.isAnonymous())
+ {
+ _LOGGER.log( Level.FINE, "Registering anonymous app connection as application \"{0}\": {1}", new Object[]{ applicationName, appConnInfo} );
+ connInfo.setApplicationName( applicationName );
+ connInfo.setApplicationParam( applicationParam );
+ }
+ else
+ {
+ throw new EtchRouterException(1, "The application client is already registered with Etch Router manager");
+ }
+ }
+ }
+ return "OK";
+ }
+
+ /**
+ *
+ * @param pluginGroupName
+ * @param state
+ * @param appClientConn
+ * @throws Exception
+ */
+ public void callAppClientMethod_pluginServiceStateChange( String pluginGroupName, PluginServiceState state, String detail, ConnectionStackInfo appClientConn ) throws Exception
+ {
+ Message msg = new Message(_pluginServiceStateChangeMethodType, _valueFactory);
+ msg.put( _mf_pluginGroupName, pluginGroupName );
+ msg.put( _mf_state, state );
+ msg.put( _mf_detail, detail );
+ callClientMethod( msg, appClientConn );
+ }
+
+ /**
+ *
+ * @param msgDetail
+ * @param connStack
+ * @throws Exception
+ */
+ public void sentNotifyMsgToConnection( String msgDetail, ConnectionStackInfo connStack ) throws Exception
+ {
+ Message msg = new Message(_valueFactory.get_mt__exception(), _valueFactory);
+ msg.put( _valueFactory._mf_result, new RuntimeException(msgDetail) );
+ callClientMethod( msg, connStack );
+ }
+
+ private Object callClientMethod( Message msg, ConnectionStackInfo connInfo ) throws Exception
+ {
+ Type methodType = msg.type();
+ if (methodType.getDirection()==Direction.SERVER)
+ {
+ throw new EtchRouterException(1, String.format( "Cannot send method '%s' to an EtchRouter client.", methodType.getName() ));
+ }
+ DeliveryService ds = connInfo.getDeliveryService();
+ Type resultType = methodType.getResult();
+ if (resultType==null)
+ {
+ //is oneWay:
+ try
+ {
+ ds.transportMessage( null, msg );
+ return null;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(String.format( "Unknown error while calling oneway client method '%s'", methodType.getName() ), e);
+ }
+ }
+ try
+ {
+ Mailbox mbox = ds.begincall( msg );
+ return ds.endcall( mbox, resultType );
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(String.format( "Unknown error while calling twoway client method '%s'", methodType.getName() ), e);
+ }
+ }
+
+
+ /**
+ *
+ * @param info
+ */
+ public void addConnectionStackInfo(ConnectionStackInfo info)
+ {
+ _connectionInfoMapByFilter.put( info.getMessageFilter(), info );
+ _connInfoMapByDs.put( info.getDeliveryService(), info );
+ }
+
+ public ConnectionStackInfo getConnectionStackInfo( EtchRouterMessageFilter filter)
+ {
+ return _connectionInfoMapByFilter.get( filter );
+ }
+
+ public ConnectionStackInfo getConnectionStackInfo( DeliveryService ds)
+ {
+ return _connInfoMapByDs.get( ds );
+ }
+
+ public void removeConnectionStackInfo( ConnectionStackInfo info )
+ {
+ _connectionInfoMapByFilter.remove( info.getMessageFilter() );
+ _connInfoMapByDs.remove( info.getDeliveryService() );
+ }
+
+ public ApplicationInstallInfo getApplicationInstallInfo(String appName)
+ {
+ return _appMap.get( appName );
+ }
+
+ public Collection<PluginGroup> getPluginGroups()
+ {
+ return _pluginMap.values();
+ }
+
+ public PluginGroup getPluginGroup(String pluginGroupName)
+ {
+ return _pluginMap.get( pluginGroupName );
+ }
+
+ public PluginGroup getPluginGroup( Type method)
+ {
+ return _method2PluginMap.get(method);
+ }
+
+ public ApplicationConnectionInfo getAppConnectionInfoByAppClientStackInfo( ConnectionStackInfo appStackInfo )
+ {
+ return _appConnectionInfoMap.get( appStackInfo );
+ }
+
+ public ApplicationConnectionInfo getAppConnectionInfoByPluginServerStackInfo( ConnectionStackInfo pluginServerStackInfo )
+ {
+ return _pluginServerConn2AppConnMap.get( pluginServerStackInfo );
+ }
+
+ public void addAppConnectionInfo( ConnectionStackInfo pluginServerStackInfo, ApplicationConnectionInfo appConnInfo )
+ {
+ _pluginServerConn2AppConnMap.put( pluginServerStackInfo, appConnInfo );
+ }
+
+ public void removeAppConnectionInfo( ConnectionStackInfo pluginServerStackInfo )
+ {
+ _pluginServerConn2AppConnMap.remove( pluginServerStackInfo );
+ }
+
+ public DynamicValueFactory getValueFactory()
+ {
+ return _valueFactory;
+ }
+
+ public boolean isLocalMethodType( Type aType )
+ {
+ return _localMethodsMap.get( aType )!=null;
+ }
+
+ private ServerFactory _listener = null;
+
+ private PluginStateMonitor _pluginMon = null;
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void start() throws Exception
+ {
+ _LOGGER.log( Level.INFO, "Etch Router Manager starting up..." );
+ loadEtchRouterXmlBinding();
+ loadInstalledPlugins();
+ loadInstalledApplications();
+ _listener = EtchRouterManagerHelper.newListener( this, _url, null );
+ _listener.transportControl( Transport.START_AND_WAIT_UP, 4000 );
+ _pluginMon = new PluginStateMonitor( this );
+ Thread monThread = new Thread( _pluginMon );
+ _LOGGER.log( Level.INFO, "Starting plugin state monitor thread..." );
+ monThread.start();
+ _LOGGER.log( Level.INFO, "Etch Router Manager running..." );
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void stop() throws Exception
+ {
+ _LOGGER.log( Level.INFO, "Stopping Etch Router Manager..." );
+ _pluginMon.stop();
+ _listener.transportControl( Transport.STOP_AND_WAIT_DOWN, 4000 );
+ }
+
+ private void loadEtchRouterXmlBinding() throws Exception
+ {
+ File xmlFile = new File(_homeDir, "EtchRouter.xml");
+ _LOGGER.log( Level.FINE, "Loading EtchRouter XML binding file: {0}", xmlFile.getAbsolutePath() );
+ List<Type> loadedEnums = new ArrayList<Type>();
+ List<Type> loadedStructs = new ArrayList<Type>();
+ List<Type> loadedExceptions = new ArrayList<Type>();
+ List<Type> loadedMethods = new ArrayList<Type>();
+ XmlBindingData data = XmlBindingData.loadXmlBindingFile( xmlFile );
+ if (data.getExterns().size()>0)
+ throw new Exception("No \"extern\" statement is allowed in EctchRouter IDL!");
+ XmlBindingDataParser parser = new XmlBindingDataParser( data );
+ Collection<Type> myTypes = parser.getEnumTypes();
+ initImpExpHelpers( myTypes, parser );
+ loadedEnums.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getExceptionTypes();
+ initImpExpHelpers( myTypes, parser );
+ loadedExceptions.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getStructTypes();
+ initImpExpHelpers( myTypes, parser );
+ loadedStructs.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getMethodTypes();
+ loadedMethods.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ //only primitive types are supported in the EtchRouter APIs:
+ if (loadedMethods.isEmpty())
+ {
+ _LOGGER.log( Level.WARNING, "No method is loaded to the dynamic value factory from the EtchRouter XML binding file: {0}", xmlFile.getAbsolutePath() );
+ }
+ for (Type methodType : loadedMethods)
+ {
+ methodType.setStubHelper( _stubHelper );
+ _localMethodsMap.put( methodType, true );
+ if (_REGISTER_ROUTER_APP_METHOD_NAME.equals( methodType.getName() ) || methodType.getName().endsWith( "."+_REGISTER_ROUTER_APP_METHOD_NAME ))
+ _registerApplicationMethodType = methodType;
+ else if (_ROUTER_PLUGIN_SERVICE_STATE_CHANGE_METHOD_NAME.equals( methodType.getName() ) || methodType.getName().endsWith( "."+ _ROUTER_PLUGIN_SERVICE_STATE_CHANGE_METHOD_NAME ))
+ _pluginServiceStateChangeMethodType = methodType;
+ }
+ if (_registerApplicationMethodType==null)
+ throw new Exception(String.format( "Cannot find \"%s\" method definition in EtchRouter IDL", _REGISTER_ROUTER_APP_METHOD_NAME) );
+ if (_pluginServiceStateChangeMethodType==null)
+ throw new Exception( String.format( "Cannot find \"%s\" method definition in EtchRouter IDL", _ROUTER_PLUGIN_SERVICE_STATE_CHANGE_METHOD_NAME ) );
+ }
+
+ private void initImpExpHelpers(Collection<Type> types, XmlBindingDataParser parser)
+ {
+ for (Type myType : types)
+ {
+ LocalTypeImportExportHelper helper = parser.getLocalImportExportHelper( myType.getName() );
+ if (helper != null)
+ {
+ _valueFactory.addClass2TypeMap( helper.getTypeClass(), myType );
+ myType.setComponentType( helper.getTypeClass() );
+ myType.setImportExportHelper( helper );
+ }
+ else
+ {
+ StructValueImportExportHelper structHelper = parser.getStructValueImportExportHelper( myType.getName() );
+ if (structHelper!=null)
+ {
+ myType.setComponentType( StructValue.class );
+ myType.setImportExportHelper( structHelper );
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void loadInstalledPlugins() throws Exception
+ {
+ String preloadPlugins = _properties.getProperty( "preload.plugins", "true" );
+ if (!"true".equalsIgnoreCase( preloadPlugins ))
+ {
+ _LOGGER.log( Level.FINE, "Plugin install info will be lazily loaded with plugin registration" );
+ return;
+ }
+ _LOGGER.log( Level.FINE, "Pre-loading all Plugins' install info from directory \"{0}\"...", _pluginsRoot.getAbsolutePath() );
+ File[] subFiles = _pluginsRoot.listFiles();
+ for (File subFile : subFiles)
+ {
+ if (subFile.isDirectory())
+ loadPluginInstallInfo(null, subFile);
+
+ }
+ }
+
+ /**
+ *
+ * @throws Exception
+ */
+ public void loadInstalledApplications() throws Exception
+ {
+ String preloadApps = _properties.getProperty( "preload.applications", "true" );
+ if (!"true".equalsIgnoreCase( preloadApps ))
+ {
+ _LOGGER.log( Level.FINE, "Application install info will be lazily loaded with application registration" );
+ return;
+ }
+ _LOGGER.log( Level.FINE, "Pre-loading all Applications' install info from directory \"{0}\"...", _appsRoot.getAbsolutePath() );
+ File[] subFiles = _appsRoot.listFiles();
+ for (File subFile : subFiles)
+ {
+ if (subFile.isDirectory())
+ loadApplicationInstallInfo(null, subFile);
+
+ }
+ }
+
+ /**
+ *
+ * @param pluginName
+ * @return
+ * @throws Exception
+ */
+ public PluginGroup loadPluginInstallInfo(String pluginName) throws Exception
+ {
+ PluginGroup pluginGrp = getPluginGroup(pluginName);
+ if (pluginGrp!=null)
+ {
+ _LOGGER.log( Level.FINER, "The plugin group info for \"{0}\" is already loaded to Etch Router manager", pluginName );
+ return pluginGrp;
+ }
+ File pluginDir = new File(_pluginsRoot, pluginName);
+ if ((!pluginDir.exists()) || (!pluginDir.isDirectory()))
+ throw new Exception(String.format( "The plugin directory does not exist: %s", pluginDir.getAbsolutePath()));
+ loadPluginInstallInfo(pluginName, pluginDir);
+ return getPluginGroup(pluginName);
+ }
+
+ private void loadPluginInstallInfo(String pluginName, File pluginDir) throws Exception
+ {
+ if (pluginName==null) pluginName = pluginDir.getName();
+ _LOGGER.log( Level.FINE, "Loading Plugin install info \"{0}\" from directory \"{1}\" ", new Object[]{ pluginName, pluginDir.getAbsolutePath() } );
+ File[] subFiles = pluginDir.listFiles();
+ List<File> xmlFiles = new ArrayList<File>(subFiles.length);
+ File metaFile = null;
+ for (File subFile : subFiles)
+ {
+ String lowName = subFile.getName().toLowerCase();
+ if (lowName.endsWith( ".xml" ))
+ xmlFiles.add( subFile );
+ else if (lowName.equals( "metadata.txt" ))
+ metaFile = subFile;
+ }
+ if (xmlFiles.size()==0)
+ throw new Exception(String.format( "The plugin directory does not contain any xml binding file: %s", pluginDir.getAbsolutePath()));
+ Properties metaProp = readMetaDataFile(metaFile);
+ PluginInstallInfo info = new PluginInstallInfo(pluginName, metaProp);
+ PluginGroup pluginGrp = PluginGroup.newPluginGroup( pluginName, this, info );
+ _LOGGER.log( Level.FINE, "Plugin group name: \"{0}\", type: \"{1}\"", new Object[]{ pluginName, pluginGrp.getClass().getName() } );
+ loadPluginXmlFiles(xmlFiles, pluginGrp);
+ if (_pluginMap.get( pluginName )==null)
+ _pluginMap.put( pluginName, pluginGrp );
+ }
+
+ private Properties readMetaDataFile(File metaDataFile) throws Exception
+ {
+ Properties prop = new Properties();
+ if (metaDataFile==null) return prop;
+ prop.load( new FileInputStream(metaDataFile) );
+ return prop;
+ }
+
+ private void loadPluginXmlFiles(List<File> xmlFiles, PluginGroup pluginGroup) throws Exception
+ {
+ List<Type> allEnums = new ArrayList<Type>();
+ List<Type> allStructs = new ArrayList<Type>();
+ List<Type> allExceptions = new ArrayList<Type>();
+ List<Type> allMethods = new ArrayList<Type>();
+ List<Type> allExterns = new ArrayList<Type>();
+ XmlBindingDataParser parser = null;
+ for (File xmlBindingFile : xmlFiles)
+ {
+ XmlBindingData data = XmlBindingData.loadXmlBindingFile( xmlBindingFile );
+ parser = new XmlBindingDataParser( data );
+ Collection<Type> myTypes = parser.getEnumTypes();
+ allEnums.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getExceptionTypes();
+ allExceptions.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getStructTypes();
+ allStructs.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getExternTypes();
+ allExterns.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ myTypes = parser.getMethodTypes();
+ allMethods.addAll( _valueFactory.addTypeDefinitions( myTypes ) );
+ }
+ initImpExpHelpers( allEnums, parser );
+ initImpExpHelpers( allExceptions, parser );
+ initImpExpHelpers( allStructs, parser );
+ initImpExpHelpers( allExterns, parser );
+ if (allMethods.isEmpty())
+ {
+ _LOGGER.log( Level.WARNING, "No method is loaded to the dynamic value factory from the plugin directory: {0}", xmlFiles.get( 0 ).getCanonicalFile().getParent() );
+ }
+ for (Type methodType : allMethods)
+ {
+ pluginGroup.getInstallInfo().addMethod( methodType );
+ methodType.setStubHelper( _stubHelper );
+ if (methodType.getDirection()!=Direction.CLIENT)
+ _method2PluginMap.put( methodType, pluginGroup );
+ }
+ }
+
+ /**
+ *
+ * @param applicationName
+ * @return
+ * @throws Exception
+ */
+ public ApplicationInstallInfo loadApplicationInstallInfo(String applicationName) throws Exception
+ {
+ ApplicationInstallInfo appInfo = getApplicationInstallInfo( applicationName );
+ if (appInfo!=null)
+ {
+ _LOGGER.log( Level.FINER, "The application install info for \"{0}\" is already loaded to Etch Router manager", applicationName );
+ return appInfo;
+ }
+ File appDir = new File(_appsRoot, applicationName);
+ if ((!appDir.exists()) || (!appDir.isDirectory()))
+ throw new Exception(String.format( "The application directory does not exist: %s", appDir.getAbsolutePath()));
+ loadApplicationInstallInfo(applicationName, appDir);
+ return getApplicationInstallInfo( applicationName );
+ }
+
+ private void loadApplicationInstallInfo(String applicationName, File appDir) throws Exception
+ {
+ if (applicationName==null) applicationName = appDir.getName();
+ _LOGGER.log( Level.FINE, "Loading Application install info \"{0}\" from directory \"{1}\"", new Object[]{ applicationName, appDir.getAbsolutePath() } );
+ File[] subFiles = appDir.listFiles();
+ List<File> xmlFiles = new ArrayList<File>(subFiles.length);
+ for (File subFile : subFiles)
+ {
+ if (subFile.getName().toLowerCase().endsWith( ".xml" ))
+ xmlFiles.add( subFile );
+ }
+ if (xmlFiles.size()==0)
+ throw new Exception(String.format( "The application directory does not contain any xml binding file: %s", appDir.getAbsolutePath()));
+ ApplicationInstallInfo info = new ApplicationInstallInfo(applicationName);
+ loadApplicationXmlFiles(xmlFiles, info);
+ if (_appMap.get( applicationName )==null)
+ _appMap.put( applicationName, info );
+ }
+
+ private void loadApplicationXmlFiles(List<File> xmlFiles, ApplicationInstallInfo appInfo) throws Exception
+ {
+ String appName = appInfo.getName();
+ List<Type> allMethods = new ArrayList<Type>();
+ XmlBindingDataParser parser = null;
+ for (File xmlBindingFile : xmlFiles)
+ {
+ XmlBindingData data = XmlBindingData.loadXmlBindingFile( xmlBindingFile );
+ parser = new XmlBindingDataParser( data);
+ checkApplicationTypeDefinitions(parser.getEnumTypes(), xmlBindingFile, appName, "Enum");
+ checkApplicationTypeDefinitions(parser.getExceptionTypes(), xmlBindingFile, appName, "Exception");
+ checkApplicationTypeDefinitions(parser.getStructTypes(), xmlBindingFile, appName, "Struct");
+ List<Type> methods = parser.getMethodTypes();
+ allMethods.addAll(methods);
+ checkApplicationTypeDefinitions(methods, xmlBindingFile, appName, "Method");
+ }
+ if (allMethods.isEmpty())
+ {
+ _LOGGER.log( Level.WARNING, "No method is found in the application directory: {0}", xmlFiles.get( 0 ).getCanonicalFile().getParent() );
+ }
+ for (Type methodType : allMethods)
+ {
+ appInfo.addMethod( methodType );
+ }
+ }
+
+ private void checkApplicationTypeDefinitions(Collection<Type> types, File xmlFile, String appName, String typeType)
+ {
+ for (Type aType : types)
+ {
+ Type typeFound = _valueFactory.getType( aType.getId() );
+ if (typeFound==null)
+ {
+ _LOGGER.log( Level.WARNING, "The \"{0}\" type \"{1}\" in file \"{2}\" for application \"{3}\" is not defined in DynamicValueFactory.",
+ new Object[]{ typeType, aType.getName(), xmlFile.getAbsolutePath(), appName } );
+ }
+ }
+ }
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManager.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,116 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import org.apache.etch.bindings.java.msg.ValueFactory;
+import org.apache.etch.bindings.java.support.DefaultServerFactory;
+import org.apache.etch.bindings.java.support.DeliveryService;
+import org.apache.etch.bindings.java.support.Pool;
+import org.apache.etch.bindings.java.support.ServerFactory;
+import org.apache.etch.bindings.java.support.TransportHelper;
+import org.apache.etch.bindings.java.transport.DefaultDeliveryService;
+import org.apache.etch.bindings.java.transport.MailboxManager;
+import org.apache.etch.bindings.java.transport.PlainMailboxManager;
+import org.apache.etch.bindings.java.transport.TransportMessage;
+import org.apache.etch.services.router.ConnectionStackInfo.ConnectionType;
+import org.apache.etch.util.Resources;
+import org.apache.etch.util.core.io.Transport;
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class EtchRouterManagerHelper extends TransportHelper
+{
+
+ /**
+ *
+ * @param routerMgr
+ * @param uri
+ * @param resources
+ * @param implFactory
+ * @return
+ * @throws Exception
+ */
+ public static ServerFactory newListener( final EtchRouterManager routerMgr, final String uri,
+ Resources resources )
+ throws Exception
+ {
+ final Resources res = initResources( resources );
+ res.put( EtchRouterManager._ETCH_ROUTER_MANAGER, routerMgr );
+
+ final Transport<ServerFactory> listener = EtchRouterMgrTransportFactory.getListener( uri, res );
+
+ return new DefaultServerFactory( listener, routerMgr )
+ {
+ public void newServer( String uri, Resources resources,
+ TransportMessage transport ) throws Exception
+ {
+ ValueFactory vf = (ValueFactory) resources.get( Transport.VALUE_FACTORY );
+ MailboxManager x = new PlainMailboxManager( transport, uri, res );
+ DeliveryService d = new DefaultDeliveryService( x, uri, res );
+ ConnectionStackInfo info = routerMgr.getConnectionStackInfo( d );
+ ERRemoteClient client = new ERRemoteClient( d, vf, routerMgr, info );
+ ImplServer server = new ImplServer( client, routerMgr );
+ Pool qp = (Pool) res.get( QUEUED_POOL );
+ Pool fp = (Pool) res.get( FREE_POOL );
+ new ERStub( d, server, qp, fp );
+ client._start();
+ }
+
+ public ValueFactory newValueFactory()
+ {
+ return new DynamicValueFactory( uri );
+ }
+
+ @Override
+ public String toString()
+ {
+ return "PerfHelper.ServerFactory/" + listener;
+ }
+ };
+ }
+
+ /**
+ * Create a connection to an Etch plug-in server listener
+ *
+ * @param etchRouterManager
+ * @param uri
+ * @param resources
+ * @return
+ * @throws Exception
+ */
+ public static ERRemoteServer newServer( EtchRouterManager etchRouterManager, String uri,
+ Resources resources, String pluginName) throws Exception
+ {
+ final Resources res = initResources( resources );
+ final DynamicValueFactory vf = etchRouterManager.getValueFactory();
+ res.put( Transport.VALUE_FACTORY, vf );
+ res.put( EtchRouterManager._ETCH_ROUTER_MANAGER, etchRouterManager );
+
+ DeliveryService d = EtchRouterMgrTransportFactory.getTransport( uri, res );
+ ConnectionStackInfo info = etchRouterManager.getConnectionStackInfo( d );
+ info.setConnectionType( ConnectionType.PLUGIN_SERVER_CONN, pluginName );
+ ERRemoteServer server = new ERRemoteServer( d, vf, etchRouterManager, info );
+ ImplClient client = new ImplClient( server, etchRouterManager );
+ Pool qp = (Pool) res.get( QUEUED_POOL );
+ Pool fp = (Pool) res.get( FREE_POOL );
+ new ERStub( d, client, qp, fp );
+ return server;
+ }
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterManagerHelper.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,238 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.etch.bindings.java.msg.Direction;
+import org.apache.etch.bindings.java.msg.Message;
+import org.apache.etch.bindings.java.msg.Type;
+import org.apache.etch.bindings.java.transport.SessionMessage;
+import org.apache.etch.bindings.java.transport.TransportMessage;
+import org.apache.etch.services.router.ConnectionStackInfo.ConnectionType;
+import org.apache.etch.services.router.EtchRouter.EtchRouterException;
+import org.apache.etch.services.router.plugin.PluginGroup;
+import org.apache.etch.services.router.plugin.PluginMemberConnection;
+import org.apache.etch.util.Resources;
+import org.apache.etch.util.URL;
+import org.apache.etch.util.core.Who;
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class EtchRouterMessageFilter implements TransportMessage,
+ SessionMessage
+{
+
+ private static final Logger _LOGGER = Logger.getLogger( EtchRouterMessageFilter.class.getName());
+
+ private EtchRouterManager _etchRouterManager = null;
+
+ private final TransportMessage _transport;
+
+ private SessionMessage _session = null;
+
+ /**
+ *
+ * @param transport
+ * @param uri
+ * @param resources
+ */
+ public EtchRouterMessageFilter( TransportMessage transport, URL uri,
+ Resources resources )
+ {
+ this._transport = transport;
+ _etchRouterManager = (EtchRouterManager)resources.get( EtchRouterManager._ETCH_ROUTER_MANAGER );
+ transport.setSession( this );
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format( "EtchRouterMessageFilter/%s", _transport);
+ }
+
+ public void transportMessage( Who recipient, Message msg ) throws Exception
+ {
+ _transport.transportMessage( recipient, msg );
+ }
+
+ public SessionMessage getSession()
+ {
+ return _session;
+ }
+
+ public void setSession( SessionMessage session )
+ {
+ _session = session;
+ }
+
+ public void transportControl( Object control, Object value )
+ throws Exception
+ {
+ _transport.transportControl( control, value );
+ }
+
+ public void transportNotify( Object event ) throws Exception
+ {
+ _transport.transportNotify( event );
+ }
+
+ public Object transportQuery( Object query ) throws Exception
+ {
+ return _transport.transportQuery( query );
+ }
+
+ public boolean sessionMessage( Who sender, Message msg ) throws Exception
+ {
+ ConnectionStackInfo connStackInfo = _etchRouterManager.getConnectionStackInfo( this );
+ if (connStackInfo==null)
+ {
+ _LOGGER.log( Level.SEVERE, "No connection stack info is saved with EtchRouter manager for {0}", this );
+ return false;
+ }
+ Type methodType = msg.type();
+ ConnectionType connType = connStackInfo.getConnectionType();
+ if (_etchRouterManager.isLocalMethodType( methodType ))
+ {
+ Long msgid = msg.getInReplyTo();
+ // the upper level mailbox manager will handle this message if
+ // it's a reply message
+ if (msgid == null)
+ {
+ _etchRouterManager.handleLocalMethodMessage( sender, connStackInfo, msg );
+ }
+ }
+ else if( connType==ConnectionType.APP_CLIENT_CONN )
+ {
+ try
+ {
+ handleMessageFromAppClientConnection( sender, msg, connStackInfo, methodType );
+ }
+ catch (Exception e)
+ {
+ returnException( sender, msg, e, connStackInfo);
+ }
+ }
+ else if ( connType==ConnectionType.PLUGIN_SERVER_CONN )
+ {
+ //from plugin-server -> app-client:
+ ApplicationConnectionInfo appConnInfo = _etchRouterManager.getAppConnectionInfoByPluginServerStackInfo( connStackInfo );
+ ConnectionStackInfo appClientStackInfo = appConnInfo.getApplicationClientConnectionStackInfo();
+ appClientStackInfo.getMessageFilter().transportMessage( sender, msg );
+ }
+ else if ( connType==null && methodType.getDirection()!=Direction.CLIENT)
+ {
+ try
+ {
+ _etchRouterManager.registerAnonymousApplication( connStackInfo, methodType );
+ handleMessageFromAppClientConnection( sender, msg, connStackInfo, methodType );
+ }
+ catch (Exception e)
+ {
+ returnException( sender, msg, e, connStackInfo);
+ }
+ }
+ return _session.sessionMessage( sender, msg );
+ }
+
+ private void returnException( Who sender, Message origMsg, Exception e, ConnectionStackInfo connStackInfo)
+ {
+ Type methodType = origMsg.type();
+ _LOGGER.log( Level.INFO, "Got Exception, original message type is "+methodType.getName()+": ", e);
+ Message rmsg = (methodType.getResult()==null) ? null : origMsg.reply();
+ if (rmsg==null) return;
+ if (!(e instanceof RuntimeException)) e = new RuntimeException( e );
+ rmsg.put( DynamicValueFactory._mf_result, e);
+ try
+ {
+ connStackInfo.getDeliveryService().transportMessage( sender, rmsg );
+ }
+ catch (Exception ee)
+ {
+ _LOGGER.log( Level.SEVERE, "Got Exception: ", ee);
+ }
+ }
+
+
+ private void handleMessageFromAppClientConnection(Who sender, Message msg, ConnectionStackInfo connStackInfo, Type methodType ) throws Exception
+ {
+ //from app-client -> plugin:
+ ApplicationConnectionInfo appConnInfo = _etchRouterManager.getAppConnectionInfoByAppClientStackInfo( connStackInfo );
+ // make sure the type info for this method is loaded with the app connection:
+ try
+ {
+ appConnInfo.loadPluginGroupByMethodType( methodType );
+ }
+ catch (Exception e)
+ {
+ // ignore this exception for we don't care whether it's a server direction'ed message
+ }
+ PluginMemberConnection pluginConn = appConnInfo.getPluginConnectionByMethod( methodType );
+ if (pluginConn==null)
+ {
+ PluginGroup pluginGrp = _etchRouterManager.getPluginGroup( methodType );
+ if (pluginGrp!=null)
+ {
+ //No plugin connection is available for this API call:
+ throw new EtchRouterException(1, String.format( "Cannot call API '%s' because the plugin connection is not established", methodType.getName() ));
+ }
+ else
+ {
+ _LOGGER.log( Level.INFO, "Not handled message from client connection: {0}", msg );
+ }
+ }
+ else
+ {
+ ERRemoteServer remoteServer = pluginConn.getRemoteServer();
+ ConnectionStackInfo serverStackInfo = remoteServer.getConnectionStackInfo();
+ serverStackInfo.getMessageFilter().transportMessage( sender, msg );
+ }
+ }
+
+ public void sessionControl( Object control, Object value ) throws Exception
+ {
+ _session.sessionControl( control, value );
+ }
+
+ public void sessionNotify( Object event ) throws Exception
+ {
+ if (event instanceof Exception)
+ {
+ _LOGGER.log( Level.FINER, "Got an exception in sessionNotify", (Exception)event);
+ }
+ _session.sessionNotify( event );
+ ConnectionStackInfo connStackInfo = _etchRouterManager.getConnectionStackInfo( this );
+ if (connStackInfo==null)
+ {
+ _LOGGER.log( Level.SEVERE, "No connection stack info is saved with EtchRouter manager for {0}", this );
+ }
+ else
+ {
+ _etchRouterManager.sessionNotify( event, connStackInfo );
+ }
+ }
+
+ public Object sessionQuery( Object query ) throws Exception
+ {
+ return _session.sessionQuery( query );
+ }
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMessageFilter.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,243 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import java.net.Socket;
+
+import javax.net.ssl.SSLSocket;
+
+import org.apache.etch.bindings.java.msg.ValueFactory;
+import org.apache.etch.bindings.java.support.DeliveryService;
+import org.apache.etch.bindings.java.support.ServerFactory;
+import org.apache.etch.bindings.java.transport.DefaultDeliveryService;
+import org.apache.etch.bindings.java.transport.MailboxManager;
+import org.apache.etch.bindings.java.transport.Messagizer;
+import org.apache.etch.bindings.java.transport.PlainMailboxManager;
+import org.apache.etch.bindings.java.transport.TcpTransportFactory;
+import org.apache.etch.bindings.java.transport.TransportMessage;
+import org.apache.etch.util.Resources;
+import org.apache.etch.util.URL;
+import org.apache.etch.util.core.io.Packetizer;
+import org.apache.etch.util.core.io.SessionListener;
+import org.apache.etch.util.core.io.TcpConnection;
+import org.apache.etch.util.core.io.TcpListener;
+import org.apache.etch.util.core.io.TlsConnection;
+import org.apache.etch.util.core.io.TlsListener;
+import org.apache.etch.util.core.io.Transport;
+import org.apache.etch.util.core.io.TransportData;
+import org.apache.etch.util.core.io.TransportPacket;
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class EtchRouterMgrTransportFactory extends TcpTransportFactory
+{
+
+ private static EtchRouterMgrTransportFactory _tcpTransportFactory = new EtchRouterMgrTransportFactory(false);
+
+ private static EtchRouterMgrTransportFactory _tlsTransportFactory = new EtchRouterMgrTransportFactory(true);
+
+ private static EtchRouterMgrTransportFactory getFactoryByScheme( String scheme, String uri ) throws Exception
+ {
+ EtchRouterMgrTransportFactory f = null;
+ if ("tcp".equalsIgnoreCase( scheme ))
+ f = _tcpTransportFactory;
+ else if ("tls".equalsIgnoreCase( scheme ))
+ f = _tlsTransportFactory;
+ else
+ throw new Exception("No transport factory found for URL " + uri);
+ return f;
+ }
+
+ // TODO these methods should not be here. they come from Transport.
+ static public DeliveryService getTransport( String uri,
+ Resources resources ) throws Exception
+ {
+ URL u = new URL( uri );
+ EtchRouterMgrTransportFactory f = getFactoryByScheme( u.getScheme(), uri );
+ return f.newTransport( uri, resources );
+ }
+
+ // TODO these methods should not be here. they come from Transport.
+ static public Transport<ServerFactory> getListener( String uri,
+ Resources resources ) throws Exception
+ {
+ URL u = new URL( uri );
+ EtchRouterMgrTransportFactory f = getFactoryByScheme( u.getScheme(), uri );
+ return f.newListener( uri, resources );
+ }
+
+ /**
+ * Constructs a TcpTransportFactory which delivers TcpConnection.
+ */
+ public EtchRouterMgrTransportFactory()
+ {
+ this( false );
+ }
+
+ /**
+ * Constructs a TcpTransportFactory which delivers TcpConnection or a
+ * TlsConnection depending upon the isSecure parameter.
+ * @param isSecure true if TlsConnection is desired, false otherwise.
+ */
+ public EtchRouterMgrTransportFactory( boolean isSecure )
+ {
+ super(isSecure);
+ _isSecure = isSecure;
+ }
+
+ private final static String _SOCKET = "TcpTransportFactory.socket";
+
+ private boolean _isSecure = false;
+
+ @Override
+ public DeliveryService newTransport( String uri, Resources resources ) throws Exception
+ {
+ EtchRouterManager etchRouterManager = (EtchRouterManager)resources.get( EtchRouterManager._ETCH_ROUTER_MANAGER );
+
+ URL u = new URL( uri );
+
+ Object socket = resources.get( _SOCKET );
+
+ TransportData c = null;
+
+ if (_isSecure)
+ c = new TlsConnection( (SSLSocket) socket, u, resources );
+ else
+ c = new TcpConnection( (Socket) socket, u, resources );
+
+ TransportPacket p = new Packetizer( c, u, resources );
+
+ Messagizer msg = new Messagizer( p, u, resources );
+
+ TransportMessage m = addFilters( msg, u, resources );
+
+ EtchRouterMessageFilter messageFilter = new EtchRouterMessageFilter(m, u, resources);
+
+ MailboxManager r = new PlainMailboxManager( messageFilter, u, resources );
+
+ DeliveryService d = new DefaultDeliveryService( r, u, resources );
+
+ ValueFactory vf = (ValueFactory) resources.get( Transport.VALUE_FACTORY );
+
+ ConnectionStackInfo connInfo = new ConnectionStackInfo( messageFilter, r, d, vf );
+
+ etchRouterManager.addConnectionStackInfo( connInfo );
+
+ return d;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Transport<ServerFactory> newListener( final String uri, final Resources resources )
+ throws Exception
+ {
+ URL u = new URL( uri );
+
+ Transport<SessionListener<Socket>> l;
+
+ if (_isSecure)
+ l = new TlsListener( u, resources );
+ else
+ l = new TcpListener( u, resources );
+
+ return new MySessionListener( l, uri, resources );
+ }
+
+ private class MySessionListener implements Transport<ServerFactory>, SessionListener<Socket>
+ {
+ /**
+ * @param transport
+ * @param uri
+ * @param resources
+ */
+ public MySessionListener( Transport<SessionListener<Socket>> transport, String uri, Resources resources )
+ {
+ this.transport = transport;
+ this.uri = uri;
+ this.resources = resources;
+
+ transport.setSession( this );
+ }
+
+ private final Transport<SessionListener<Socket>> transport;
+
+ private final String uri;
+
+ private final Resources resources;
+
+ public ServerFactory getSession()
+ {
+ return session;
+ }
+
+ public void setSession( ServerFactory session )
+ {
+ this.session = session;
+ }
+
+ private ServerFactory session;
+
+ public Object transportQuery( Object query ) throws Exception
+ {
+ return transport.transportQuery( query );
+ }
+
+ public void transportControl( Object control, Object value )
+ throws Exception
+ {
+ transport.transportControl( control, value );
+ }
+
+ public void transportNotify( Object event ) throws Exception
+ {
+ transport.transportNotify( event );
+ }
+
+ public void sessionAccepted( Socket socket ) throws Exception
+ {
+ Resources r = new Resources( resources );
+ r.put( _SOCKET, socket );
+
+ ValueFactory vf = session.newValueFactory();
+ r.put( Transport.VALUE_FACTORY, vf );
+
+ TransportMessage t = newTransport( uri, r );
+
+ session.newServer( uri, r, t );
+ }
+
+ public Object sessionQuery( Object query ) throws Exception
+ {
+ return session.sessionQuery( query );
+ }
+
+ public void sessionControl( Object control, Object value )
+ throws Exception
+ {
+ session.sessionControl( control, value );
+ }
+
+ public void sessionNotify( Object event ) throws Exception
+ {
+ session.sessionNotify( event );
+ }
+ }
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/EtchRouterMgrTransportFactory.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,32 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+public class ImplBase
+{
+ private EtchRouterManager _etchRouterManager = null;
+
+ public ImplBase( EtchRouterManager etchRouterManager )
+ {
+ etchRouterManager = _etchRouterManager;
+ }
+
+ public EtchRouterManager getEtchRouterManager()
+ {
+ return _etchRouterManager;
+ }
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplBase.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,51 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import org.apache.etch.bindings.java.support.ObjSession;
+
+public class ImplClient extends ImplBase implements ObjSession
+{
+ private ERRemoteServer _server = null;
+
+ public ImplClient(ERRemoteServer server, EtchRouterManager etchRouterManager)
+ {
+ super(etchRouterManager);
+ _server = server;
+ }
+
+ public void _sessionControl( Object control, Object value )
+ throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void _sessionNotify( Object event ) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Object _sessionQuery( Object query ) throws Exception
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplClient.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,61 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import org.apache.etch.bindings.java.support.ObjSession;
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class ImplServer extends ImplBase implements ObjSession
+{
+
+ private ERRemoteClient _client = null;
+
+ /**
+ *
+ * @param client
+ */
+ public ImplServer(ERRemoteClient client, EtchRouterManager etchRouterManager)
+ {
+ super(etchRouterManager);
+ _client = client;
+ }
+
+ public void _sessionControl( Object control, Object value )
+ throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void _sessionNotify( Object event ) throws Exception
+ {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Object _sessionQuery( Object query ) throws Exception
+ {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/ImplServer.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,115 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.etch.bindings.java.msg.Type;
+
+/**
+ * Class
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class PluginInstallInfo
+{
+ private Properties _metaProperties = null;
+
+ private String _name = null;
+
+ private Map<String, Type> _methodMapByName = null;
+
+ private Map<Integer, Type> _methodMapById = null;
+
+ /**
+ * Constructor
+ *
+ * @param name
+ */
+ public PluginInstallInfo(String name, Properties metaProperties)
+ {
+ _metaProperties = metaProperties;
+ _name = name;
+ _methodMapByName = new HashMap<String, Type>();
+ _methodMapById = new HashMap<Integer, Type>();
+ }
+
+ public void addMethod(Type method)
+ {
+ if (method==null) return;
+ _methodMapByName.put( method.getName(), method );
+ _methodMapById.put( method.getId(), method );
+ }
+
+ public Type getMethod(String name)
+ {
+ return _methodMapByName.get( name );
+ }
+
+ public Type getMethod(Integer id)
+ {
+ return _methodMapById.get( id );
+ }
+
+ public Collection<Type> getMethods()
+ {
+ return _methodMapById.values();
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String getMetaProperty( String key )
+ {
+ return _metaProperties.getProperty( key );
+ }
+
+ public String getMetaProperty( String key, String defValue )
+ {
+ return _metaProperties.getProperty( key, defValue );
+ }
+
+ /**
+ *
+ * @param prefix
+ * @return
+ */
+ public String[] getSortedMetaPropertyKeysWithPrefix( String prefix )
+ {
+ Set<Object> keySet = _metaProperties.keySet();
+ List<String> keyList = new ArrayList<String>();
+ for (Object key : keySet)
+ {
+ if (key.toString().startsWith( prefix ))
+ keyList.add( key.toString() );
+ }
+ String[] arr = new String[keyList.size()];
+ arr = keyList.toArray( arr );
+ Arrays.sort( arr );
+ return arr;
+ }
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/PluginInstallInfo.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,79 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.etch.services.router.ConnectionStackInfo;
+import org.apache.etch.services.router.EtchRouterManager;
+import org.apache.etch.services.router.PluginInstallInfo;
+import org.apache.etch.services.router.EtchRouter.EtchRouterException;
+import org.apache.etch.services.router.utils.ApplicationAttributes;
+
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class FailoverPluginGroup extends PluginGroup
+{
+
+ private List<PluginMember> _primaryMembers = new ArrayList<PluginMember>();
+ /**
+ *
+ * @param name
+ * @param routerMgr
+ * @param installInfo
+ */
+ public FailoverPluginGroup( String name, EtchRouterManager routerMgr, PluginInstallInfo installInfo)
+ {
+ super( name, routerMgr, installInfo);
+ }
+
+ @Override
+ public synchronized PluginMember getActiveMember(
+ ApplicationAttributes appAttrs ) throws EtchRouterException
+ {
+ for (PluginMember aMember : _primaryMembers)
+ {
+ if (aMember.isActive() && aMember.getMetaAttributes().matches( appAttrs ))
+ return aMember;
+ }
+ PluginMember member = super.getActiveMember( appAttrs );
+ _primaryMembers.add( member );
+ return member;
+ }
+
+ @Override
+ public synchronized void onPluginMemberConnectionDown( ConnectionStackInfo connInfo )
+ throws EtchRouterException
+ {
+ super.onPluginMemberConnectionDown( connInfo );
+ for (PluginMember member : _primaryMembers)
+ {
+ if (connInfo==member.getConnInfo())
+ {
+ _primaryMembers.remove( member );
+ return;
+ }
+ }
+ }
+
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/FailoverPluginGroup.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,204 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router.plugin;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.etch.services.router.ApplicationConnectionInfo;
+import org.apache.etch.services.router.ConnectionStackInfo;
+import org.apache.etch.services.router.EtchRouterManager;
+import org.apache.etch.services.router.PluginInstallInfo;
+import org.apache.etch.services.router.EtchRouter.EtchRouterException;
+import org.apache.etch.services.router.utils.ApplicationAttributes;
+import org.apache.etch.services.router.utils.PluginAttributes;
+
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public abstract class PluginGroup
+{
+ /**
+ *
+ */
+ public static final String _URL_PROPERTY_KEY_PREFIX = "plugin.member.url.";
+
+ /**
+ *
+ */
+ public static final String _META_DATA_PROPERTY_KEY_PREFIX = "plugin.member.metadata.";
+
+ /**
+ * Factory method to new a PluginGroup of a particular type
+ *
+ * @param name
+ * @param routerMgr
+ * @param installInfo
+ * @return
+ */
+ public static PluginGroup newPluginGroup( String name, EtchRouterManager routerMgr, PluginInstallInfo installInfo)
+ {
+ String groupType = installInfo.getMetaProperty( "plugin.group.type" );
+ PluginGroup group = null;
+ if ("roundrobin".equalsIgnoreCase( groupType ))
+ {
+ group = new RoundRobinPluginGroup(name, routerMgr, installInfo);
+ }
+ if (group==null)
+ group = new FailoverPluginGroup(name, routerMgr, installInfo);
+ return group;
+ }
+
+ protected String _name = null;
+
+ protected List<PluginMember> _pluginMembers = null;
+
+ protected PluginInstallInfo _installInfo = null;
+
+ protected EtchRouterManager _etchRouterManager = null;
+
+ protected List<ApplicationConnectionInfo> _appConnections = null;
+
+ protected PluginGroup(String name, EtchRouterManager routerMgr, PluginInstallInfo installInfo)
+ {
+ _name = name;
+ _pluginMembers = new ArrayList<PluginMember>();
+ _etchRouterManager = routerMgr;
+ _installInfo = installInfo;
+ _appConnections = new ArrayList<ApplicationConnectionInfo>();
+ populatePluginMembers();
+ }
+
+ private void populatePluginMembers()
+ {
+ String[] urlKeys = _installInfo.getSortedMetaPropertyKeysWithPrefix( _URL_PROPERTY_KEY_PREFIX );
+ for (String key : urlKeys)
+ {
+ String url = _installInfo.getMetaProperty( key );
+ String suffix = key.substring( _URL_PROPERTY_KEY_PREFIX.length() );
+ String metaData = _installInfo.getMetaProperty( String.format( "%s%s", _META_DATA_PROPERTY_KEY_PREFIX, suffix ) );
+ PluginMember member = new PluginMember(this, url, metaData);
+ _pluginMembers.add( member );
+ }
+ }
+
+ /**
+ * Getter
+ *
+ * @return
+ */
+ public String getName()
+ {
+ return _name;
+ }
+
+ /**
+ *
+ * @return
+ * @throws EtchRouterException
+ */
+ public synchronized PluginMember getActiveMember( ApplicationAttributes appAttrs ) throws EtchRouterException
+ {
+ if (_pluginMembers.isEmpty())
+ throw new EtchRouterException(1, String.format( "No member is registered in plugin group '%s'", getName()));
+ for (PluginMember member : _pluginMembers)
+ {
+ if (member.isActive() && member.getMetaAttributes().matches( appAttrs ))
+ return member;
+ }
+ throw new EtchRouterException(1, String.format( "No active member is found in plugin group '%s' that matches application attributes \"%s\"", getName(), appAttrs.getEncodedString()));
+ }
+
+ /**
+ *
+ * @param appConnection
+ */
+ public synchronized void addApplicationConnection( ApplicationConnectionInfo appConnection )
+ {
+ _appConnections.add( appConnection );
+ }
+
+ /**
+ *
+ */
+ public void refreshAppConnections()
+ {
+ for (ApplicationConnectionInfo appConnection : _appConnections)
+ {
+ appConnection.initPluginConnectionIfNotConnected( this );
+ }
+ }
+
+ /**
+ *
+ * @param appConnection
+ */
+ public synchronized void removeApplicationConnection( ApplicationConnectionInfo appConnection )
+ {
+ _appConnections.remove( appConnection );
+ }
+
+ /**
+ *
+ * @param connInfo
+ * @throws EtchRouterException
+ */
+ public void onPluginMemberConnectionDown( ConnectionStackInfo connInfo ) throws EtchRouterException
+ {
+ if (connInfo==null) return;
+ for (PluginMember member : _pluginMembers)
+ {
+ if (connInfo==member.getConnInfo())
+ {
+ member.onRemoteConnectionDown( );
+ }
+ }
+ }
+
+ /**
+ *
+ * @return
+ */
+ public PluginInstallInfo getInstallInfo()
+ {
+ return _installInfo;
+ }
+
+ public List<PluginMember> getPluginMembers()
+ {
+ List<PluginMember> list = new ArrayList<PluginMember>();
+ list.addAll( _pluginMembers );
+ return list;
+ }
+
+ protected List<PluginMember> getActivePluginMembers( ApplicationAttributes appAttrs )
+ {
+ List<PluginMember> list = new ArrayList<PluginMember>(_pluginMembers.size());
+ for (PluginMember member : _pluginMembers)
+ {
+ if (member.isActive()) {
+ PluginAttributes pluginAttrs = member.getMetaAttributes();
+ if (pluginAttrs.matches( appAttrs ))
+ list.add(member);
+ }
+ }
+ return list;
+ }
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginGroup.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,166 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router.plugin;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.etch.services.router.ConnectionStackInfo;
+import org.apache.etch.services.router.ERRemoteServer;
+import org.apache.etch.services.router.EtchRouterManager;
+import org.apache.etch.services.router.EtchRouterManagerHelper;
+import org.apache.etch.services.router.utils.PluginAttributes;
+
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class PluginMember
+{
+ private static final Logger _LOGGER = Logger.getLogger( PluginMember.class.getName());
+
+ private PluginGroup _pluginGroup = null;
+
+ private String _url = null;
+ private String _metaData = null;
+ private PluginAttributes _metaAttrs = null;
+ private List<PluginMemberConnection> _memberConnections = null;
+
+ private ERRemoteServer _remoteServer = null;
+
+ private boolean _active = false;
+
+ /**
+ *
+ * @param pluginGroup
+ * @param url
+ * @param metaData
+ */
+ public PluginMember( PluginGroup pluginGroup, String url, String metaData )
+ {
+ _pluginGroup = pluginGroup;
+ _url = url;
+ _metaData = metaData;
+ _memberConnections = Collections.synchronizedList( new ArrayList<PluginMemberConnection>());
+ try
+ {
+ _metaAttrs = new PluginAttributes(_pluginGroup.getName(), _metaData);
+ }
+ catch (Exception e)
+ {
+ String msg = String.format( "Invalid plugin member metaData \"%s\"", _metaData);
+ _LOGGER.log( Level.SEVERE, msg, e );
+ try
+ {
+ _metaAttrs = new PluginAttributes(_pluginGroup.getName(), null);
+ }
+ catch (Exception ee)
+ {
+ _LOGGER.log( Level.SEVERE, "Got exception with NULL plugin member metaData: ", e );
+ }
+ }
+ }
+
+ public PluginAttributes getMetaAttributes()
+ {
+ return _metaAttrs;
+ }
+
+ public PluginGroup getPluginGroup()
+ {
+ return _pluginGroup;
+ }
+
+ public String getUrl()
+ {
+ return _url;
+ }
+
+ public String getMetaData()
+ {
+ return _metaData;
+ }
+
+ public ConnectionStackInfo getConnInfo()
+ {
+ return (_remoteServer==null ? null : _remoteServer.getConnectionStackInfo());
+ }
+
+ public void addMemberConnection(PluginMemberConnection memberConn)
+ {
+ _memberConnections.add( memberConn );
+ }
+
+ public void removeMemberConnection(PluginMemberConnection memberConn)
+ {
+ _memberConnections.remove( memberConn );
+ }
+
+ public int sizeOfMemberConnections()
+ {
+ return _memberConnections.size();
+ }
+
+ public synchronized void checkState(EtchRouterManager etchRouterManager)
+ {
+ if (_active) return;
+ ConnectionStackInfo connInfo = null;
+ try
+ {
+ _remoteServer = EtchRouterManagerHelper.newServer( etchRouterManager, _url, null, _pluginGroup.getName() );
+ connInfo = _remoteServer.getConnectionStackInfo();
+ connInfo.setConnectionType( ConnectionStackInfo.ConnectionType.PLUGIN_MONITOR_CONN, _pluginGroup.getName() );
+ _remoteServer._startAndWaitUp( etchRouterManager.getConnectionStartMaxDelay() );
+ _active = true;
+ etchRouterManager.addConnectionStackInfo( connInfo );
+ _LOGGER.log( Level.INFO, "Succefully created a monitor connection to plugin service url \"{0}\", the monitor connection is \"{1}\"", new Object[]{_url, _remoteServer.toString()} );
+ }
+ catch (Exception e)
+ {
+ _LOGGER.log( Level.FINER, String.format( "Failed to connection to plugin service url \"%s\"", _url), e );
+ _remoteServer = null;
+ if (connInfo != null) etchRouterManager.removeConnectionStackInfo( connInfo );
+ }
+ }
+
+ public synchronized void onRemoteConnectionDown()
+ {
+ _active = false;
+ if (_remoteServer!=null)
+ {
+ _remoteServer = null;
+ }
+ }
+
+ public synchronized boolean isActive()
+ {
+ return _active;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format( "%s[url:%s, meta-data:%s]", this.getClass().getSimpleName(), _url, _metaData );
+ }
+
+
+}
\ No newline at end of file
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMember.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,52 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router.plugin;
+
+import org.apache.etch.services.router.ERRemoteServer;
+
+public class PluginMemberConnection
+{
+
+ private PluginMember _member = null;
+
+ private ERRemoteServer _remoteServer = null;
+
+ public PluginMemberConnection( PluginMember member, ERRemoteServer remoteServer )
+ {
+ _member = member;
+ _remoteServer = remoteServer;
+ }
+
+ public PluginMember getMember()
+ {
+ return _member;
+ }
+
+ public ERRemoteServer getRemoteServer()
+ {
+ return _remoteServer;
+ }
+
+ @Override
+ public String toString()
+ {
+ return String.format( "%s[member:%s, remote-server:%s]", this.getClass().getSimpleName(), _member, _remoteServer );
+ }
+
+
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginMemberConnection.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"
Added: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java
URL: http://svn.apache.org/viewvc/incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java?rev=748580&view=auto
==============================================================================
--- incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java (added)
+++ incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java Fri Feb 27 16:37:17 2009
@@ -0,0 +1,124 @@
+/* $Id$
+ *
+ * Copyright 2009-2010 Cisco Systems Inc.
+ *
+ * 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.etch.services.router.plugin;
+
+import java.util.Collection;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.etch.services.router.EtchRouterManager;
+
+
+/**
+ *
+ * @author Wei Wang (weiwa@cisco.com)
+ *
+ */
+public class PluginStateMonitor implements Runnable
+{
+ private static final Logger _LOGGER = Logger.getLogger( PluginStateMonitor.class.getName());
+
+ private int _sleepTime = 60000;
+
+ private EtchRouterManager _etchRouterManager = null;
+
+ private boolean _running = true;
+
+ /**
+ *
+ * @param etchRouterManager
+ */
+ public PluginStateMonitor(EtchRouterManager etchRouterManager)
+ {
+ _etchRouterManager = etchRouterManager;
+ try
+ {
+ _sleepTime = Integer.parseInt( _etchRouterManager.getProperty( "plugin.monitor.sleep.interval", "" ) );
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ /**
+ *
+ */
+ public void stop()
+ {
+ _running = false;
+ }
+
+ public void run()
+ {
+ int sleepBetween = 2*_etchRouterManager.getConnectionStartMaxDelay();
+ while (_running)
+ {
+ _LOGGER.log( Level.FINE, "Checking each plugin member's state..." );
+ Collection<PluginGroup> pluginGrps = _etchRouterManager.getPluginGroups();
+ for (PluginGroup pluginGrp : pluginGrps)
+ {
+ Collection<PluginMember> members = pluginGrp.getPluginMembers();
+ for (PluginMember member : members)
+ {
+ Thread runner = new Thread(new CheckPluginMemberStateRunner(member));
+ runner.start();
+ }
+ }
+
+ _LOGGER.log( Level.FINE, "Sleeping for {0} miliseconds before refreshing applications...", sleepBetween );
+ try
+ {
+ Thread.sleep( sleepBetween );
+ }
+ catch (Exception e)
+ {
+
+ }
+
+ _LOGGER.log( Level.FINE, "Refreshing each application's connection..." );
+ for (PluginGroup pluginGrp : pluginGrps)
+ {
+ pluginGrp.refreshAppConnections();
+ }
+
+ _LOGGER.log( Level.FINE, "Sleeping for {0} miliseconds before starting next cycle...", _sleepTime );
+ try
+ {
+ Thread.sleep( _sleepTime );
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ private class CheckPluginMemberStateRunner implements Runnable
+ {
+ private PluginMember _pluginMember = null;
+
+ public CheckPluginMemberStateRunner(PluginMember member)
+ {
+ _pluginMember = member;
+ }
+
+ public void run()
+ {
+ _pluginMember.checkState( _etchRouterManager );
+ }
+ }
+
+}
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/etch/branches/router/services/router/src/main/java/org/apache/etch/services/router/plugin/PluginStateMonitor.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"