diff options
8 files changed, 262 insertions, 202 deletions
diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/.project b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/.project index 6ceb15778..030063859 100644 --- a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/.project +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/.project @@ -25,6 +25,11 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.pde.ds.core.builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.pde.PluginNature</nature> diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/META-INF/MANIFEST.MF b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/META-INF/MANIFEST.MF index 087343ab3..b759db01b 100644 --- a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/META-INF/MANIFEST.MF +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.ecf.osgi.services.distribution -Bundle-Version: 2.0.200.qualifier +Bundle-Version: 2.0.300.qualifier Bundle-Activator: org.eclipse.ecf.internal.osgi.services.distribution.Activator Bundle-Vendor: %pluginProvider Bundle-RequiredExecutionEnvironment: CDC-1.1/Foundation-1.1, @@ -17,3 +17,5 @@ Bundle-Localization: plugin Export-Package: org.eclipse.ecf.osgi.services.distribution;version="2.0.0";x-internal:=true Require-Bundle: org.eclipse.equinox.common, org.eclipse.ecf.osgi.services.remoteserviceadmin;bundle-version="1.0.0" +Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/eventhookcomponent.xml diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/OSGI-INF/eventhookcomponent.xml b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/OSGI-INF/eventhookcomponent.xml new file mode 100644 index 000000000..348301167 --- /dev/null +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/OSGI-INF/eventhookcomponent.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="activate" immediate="false" name="org.eclipse.ecf.osgi.services.distribution.basictopologymanager"> + <implementation class="org.eclipse.ecf.internal.osgi.services.distribution.BasicTopologyManagerComponent"/> + <service> + <provide interface="org.osgi.framework.hooks.service.EventHook"/> + </service> + <reference bind="bindEndpointListener" cardinality="1..n" interface="org.osgi.service.remoteserviceadmin.EndpointListener" name="EndpointListener" policy="static" unbind="unbindEndpointListener"/> +</scr:component> diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/build.properties b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/build.properties index 89b639e01..247c244cf 100644 --- a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/build.properties +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/build.properties @@ -1,9 +1,11 @@ -source.. = src/ output.. = bin/ bin.includes = META-INF/,\ .,\ about.html,\ - plugin.properties + plugin.properties,\ + OSGI-INF/ src.includes = about.html +javacErrors.. = -assertIdentifier,\ + -enumIdentifier +source.. = src/ jre.compilation.profile = J2SE-1.4 -javacErrors.. = -assertIdentifier,-enumIdentifier diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/Activator.java b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/Activator.java index 1a215f17c..83535b505 100644 --- a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/Activator.java +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/Activator.java @@ -9,17 +9,31 @@ ******************************************************************************/ package org.eclipse.ecf.internal.osgi.services.distribution; +import java.util.Dictionary; +import java.util.Properties; import org.eclipse.core.runtime.IStatus; import org.eclipse.ecf.core.util.LogHelper; import org.eclipse.ecf.core.util.SystemLogService; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.Filter; import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.framework.hooks.service.EventHook; import org.osgi.service.log.LogService; +import org.osgi.service.remoteserviceadmin.EndpointListener; import org.osgi.util.tracker.ServiceTracker; public class Activator implements BundleActivator { + private static final boolean allowLoopbackReference = new Boolean( + System.getProperty( + "org.eclipse.ecf.osgi.services.discovery.allowLoopbackReference", //$NON-NLS-1$ + "false")).booleanValue(); //$NON-NLS-1$ + + private static final String endpointListenerScope = System + .getProperty("org.eclipse.ecf.osgi.services.discovery.endpointListenerScope"); //$NON-NLS-1$ + public static final String PLUGIN_ID = "org.eclipse.ecf.osgi.services.distribution"; //$NON-NLS-1$ public static final boolean autoCreateProxyContainer = new Boolean( @@ -36,13 +50,18 @@ public class Activator implements BundleActivator { "org.eclipse.ecf.osgi.services.distribution.defaultConfigType", //$NON-NLS-1$ "ecf.generic.server"); //$NON-NLS-1$ + private static final String PROP_USE_DS = "equinox.use.ds"; //$NON-NLS-1$ + private static Activator plugin; private BundleContext context; private ServiceTracker logServiceTracker = null; private LogService logService = null; - private BasicTopologyManager basicTopologyManager; + private BasicTopologyManagerImpl basicTopologyManagerImpl; + private ServiceRegistration endpointListenerReg; + private BasicTopologyManagerComponent basicTopologyManagerComp; + private ServiceRegistration eventHookRegistration; public static Activator getDefault() { return plugin; @@ -52,7 +71,7 @@ public class Activator implements BundleActivator { return context; } - protected synchronized LogService getLogService() { + protected LogService getLogService() { if (this.context == null) return null; if (logServiceTracker == null) { @@ -86,6 +105,30 @@ public class Activator implements BundleActivator { logService.log(sr, level, message, t); } + private String getEndpointListenerScope() { + // If it's set via system property, then simply use it + if (endpointListenerScope != null) + return endpointListenerScope; + // Otherwise create it + // if allowLoopbackReference is true, then return a filter to match all + // endpoint description ids + StringBuffer elScope = new StringBuffer("("); //$NON-NLS-1$ + if (allowLoopbackReference) { + elScope.append(org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_ID); + elScope.append("=*"); //$NON-NLS-1$ + } else { + // filter so that local framework uuid is not the same as local + // value + elScope.append("!("); //$NON-NLS-1$ + elScope.append(org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_FRAMEWORK_UUID); + elScope.append("="); //$NON-NLS-1$ + elScope.append(basicTopologyManagerImpl.getFrameworkUUID()); + elScope.append(")"); //$NON-NLS-1$ + } + elScope.append(")"); //$NON-NLS-1$ + return elScope.toString(); + } + /* * (non-Javadoc) * @@ -94,11 +137,53 @@ public class Activator implements BundleActivator { * ) */ public void start(final BundleContext ctxt) throws Exception { + // Always set plugin and context plugin = this; this.context = ctxt; - basicTopologyManager = new BasicTopologyManager(context); - // start topology manager first - basicTopologyManager.start(); + // Create basicTopologyManagerImpl + basicTopologyManagerImpl = new BasicTopologyManagerImpl(context); + + // Register basicTopologyManagerImpl as EndpointListener always, so that + // it + // gets notified when Endpoints are discovered + Properties props = new Properties(); + props.put( + org.osgi.service.remoteserviceadmin.EndpointListener.ENDPOINT_LISTENER_SCOPE, + getEndpointListenerScope()); + endpointListenerReg = getContext().registerService( + EndpointListener.class.getName(), basicTopologyManagerImpl, + (Dictionary) props); + + // Like EventAdmin, if equinox ds is running, then we simply return (no + // more to do) + if (Boolean.valueOf(context.getProperty(PROP_USE_DS)).booleanValue()) + return; // If this property is set we assume DS is being used. + + // The following code is to make sure that we don't do any more if + // EventHook has already been registered for us by DS + // Create serviceFilter for EventHook classname + String serviceName = EventHook.class.getName(); + Filter serviceFilter = context + .createFilter("(objectclass=" + serviceName + ")"); //$NON-NLS-1$ //$NON-NLS-2$ + // if this bundle has already registered EventHook service via ds, then + // we're done + ServiceReference[] refs = context.getBundle().getRegisteredServices(); + if (refs != null) { + for (int i = 0; i < refs.length; i++) + if (serviceFilter.match(refs[i])) + return; // We found a service registered by this bundle + // already so we return + } + + // Otherwise (no DS), we create a basicTopologyManagerComponent + basicTopologyManagerComp = new BasicTopologyManagerComponent(); + // bind the topology manager to it + basicTopologyManagerComp.bindEndpointListener(basicTopologyManagerImpl); + // register the basic topology manager as EventHook service + eventHookRegistration = this.context.registerService(EventHook.class, + basicTopologyManagerComp, null); + // export any previously registered remote services by calling activate + basicTopologyManagerComp.activate(); } /* @@ -108,18 +193,29 @@ public class Activator implements BundleActivator { * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) */ public void stop(BundleContext ctxt) throws Exception { - if (basicTopologyManager != null) { - basicTopologyManager.close(); - basicTopologyManager = null; + if (eventHookRegistration != null) { + eventHookRegistration.unregister(); + eventHookRegistration = null; + } + if (basicTopologyManagerComp != null) { + basicTopologyManagerComp + .unbindEndpointListener(basicTopologyManagerImpl); + basicTopologyManagerComp = null; + } + if (endpointListenerReg != null) { + endpointListenerReg.unregister(); + endpointListenerReg = null; + } + if (basicTopologyManagerImpl != null) { + basicTopologyManagerImpl.close(); + basicTopologyManagerImpl = null; } if (logServiceTracker != null) { logServiceTracker.close(); logServiceTracker = null; logService = null; } - synchronized (this) { - this.context = null; - } + this.context = null; plugin = null; } diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManager.java b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManager.java deleted file mode 100644 index 431603bad..000000000 --- a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManager.java +++ /dev/null @@ -1,187 +0,0 @@ -package org.eclipse.ecf.internal.osgi.services.distribution; - -import java.util.Collection; -import java.util.Dictionary; -import java.util.Properties; -import org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractTopologyManager; -import org.osgi.framework.BundleContext; -import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceEvent; -import org.osgi.framework.ServiceReference; -import org.osgi.framework.ServiceRegistration; -import org.osgi.framework.hooks.service.EventHook; -import org.osgi.service.remoteserviceadmin.EndpointListener; - -public class BasicTopologyManager extends AbstractTopologyManager implements - EventHook, EndpointListener { - - private static final boolean allowLoopbackReference = new Boolean( - System.getProperty( - "org.eclipse.ecf.osgi.services.discovery.allowLoopbackReference", //$NON-NLS-1$ - "false")).booleanValue(); //$NON-NLS-1$ - - private static final String endpointListenerScope = System - .getProperty("org.eclipse.ecf.osgi.services.discovery.endpointListenerScope"); //$NON-NLS-1$ - - private boolean exportRegisteredSvcs = new Boolean( - System.getProperty( - "org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcs", "true")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$ - - private String exportRegisteredSvcsClassname = System - .getProperty("org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcsClassname"); //$NON-NLS-1$ - - private String exportRegisteredSvcsFilter = System - .getProperty( - "org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcsFilter", "(service.exported.interfaces=*)"); //$NON-NLS-1$ //$NON-NLS-2$ - - private ServiceRegistration endpointListenerRegistration; - - private ServiceRegistration eventHookRegistration; - - BasicTopologyManager(BundleContext context) { - super(context); - } - - private String getEndpointListenerScope() { - // If it's set via system property, then simply use it - if (endpointListenerScope != null) - return endpointListenerScope; - // Otherwise create it - // if allowLoopbackReference is true, then return a filter to match all - // endpoint description ids - StringBuffer elScope = new StringBuffer("("); //$NON-NLS-1$ - if (allowLoopbackReference) { - elScope.append(org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_ID); - elScope.append("=*"); //$NON-NLS-1$ - } else { - // filter so that local framework uuid is not the same as local - // value - elScope.append("!("); //$NON-NLS-1$ - elScope.append(org.osgi.service.remoteserviceadmin.RemoteConstants.ENDPOINT_FRAMEWORK_UUID); - elScope.append("="); //$NON-NLS-1$ - elScope.append(getFrameworkUUID()); - elScope.append(")"); //$NON-NLS-1$ - } - elScope.append(")"); //$NON-NLS-1$ - String result = elScope.toString(); - trace("getEndpointListenerScope", "endpointListenerScope=" + result); //$NON-NLS-1$ //$NON-NLS-2$ - return result; - } - - private void exportRegisteredServices(String exportRegisteredSvcsClassname, - String exportRegisteredSvcsFilter) { - try { - final ServiceReference[] existingServiceRefs = getContext() - .getAllServiceReferences(exportRegisteredSvcsClassname, - exportRegisteredSvcsFilter); - // Now export as if the service was registering right now...i.e. - // perform - // export - if (existingServiceRefs != null && existingServiceRefs.length > 0) { - // After having collected all pre-registered services (with - // marker prop) we are going to asynchronously remote them. - // Registering potentially is a long-running operation (due to - // discovery I/O...) and thus should no be carried out in the - // OSGi FW thread. (https://bugs.eclipse.org/405027) - new Thread(new Runnable() { - public void run() { - for (int i = 0; i < existingServiceRefs.length; i++) { - // This method will check the service properties for - // remote service props. If previously registered as - // a - // remote service, it will export the remote - // service if not it will simply return/skip - handleServiceRegistering(existingServiceRefs[i]); - } - } - }, "BasicTopologyManagerPreRegSrvExporter").start(); //$NON-NLS-1$ - } - } catch (InvalidSyntaxException e) { - logError( - "exportRegisteredServices", //$NON-NLS-1$ - "Could not retrieve existing service references for exportRegisteredSvcsClassname=" //$NON-NLS-1$ - + exportRegisteredSvcsClassname - + " and exportRegisteredSvcsFilter=" //$NON-NLS-1$ - + exportRegisteredSvcsFilter, e); - } - } - - void start() throws Exception { - - // Register as EndpointListener, so that it gets notified when Endpoints - // are discovered - Properties props = new Properties(); - props.put( - org.osgi.service.remoteserviceadmin.EndpointListener.ENDPOINT_LISTENER_SCOPE, - getEndpointListenerScope()); - endpointListenerRegistration = getContext().registerService( - EndpointListener.class.getName(), this, (Dictionary) props); - - // Register as EventHook, so that we get notified when remote services - // are registered - eventHookRegistration = getContext().registerService( - EventHook.class.getName(), this, null); - - // Lastly, export any previously registered remote services - if (exportRegisteredSvcs) - exportRegisteredServices(exportRegisteredSvcsClassname, - exportRegisteredSvcsFilter); - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.service.remoteserviceadmin.EndpointListener#endpointAdded(org - * .osgi.service.remoteserviceadmin.EndpointDescription, java.lang.String) - */ - public void endpointAdded( - org.osgi.service.remoteserviceadmin.EndpointDescription endpoint, - String matchedFilter) { - handleEndpointAdded(endpoint, matchedFilter); - } - - /* - * (non-Javadoc) - * - * @see - * org.osgi.service.remoteserviceadmin.EndpointListener#endpointRemoved( - * org.osgi.service.remoteserviceadmin.EndpointDescription, - * java.lang.String) - */ - public void endpointRemoved( - org.osgi.service.remoteserviceadmin.EndpointDescription endpoint, - String matchedFilter) { - handleEndpointRemoved(endpoint, matchedFilter); - } - - /* - * (non-Javadoc) - * - * @see org.osgi.framework.hooks.service.EventHook#event(org.osgi.framework. - * ServiceEvent, java.util.Collection) - */ - public void event(ServiceEvent event, Collection contexts) { - handleEvent(event, contexts); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractTopologyManager - * #close() - */ - public void close() { - if (eventHookRegistration != null) { - eventHookRegistration.unregister(); - eventHookRegistration = null; - } - if (endpointListenerRegistration != null) { - endpointListenerRegistration.unregister(); - endpointListenerRegistration = null; - } - super.close(); - } - -} diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerComponent.java b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerComponent.java new file mode 100644 index 000000000..7b4e7e9d7 --- /dev/null +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerComponent.java @@ -0,0 +1,43 @@ +package org.eclipse.ecf.internal.osgi.services.distribution; + +import java.util.Collection; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.hooks.service.EventHook; +import org.osgi.service.remoteserviceadmin.EndpointListener; + +public class BasicTopologyManagerComponent implements EventHook { + + private boolean exportRegisteredSvcs = new Boolean( + System.getProperty( + "org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcs", "true")).booleanValue(); //$NON-NLS-1$ //$NON-NLS-2$ + + private String exportRegisteredSvcsFilter = System + .getProperty( + "org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcsFilter", "(service.exported.interfaces=*)"); //$NON-NLS-1$ //$NON-NLS-2$ + + private String exportRegisteredSvcsClassname = System + .getProperty("org.eclipse.ecf.osgi.services.basictopologymanager.exportRegisteredSvcsClassname"); //$NON-NLS-1$ + + private BasicTopologyManagerImpl basicTopologyManagerImpl; + + void bindEndpointListener(EndpointListener el) { + if (el instanceof BasicTopologyManagerImpl) + basicTopologyManagerImpl = (BasicTopologyManagerImpl) el; + } + + void unbindEndpointListener(EndpointListener el) { + if (el instanceof BasicTopologyManagerImpl) + basicTopologyManagerImpl = null; + } + + void activate() { + if (exportRegisteredSvcs) + basicTopologyManagerImpl.exportRegisteredServices( + exportRegisteredSvcsClassname, exportRegisteredSvcsFilter); + } + + public void event(ServiceEvent event, Collection contexts) { + basicTopologyManagerImpl.event(event, contexts); + } + +} diff --git a/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerImpl.java b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerImpl.java new file mode 100644 index 000000000..89c78345d --- /dev/null +++ b/compendium/bundles/org.eclipse.ecf.osgi.services.distribution/src/org/eclipse/ecf/internal/osgi/services/distribution/BasicTopologyManagerImpl.java @@ -0,0 +1,91 @@ +package org.eclipse.ecf.internal.osgi.services.distribution; + +import java.util.Collection; +import org.eclipse.ecf.osgi.services.remoteserviceadmin.AbstractTopologyManager; +import org.osgi.framework.BundleContext; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceEvent; +import org.osgi.framework.ServiceReference; +import org.osgi.service.remoteserviceadmin.EndpointListener; + +public class BasicTopologyManagerImpl extends AbstractTopologyManager implements + EndpointListener { + + BasicTopologyManagerImpl(BundleContext context) { + super(context); + } + + protected String getFrameworkUUID() { + return super.getFrameworkUUID(); + } + + void exportRegisteredServices(String exportRegisteredSvcsClassname, + String exportRegisteredSvcsFilter) { + try { + final ServiceReference[] existingServiceRefs = getContext() + .getAllServiceReferences(exportRegisteredSvcsClassname, + exportRegisteredSvcsFilter); + // Now export as if the service was registering right now...i.e. + // perform + // export + if (existingServiceRefs != null && existingServiceRefs.length > 0) { + // After having collected all pre-registered services (with + // marker prop) we are going to asynchronously remote them. + // Registering potentially is a long-running operation (due to + // discovery I/O...) and thus should no be carried out in the + // OSGi FW thread. (https://bugs.eclipse.org/405027) + new Thread(new Runnable() { + public void run() { + for (int i = 0; i < existingServiceRefs.length; i++) { + // This method will check the service properties for + // remote service props. If previously registered as + // a + // remote service, it will export the remote + // service if not it will simply return/skip + handleServiceRegistering(existingServiceRefs[i]); + } + } + }, "BasicTopologyManagerPreRegSrvExporter").start(); //$NON-NLS-1$ + } + } catch (InvalidSyntaxException e) { + logError( + "exportRegisteredServices", //$NON-NLS-1$ + "Could not retrieve existing service references for exportRegisteredSvcsClassname=" //$NON-NLS-1$ + + exportRegisteredSvcsClassname + + " and exportRegisteredSvcsFilter=" //$NON-NLS-1$ + + exportRegisteredSvcsFilter, e); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.service.remoteserviceadmin.EndpointListener#endpointAdded(org + * .osgi.service.remoteserviceadmin.EndpointDescription, java.lang.String) + */ + public void endpointAdded( + org.osgi.service.remoteserviceadmin.EndpointDescription endpoint, + String matchedFilter) { + handleEndpointAdded(endpoint, matchedFilter); + } + + /* + * (non-Javadoc) + * + * @see + * org.osgi.service.remoteserviceadmin.EndpointListener#endpointRemoved( + * org.osgi.service.remoteserviceadmin.EndpointDescription, + * java.lang.String) + */ + public void endpointRemoved( + org.osgi.service.remoteserviceadmin.EndpointDescription endpoint, + String matchedFilter) { + handleEndpointRemoved(endpoint, matchedFilter); + } + + void event(ServiceEvent event, Collection contexts) { + handleEvent(event, contexts); + } + +} |