Repository: aries-rsa
Updated Branches:
  refs/heads/master 495a0e939 -> 965444751


[ARIES-1527] Make eventadmin optional

Project: http://git-wip-us.apache.org/repos/asf/aries-rsa/repo
Commit: http://git-wip-us.apache.org/repos/asf/aries-rsa/commit/96544475
Tree: http://git-wip-us.apache.org/repos/asf/aries-rsa/tree/96544475
Diff: http://git-wip-us.apache.org/repos/asf/aries-rsa/diff/96544475

Branch: refs/heads/master
Commit: 965444751bec438b3220e1ae0ffbbd7d45ae6610
Parents: 495a0e9
Author: Guillaume Nodet <[email protected]>
Authored: Tue Apr 12 14:48:10 2016 +0200
Committer: Christian Schneider <[email protected]>
Committed: Tue Apr 12 15:49:39 2016 +0200

----------------------------------------------------------------------
 eapub/Readme.md                                 |   3 +
 eapub/bnd.bnd                                   |   2 +
 eapub/pom.xml                                   |  26 +++
 .../org/apache/aries/rsa/eapub/Activator.java   |  39 ++++
 .../aries/rsa/eapub/EventAdminHelper.java       | 153 ++++++++++++++
 .../aries/rsa/eapub/EventAdminHelperTest.java   | 197 +++++++++++++++++++
 features/src/main/resources/features.xml        |   7 +-
 pom.xml                                         |   1 +
 .../apache/aries/rsa/core/EventAdminHelper.java | 151 --------------
 .../apache/aries/rsa/core/EventProducer.java    |  42 ++--
 .../aries/rsa/core/EventProducerTest.java       |  88 +++------
 11 files changed, 481 insertions(+), 228 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/Readme.md
----------------------------------------------------------------------
diff --git a/eapub/Readme.md b/eapub/Readme.md
new file mode 100644
index 0000000..5fd3dbf
--- /dev/null
+++ b/eapub/Readme.md
@@ -0,0 +1,3 @@
+# Remote Service Admin EventAdmin Publisher
+
+Is used to publish EventAdmin events for Remote Service Admin events 
notifications.

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/bnd.bnd
----------------------------------------------------------------------
diff --git a/eapub/bnd.bnd b/eapub/bnd.bnd
new file mode 100644
index 0000000..94d281a
--- /dev/null
+++ b/eapub/bnd.bnd
@@ -0,0 +1,2 @@
+Bundle-Activator: org.apache.aries.rsa.eapub.Activator
+Private-Package: org.apache.aries.rsa.eapub

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/pom.xml
----------------------------------------------------------------------
diff --git a/eapub/pom.xml b/eapub/pom.xml
new file mode 100644
index 0000000..e6a1c9b
--- /dev/null
+++ b/eapub/pom.xml
@@ -0,0 +1,26 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.rsa</groupId>
+        <artifactId>org.apache.aries.rsa.parent</artifactId>
+        <version>1.9-SNAPSHOT</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    <artifactId>org.apache.aries.rsa.eapub</artifactId>
+    <packaging>bundle</packaging>
+    <name>Aries Remote Service Event Admin Publisher</name>
+    <description>The Remote Service Event Admin Publisher</description>
+
+    <properties>
+        <topDirectoryLocation>..</topDirectoryLocation>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.rsa</groupId>
+            <artifactId>org.apache.aries.rsa.spi</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/src/main/java/org/apache/aries/rsa/eapub/Activator.java
----------------------------------------------------------------------
diff --git a/eapub/src/main/java/org/apache/aries/rsa/eapub/Activator.java 
b/eapub/src/main/java/org/apache/aries/rsa/eapub/Activator.java
new file mode 100644
index 0000000..8bf4cee
--- /dev/null
+++ b/eapub/src/main/java/org/apache/aries/rsa/eapub/Activator.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.rsa.eapub;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
+
+public class Activator implements BundleActivator {
+
+    private ServiceRegistration<RemoteServiceAdminListener> registration;
+
+    public void start(BundleContext bundlecontext) throws Exception {
+        registration = bundlecontext.registerService(
+                RemoteServiceAdminListener.class, new 
EventAdminHelper(bundlecontext), null);
+    }
+
+    public void stop(BundleContext context) throws Exception {
+        registration.unregister();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/src/main/java/org/apache/aries/rsa/eapub/EventAdminHelper.java
----------------------------------------------------------------------
diff --git 
a/eapub/src/main/java/org/apache/aries/rsa/eapub/EventAdminHelper.java 
b/eapub/src/main/java/org/apache/aries/rsa/eapub/EventAdminHelper.java
new file mode 100644
index 0000000..d560a8f
--- /dev/null
+++ b/eapub/src/main/java/org/apache/aries/rsa/eapub/EventAdminHelper.java
@@ -0,0 +1,153 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.rsa.eapub;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class EventAdminHelper implements RemoteServiceAdminListener {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(EventAdminHelper.class);
+
+    private BundleContext bctx;
+
+    public EventAdminHelper(BundleContext bc) {
+        bctx = bc;
+    }
+
+    private Event createEvent(Map<String, Object> props, String type) {
+        String topic = "org/osgi/service/remoteserviceadmin/" + type;
+        props.put("bundle", bctx.getBundle());
+        props.put("bundle.id", bctx.getBundle().getBundleId());
+        props.put("bundle.symbolicname", bctx.getBundle().getSymbolicName());
+
+        String version = 
(String)bctx.getBundle().getHeaders().get("Bundle-Version");
+        Version v = version != null ? new Version(version) : 
Version.emptyVersion;
+        setIfNotNull(props, "bundle.version", v);
+
+        return new Event(topic, props);
+    }
+
+    @Override
+    public void remoteAdminEvent(RemoteServiceAdminEvent rsae) {
+        String topic = remoteServiceAdminEventTypeToString(rsae.getType());
+
+        Map<String, Object> props = new HashMap<String, Object>();
+        setIfNotNull(props, "cause", rsae.getException());
+
+        EndpointDescription endpoint = null;
+        if (rsae.getImportReference() != null) {
+            endpoint = rsae.getImportReference().getImportedEndpoint();
+            setIfNotNull(props, "import.registration", endpoint);
+        } else if (rsae.getExportReference() != null) {
+            endpoint = rsae.getExportReference().getExportedEndpoint();
+            setIfNotNull(props, "export.registration", endpoint);
+        }
+
+        if (endpoint != null) {
+            setIfNotNull(props, "service.remote.id", endpoint.getServiceId());
+            setIfNotNull(props, "service.remote.uuid", 
endpoint.getFrameworkUUID());
+            setIfNotNull(props, "service.remote.uri", endpoint.getId());
+            setIfNotNull(props, "objectClass", 
endpoint.getInterfaces().toArray());
+            setIfNotNull(props, "service.imported.configs", 
endpoint.getConfigurationTypes());
+        }
+        props.put("timestamp", System.currentTimeMillis());
+        props.put("event", rsae);
+
+        Event event = createEvent(props, topic);
+        notifyEventAdmins(topic, event);
+    }
+
+    @SuppressWarnings({
+     "rawtypes", "unchecked"
+    })
+    private void notifyEventAdmins(String topic, Event event) {
+        ServiceReference[] refs = null;
+        try {
+            refs = bctx.getAllServiceReferences(EventAdmin.class.getName(), 
null);
+        } catch (InvalidSyntaxException e) {
+            LOG.error("Failed to get EventAdmin: " + e.getMessage(), e);
+        }
+
+        if (refs != null) {
+            LOG.debug("Publishing event to {} EventAdmins; Topic:[{}]", 
refs.length, topic);
+            for (ServiceReference serviceReference : refs) {
+                EventAdmin eventAdmin = (EventAdmin) 
bctx.getService(serviceReference);
+                try {
+                    eventAdmin.postEvent(event);
+                } finally {
+                    if (eventAdmin != null) {
+                        bctx.ungetService(serviceReference);
+                    }
+                }
+            }
+        }
+    }
+
+    private <K, V> void setIfNotNull(Map<K, V> map, K key, V val) {
+        if (val != null) {
+            map.put(key, val);
+        }
+    }
+
+    private static String remoteServiceAdminEventTypeToString(int type) {
+        String retval;
+        switch (type) {
+        case RemoteServiceAdminEvent.EXPORT_ERROR:
+            retval = "EXPORT_ERROR";
+            break;
+        case RemoteServiceAdminEvent.EXPORT_REGISTRATION:
+            retval = "EXPORT_REGISTRATION";
+            break;
+        case RemoteServiceAdminEvent.EXPORT_UNREGISTRATION:
+            retval = "EXPORT_UNREGISTRATION";
+            break;
+        case RemoteServiceAdminEvent.EXPORT_WARNING:
+            retval = "EXPORT_WARNING";
+            break;
+        case RemoteServiceAdminEvent.IMPORT_ERROR:
+            retval = "IMPORT_ERROR";
+            break;
+        case RemoteServiceAdminEvent.IMPORT_REGISTRATION:
+            retval = "IMPORT_REGISTRATION";
+            break;
+        case RemoteServiceAdminEvent.IMPORT_UNREGISTRATION:
+            retval = "IMPORT_UNREGISTRATION";
+            break;
+        case RemoteServiceAdminEvent.IMPORT_WARNING:
+            retval = "IMPORT_WARNING";
+            break;
+        default:
+            retval = "UNKNOWN_EVENT";
+        }
+        return retval;
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/eapub/src/test/java/org/apache/aries/rsa/eapub/EventAdminHelperTest.java
----------------------------------------------------------------------
diff --git 
a/eapub/src/test/java/org/apache/aries/rsa/eapub/EventAdminHelperTest.java 
b/eapub/src/test/java/org/apache/aries/rsa/eapub/EventAdminHelperTest.java
new file mode 100644
index 0000000..e08a05f
--- /dev/null
+++ b/eapub/src/test/java/org/apache/aries/rsa/eapub/EventAdminHelperTest.java
@@ -0,0 +1,197 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.aries.rsa.eapub;
+
+import java.util.Arrays;
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.UUID;
+
+import org.easymock.EasyMock;
+import org.easymock.IAnswer;
+import org.junit.Assert;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
+import org.osgi.service.remoteserviceadmin.EndpointDescription;
+import org.osgi.service.remoteserviceadmin.ExportReference;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
+
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class EventAdminHelperTest {
+    
+    @Test
+    public void testPublishNotification() throws Exception {
+        final EndpointDescription epd = 
EasyMock.createNiceMock(EndpointDescription.class);
+        
EasyMock.expect(epd.getServiceId()).andReturn(Long.MAX_VALUE).anyTimes();
+        final String uuid = UUID.randomUUID().toString();
+        EasyMock.expect(epd.getFrameworkUUID()).andReturn(uuid).anyTimes();
+        EasyMock.expect(epd.getId()).andReturn("foo://bar").anyTimes();
+        final List<String> interfaces = Arrays.asList("org.foo.Bar", 
"org.boo.Far");
+        EasyMock.expect(epd.getInterfaces()).andReturn(interfaces).anyTimes();
+        
EasyMock.expect(epd.getConfigurationTypes()).andReturn(Arrays.asList("org.apache.cxf.ws")).anyTimes();
+        EasyMock.replay(epd);
+        final ServiceReference sref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(sref);
+        final ExportReference er = 
EasyMock.createNiceMock(ExportReference.class);
+        EasyMock.expect(er.getExportedEndpoint()).andReturn(epd).anyTimes();
+        EasyMock.expect(er.getExportedService()).andReturn(sref).anyTimes();
+        EasyMock.replay(er);
+
+        final Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(bundle.getBundleId()).andReturn(42L).anyTimes();
+        
EasyMock.expect(bundle.getSymbolicName()).andReturn("test.bundle").anyTimes();
+        Dictionary<String, String> headers = new Hashtable<String, String>();
+        headers.put("Bundle-Version", "1.2.3.test");
+        EasyMock.expect(bundle.getHeaders()).andReturn(headers).anyTimes();
+        EasyMock.replay(bundle);
+
+        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
+        ea.postEvent((Event) EasyMock.anyObject());
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws Throwable {
+                Event event = (Event) EasyMock.getCurrentArguments()[0];
+
+                
Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_REGISTRATION", 
event.getTopic());
+                Assert.assertSame(bundle, event.getProperty("bundle"));
+                Assert.assertEquals(42L, event.getProperty("bundle.id"));
+                Assert.assertEquals("test.bundle", 
event.getProperty("bundle.symbolicname"));
+                Assert.assertEquals(new Version(1, 2, 3, "test"), 
event.getProperty("bundle.version"));
+                Assert.assertNull(event.getProperty("cause"));
+                Assert.assertEquals(epd, 
event.getProperty("export.registration"));
+
+                Assert.assertEquals(Long.MAX_VALUE, 
event.getProperty("service.remote.id"));
+                Assert.assertEquals(uuid, 
event.getProperty("service.remote.uuid"));
+                Assert.assertEquals("foo://bar", 
event.getProperty("service.remote.uri"));
+                Assert.assertTrue(Arrays.equals(interfaces.toArray(new 
String[] {}),
+                                                (String[]) 
event.getProperty("objectClass")));
+
+                Assert.assertNotNull(event.getProperty("timestamp"));
+
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
event.getProperty("event");
+                Assert.assertNull(rsae.getException());
+                
Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_REGISTRATION, 
rsae.getType());
+                Assert.assertSame(bundle, rsae.getSource());
+                ExportReference er = rsae.getExportReference();
+                Assert.assertSame(epd, er.getExportedEndpoint());
+                Assert.assertSame(sref, er.getExportedService());
+
+                return null;
+            }
+        });
+        EasyMock.replay(ea);
+
+        ServiceReference eaSref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(eaSref);
+
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+        EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), 
null))
+            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
+        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        EasyMock.replay(bc);
+
+        RemoteServiceAdminEvent event = new RemoteServiceAdminEvent(
+                RemoteServiceAdminEvent.EXPORT_REGISTRATION,
+                bundle,
+                er,
+                null
+        );
+        new EventAdminHelper(bc).remoteAdminEvent(event);
+        EasyMock.verify(epd, sref, er, ea, eaSref, bc);
+    }
+
+    @Test
+    public void testPublishErrorNotification() throws Exception {
+        final EndpointDescription epd = 
EasyMock.createNiceMock(EndpointDescription.class);
+        
EasyMock.expect(epd.getInterfaces()).andReturn(Arrays.asList("org.foo.Bar")).anyTimes();
+        EasyMock.replay(epd);
+        final ServiceReference sref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(sref);
+        final ExportReference er = 
EasyMock.createNiceMock(ExportReference.class);
+        EasyMock.expect(er.getExportedEndpoint()).andReturn(epd).anyTimes();
+        EasyMock.expect(er.getExportedService()).andReturn(sref).anyTimes();
+        EasyMock.replay(er);
+
+        final Bundle bundle = EasyMock.createNiceMock(Bundle.class);
+        EasyMock.expect(bundle.getBundleId()).andReturn(42L).anyTimes();
+        
EasyMock.expect(bundle.getSymbolicName()).andReturn("test.bundle").anyTimes();
+        EasyMock.expect(bundle.getHeaders()).andReturn(new Hashtable<String, 
String>()).anyTimes();
+        EasyMock.replay(bundle);
+
+        final Exception exportException = new Exception();
+
+        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
+        ea.postEvent((Event) EasyMock.anyObject());
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws Throwable {
+                Event event = (Event) EasyMock.getCurrentArguments()[0];
+
+                
Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_ERROR", 
event.getTopic());
+                Assert.assertSame(bundle, event.getProperty("bundle"));
+                Assert.assertEquals(42L, event.getProperty("bundle.id"));
+                Assert.assertEquals("test.bundle", 
event.getProperty("bundle.symbolicname"));
+                Assert.assertEquals(new Version("0"), 
event.getProperty("bundle.version"));
+                Assert.assertSame(exportException, event.getProperty("cause"));
+                Assert.assertEquals(epd, 
event.getProperty("export.registration"));
+                Assert.assertTrue(Arrays.equals(new String[] {"org.foo.Bar"},
+                                                (String[]) 
event.getProperty("objectClass")));
+
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
event.getProperty("event");
+                Assert.assertSame(exportException, rsae.getException());
+                Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_ERROR, 
rsae.getType());
+                Assert.assertSame(bundle, rsae.getSource());
+                ExportReference er = rsae.getExportReference();
+                Assert.assertSame(epd, er.getExportedEndpoint());
+                Assert.assertSame(sref, er.getExportedService());
+
+                return null;
+            }
+        });
+        EasyMock.replay(ea);
+
+        ServiceReference eaSref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.replay(eaSref);
+
+        BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+
+        EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), 
null))
+            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
+        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        EasyMock.replay(bc);
+
+
+        RemoteServiceAdminEvent event = new RemoteServiceAdminEvent(
+                RemoteServiceAdminEvent.EXPORT_ERROR,
+                bundle,
+                er,
+                exportException
+        );
+        new EventAdminHelper(bc).remoteAdminEvent(event);
+        EasyMock.verify(epd, sref, er, ea, eaSref, bc);
+    }
+}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/features/src/main/resources/features.xml
----------------------------------------------------------------------
diff --git a/features/src/main/resources/features.xml 
b/features/src/main/resources/features.xml
index bf55d79..be79a3b 100644
--- a/features/src/main/resources/features.xml
+++ b/features/src/main/resources/features.xml
@@ -1,11 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.0.0"; 
name="aries-rsa-${project.version}">
+<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0"; 
name="aries-rsa-${project.version}">
 
     <feature name="aries-rsa-core" version="${project.version}">
-        <feature>eventadmin</feature>
         
<bundle>mvn:org.apache.aries.rsa/org.apache.aries.rsa.spi/${project.version}</bundle>
         
<bundle>mvn:org.apache.aries.rsa/org.apache.aries.rsa.core/${project.version}</bundle>
         
<bundle>mvn:org.apache.aries.rsa/org.apache.aries.rsa.topology-manager/${project.version}</bundle>
+        <conditional>
+            <condition>eventadmin</condition>
+            
<bundle>mvn:org.apache.aries.rsa/org.apache.aries.rsa.eapub/${project.version}</bundle>
+        </conditional>
     </feature>
     
     <feature name="aries-rsa-provider-tcp" version="${project.version}">

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 6886ea3..c519e37 100644
--- a/pom.xml
+++ b/pom.xml
@@ -78,6 +78,7 @@
         <module>parent</module>
         <module>spi</module>
         <module>rsa</module>
+        <module>eapub</module>
         <module>topology-manager</module>
         <module>provider</module>
         <module>discovery</module>

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
deleted file mode 100644
index e59c0ef..0000000
--- a/rsa/src/main/java/org/apache/aries/rsa/core/EventAdminHelper.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.aries.rsa.core;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
-import org.osgi.service.remoteserviceadmin.EndpointDescription;
-import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class EventAdminHelper {
-
-    private static final Logger LOG = 
LoggerFactory.getLogger(EventAdminHelper.class);
-
-    private BundleContext bctx;
-
-    public EventAdminHelper(BundleContext bc) {
-        bctx = bc;
-    }
-
-    private Event createEvent(Map<String, Object> props, String type) {
-        String topic = "org/osgi/service/remoteserviceadmin/" + type;
-        props.put("bundle", bctx.getBundle());
-        props.put("bundle.id", bctx.getBundle().getBundleId());
-        props.put("bundle.symbolicname", bctx.getBundle().getSymbolicName());
-
-        String version = 
(String)bctx.getBundle().getHeaders().get("Bundle-Version");
-        Version v = version != null ? new Version(version) : 
Version.emptyVersion;
-        setIfNotNull(props, "bundle.version", v);
-
-        return new Event(topic, props);
-    }
-
-    public void notifyEventAdmin(RemoteServiceAdminEvent rsae) {
-        String topic = remoteServiceAdminEventTypeToString(rsae.getType());
-
-        Map<String, Object> props = new HashMap<String, Object>();
-        setIfNotNull(props, "cause", rsae.getException());
-
-        EndpointDescription endpoint = null;
-        if (rsae.getImportReference() != null) {
-            endpoint = 
((ImportRegistrationImpl)rsae.getImportReference()).getImportedEndpointAlways();
-            setIfNotNull(props, "import.registration", endpoint);
-        } else if (rsae.getExportReference() != null) {
-            endpoint = rsae.getExportReference().getExportedEndpoint();
-            setIfNotNull(props, "export.registration", endpoint);
-        }
-
-        if (endpoint != null) {
-            setIfNotNull(props, "service.remote.id", endpoint.getServiceId());
-            setIfNotNull(props, "service.remote.uuid", 
endpoint.getFrameworkUUID());
-            setIfNotNull(props, "service.remote.uri", endpoint.getId());
-            setIfNotNull(props, "objectClass", 
endpoint.getInterfaces().toArray());
-            setIfNotNull(props, "service.imported.configs", 
endpoint.getConfigurationTypes());
-        }
-        props.put("timestamp", System.currentTimeMillis());
-        props.put("event", rsae);
-
-        Event event = createEvent(props, topic);
-        notifyEventAdmins(topic, event);
-    }
-
-    @SuppressWarnings({
-     "rawtypes", "unchecked"
-    })
-    private void notifyEventAdmins(String topic, Event event) {
-        ServiceReference[] refs = null;
-        try {
-            refs = bctx.getAllServiceReferences(EventAdmin.class.getName(), 
null);
-        } catch (InvalidSyntaxException e) {
-            LOG.error("Failed to get EventAdmin: " + e.getMessage(), e);
-        }
-
-        if (refs != null) {
-            LOG.debug("Publishing event to {} EventAdmins; Topic:[{}]", 
refs.length, topic);
-            for (ServiceReference serviceReference : refs) {
-                EventAdmin eventAdmin = (EventAdmin) 
bctx.getService(serviceReference);
-                try {
-                    eventAdmin.postEvent(event);
-                } finally {
-                    if (eventAdmin != null) {
-                        bctx.ungetService(serviceReference);
-                    }
-                }
-            }
-        }
-    }
-
-    private <K, V> void setIfNotNull(Map<K, V> map, K key, V val) {
-        if (val != null) {
-            map.put(key, val);
-        }
-    }
-
-    private static String remoteServiceAdminEventTypeToString(int type) {
-        String retval;
-        switch (type) {
-        case RemoteServiceAdminEvent.EXPORT_ERROR:
-            retval = "EXPORT_ERROR";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_REGISTRATION:
-            retval = "EXPORT_REGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_UNREGISTRATION:
-            retval = "EXPORT_UNREGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.EXPORT_WARNING:
-            retval = "EXPORT_WARNING";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_ERROR:
-            retval = "IMPORT_ERROR";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_REGISTRATION:
-            retval = "IMPORT_REGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_UNREGISTRATION:
-            retval = "IMPORT_UNREGISTRATION";
-            break;
-        case RemoteServiceAdminEvent.IMPORT_WARNING:
-            retval = "IMPORT_WARNING";
-            break;
-        default:
-            retval = "UNKNOWN_EVENT";
-        }
-        return retval;
-    }
-}

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
----------------------------------------------------------------------
diff --git a/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java 
b/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
index 4098201..0d9453b 100644
--- a/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
+++ b/rsa/src/main/java/org/apache/aries/rsa/core/EventProducer.java
@@ -24,7 +24,9 @@ import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
+import org.osgi.service.remoteserviceadmin.ExportReference;
 import org.osgi.service.remoteserviceadmin.ExportRegistration;
+import org.osgi.service.remoteserviceadmin.ImportReference;
 import org.osgi.service.remoteserviceadmin.ImportRegistration;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
@@ -35,11 +37,9 @@ public class EventProducer {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(EventProducer.class);
     private final BundleContext bctx;
-    private final EventAdminHelper eaHelper;
 
     public EventProducer(BundleContext bc) {
         bctx = bc;
-        eaHelper = new EventAdminHelper(bctx);
     }
 
     protected void publishNotification(List<ExportRegistration> erl) {
@@ -49,35 +49,41 @@ public class EventProducer {
     }
 
     protected void publishNotification(ExportRegistration er) {
-        int type = er.getException() == null
-            ? RemoteServiceAdminEvent.EXPORT_REGISTRATION
-            : RemoteServiceAdminEvent.EXPORT_ERROR;
-        notify(type, null, er);
+        if (er.getException() == null) {
+            notify(RemoteServiceAdminEvent.EXPORT_REGISTRATION, 
er.getExportReference(), null);
+        } else {
+            notify(RemoteServiceAdminEvent.EXPORT_ERROR, (ExportReference) 
null, er.getException());
+        }
     }
 
     protected void publishNotification(ImportRegistration ir) {
-        int type = ir.getException() == null
-            ? RemoteServiceAdminEvent.IMPORT_REGISTRATION
-            : RemoteServiceAdminEvent.IMPORT_ERROR;
-        notify(type, ir, null);
+        if (ir.getException() == null) {
+            notify(RemoteServiceAdminEvent.IMPORT_REGISTRATION, 
ir.getImportReference(), null);
+        } else {
+            notify(RemoteServiceAdminEvent.IMPORT_ERROR, (ImportReference) 
null, ir.getException());
+        }
     }
 
     public void notifyRemoval(ExportRegistration er) {
-        notify(RemoteServiceAdminEvent.EXPORT_UNREGISTRATION, null, er);
+        notify(RemoteServiceAdminEvent.EXPORT_UNREGISTRATION, 
er.getExportReference(), null);
     }
 
     public void notifyRemoval(ImportRegistration ir) {
-        notify(RemoteServiceAdminEvent.IMPORT_UNREGISTRATION, ir, null);
+        notify(RemoteServiceAdminEvent.IMPORT_UNREGISTRATION, 
ir.getImportReference(), null);
     }
 
-    // only one of ir or er must be set, and the other must be null
-    private void notify(int type, ImportRegistration ir, ExportRegistration 
er) {
+    private void notify(int type, ExportReference er, Throwable ex) {
+        try {
+            RemoteServiceAdminEvent event = new RemoteServiceAdminEvent(type, 
bctx.getBundle(), er, ex);
+            notifyListeners(event);
+        } catch (IllegalStateException ise) {
+            LOG.debug("can't send notifications since bundle context is no 
longer valid");
+        }
+    }
+    private void notify(int type, ImportReference ir, Throwable ex) {
         try {
-            RemoteServiceAdminEvent event = ir != null
-                ? new RemoteServiceAdminEvent(type, bctx.getBundle(), 
ir.getImportReference(), ir.getException())
-                : new RemoteServiceAdminEvent(type, bctx.getBundle(), 
er.getExportReference(), er.getException());
+            RemoteServiceAdminEvent event = new RemoteServiceAdminEvent(type, 
bctx.getBundle(), ir, ex);
             notifyListeners(event);
-            eaHelper.notifyEventAdmin(event);
         } catch (IllegalStateException ise) {
             LOG.debug("can't send notifications since bundle context is no 
longer valid");
         }

http://git-wip-us.apache.org/repos/asf/aries-rsa/blob/96544475/rsa/src/test/java/org/apache/aries/rsa/core/EventProducerTest.java
----------------------------------------------------------------------
diff --git a/rsa/src/test/java/org/apache/aries/rsa/core/EventProducerTest.java 
b/rsa/src/test/java/org/apache/aries/rsa/core/EventProducerTest.java
index 2714a65..8b00534 100644
--- a/rsa/src/test/java/org/apache/aries/rsa/core/EventProducerTest.java
+++ b/rsa/src/test/java/org/apache/aries/rsa/core/EventProducerTest.java
@@ -32,13 +32,11 @@ import org.junit.Test;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
-import org.osgi.framework.Version;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
 import org.osgi.service.remoteserviceadmin.EndpointDescription;
 import org.osgi.service.remoteserviceadmin.ExportReference;
 import org.osgi.service.remoteserviceadmin.ExportRegistration;
 import org.osgi.service.remoteserviceadmin.RemoteServiceAdminEvent;
+import org.osgi.service.remoteserviceadmin.RemoteServiceAdminListener;
 
 @SuppressWarnings({"rawtypes", "unchecked"})
 public class EventProducerTest {
@@ -46,8 +44,8 @@ public class EventProducerTest {
     
     @Test
     public void testPublishNotification() throws Exception {
-        RemoteServiceAdminCore remoteServiceAdminCore = 
EasyMock.createNiceMock(RemoteServiceAdminCore.class);
-        EasyMock.replay(remoteServiceAdminCore);
+        RemoteServiceAdminCore rsaCore = 
EasyMock.createNiceMock(RemoteServiceAdminCore.class);
+        EasyMock.replay(rsaCore);
 
         final EndpointDescription epd = 
EasyMock.createNiceMock(EndpointDescription.class);
         
EasyMock.expect(epd.getServiceId()).andReturn(Long.MAX_VALUE).anyTimes();
@@ -69,30 +67,12 @@ public class EventProducerTest {
         EasyMock.expect(bundle.getHeaders()).andReturn(headers).anyTimes();
         EasyMock.replay(bundle);
 
-        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
-        ea.postEvent((Event) EasyMock.anyObject());
+        RemoteServiceAdminListener rsal = 
EasyMock.createNiceMock(RemoteServiceAdminListener.class);
+        rsal.remoteAdminEvent((RemoteServiceAdminEvent) EasyMock.anyObject());
         EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
             @Override
             public Object answer() throws Throwable {
-                Event event = (Event) EasyMock.getCurrentArguments()[0];
-
-                
Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_REGISTRATION", 
event.getTopic());
-                Assert.assertSame(bundle, event.getProperty("bundle"));
-                Assert.assertEquals(42L, event.getProperty("bundle.id"));
-                Assert.assertEquals("test.bundle", 
event.getProperty("bundle.symbolicname"));
-                Assert.assertEquals(new Version(1, 2, 3, "test"), 
event.getProperty("bundle.version"));
-                Assert.assertNull(event.getProperty("cause"));
-                Assert.assertEquals(epd, 
event.getProperty("export.registration"));
-
-                Assert.assertEquals(Long.MAX_VALUE, 
event.getProperty("service.remote.id"));
-                Assert.assertEquals(uuid, 
event.getProperty("service.remote.uuid"));
-                Assert.assertEquals("foo://bar", 
event.getProperty("service.remote.uri"));
-                Assert.assertTrue(Arrays.equals(interfaces.toArray(new 
String[] {}),
-                                                (String[]) 
event.getProperty("objectClass")));
-
-                Assert.assertNotNull(event.getProperty("timestamp"));
-
-                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
event.getProperty("event");
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
EasyMock.getCurrentArguments()[0];
                 Assert.assertNull(rsae.getException());
                 
Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_REGISTRATION, 
rsae.getType());
                 Assert.assertSame(bundle, rsae.getSource());
@@ -103,24 +83,27 @@ public class EventProducerTest {
                 return null;
             }
         });
-        EasyMock.replay(ea);
+        EasyMock.replay(rsal);
 
-        ServiceReference eaSref = 
EasyMock.createNiceMock(ServiceReference.class);
-        EasyMock.replay(eaSref);
+        ServiceReference rsalSref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.expect(rsalSref.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.replay(rsalSref);
 
         BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
         EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
-        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), 
null))
-            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
-        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        
EasyMock.expect(bc.getServiceReferences(RemoteServiceAdminListener.class.getName(),
 null))
+                .andReturn(new ServiceReference[] {rsalSref}).anyTimes();
+        EasyMock.expect(bc.getService(rsalSref)).andReturn(rsal).anyTimes();
         Endpoint endpoint = EasyMock.mock(Endpoint.class);
         EasyMock.expect(endpoint.description()).andReturn(epd);
         EasyMock.replay(endpoint);
         EasyMock.replay(bc);
         EventProducer eventProducer = new EventProducer(bc);
 
-        ExportRegistrationImpl ereg = new ExportRegistrationImpl(sref, 
endpoint, remoteServiceAdminCore);
+        ExportRegistrationImpl ereg = new ExportRegistrationImpl(sref, 
endpoint, rsaCore);
         eventProducer.publishNotification(ereg);
+
+        EasyMock.verify(rsaCore, sref, bundle, rsal, rsalSref, bc);
     }
 
     @Test
@@ -142,48 +125,39 @@ public class EventProducerTest {
 
         final Exception exportException = new Exception();
 
-        EventAdmin ea = EasyMock.createNiceMock(EventAdmin.class);
-        ea.postEvent((Event) EasyMock.anyObject());
+        RemoteServiceAdminListener rsal = 
EasyMock.createNiceMock(RemoteServiceAdminListener.class);
+        rsal.remoteAdminEvent((RemoteServiceAdminEvent) EasyMock.anyObject());
         EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
             @Override
             public Object answer() throws Throwable {
-                Event event = (Event) EasyMock.getCurrentArguments()[0];
-
-                
Assert.assertEquals("org/osgi/service/remoteserviceadmin/EXPORT_ERROR", 
event.getTopic());
-                Assert.assertSame(bundle, event.getProperty("bundle"));
-                Assert.assertEquals(42L, event.getProperty("bundle.id"));
-                Assert.assertEquals("test.bundle", 
event.getProperty("bundle.symbolicname"));
-                Assert.assertEquals(new Version("0"), 
event.getProperty("bundle.version"));
-                Assert.assertSame(exportException, event.getProperty("cause"));
-                Assert.assertEquals(endpoint, 
event.getProperty("export.registration"));
-                Assert.assertTrue(Arrays.equals(new String[] {"org.foo.Bar"},
-                                                (String[]) 
event.getProperty("objectClass")));
-
-                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
event.getProperty("event");
+                RemoteServiceAdminEvent rsae = (RemoteServiceAdminEvent) 
EasyMock.getCurrentArguments()[0];
                 Assert.assertSame(exportException, rsae.getException());
                 Assert.assertEquals(RemoteServiceAdminEvent.EXPORT_ERROR, 
rsae.getType());
                 Assert.assertSame(bundle, rsae.getSource());
-                ExportReference er = rsae.getExportReference();
-                Assert.assertSame(endpoint, er.getExportedEndpoint());
-                Assert.assertSame(sref, er.getExportedService());
+                Assert.assertNull(rsae.getImportReference());
+                Assert.assertNull(rsae.getExportReference());
 
                 return null;
             }
         });
-        EasyMock.replay(ea);
+        EasyMock.replay(rsal);
 
-        ServiceReference eaSref = 
EasyMock.createNiceMock(ServiceReference.class);
-        EasyMock.replay(eaSref);
+        ServiceReference rsalSref = 
EasyMock.createNiceMock(ServiceReference.class);
+        EasyMock.expect(rsalSref.getBundle()).andReturn(bundle).anyTimes();
+        EasyMock.replay(rsalSref);
 
         BundleContext bc = EasyMock.createNiceMock(BundleContext.class);
+
         EasyMock.expect(bc.getBundle()).andReturn(bundle).anyTimes();
-        EasyMock.expect(bc.getAllServiceReferences(EventAdmin.class.getName(), 
null))
-            .andReturn(new ServiceReference[] {eaSref}).anyTimes();
-        EasyMock.expect(bc.getService(eaSref)).andReturn(ea).anyTimes();
+        
EasyMock.expect(bc.getServiceReferences(RemoteServiceAdminListener.class.getName(),
 null))
+                .andReturn(new ServiceReference[] {rsalSref}).anyTimes();
+        EasyMock.expect(bc.getService(rsalSref)).andReturn(rsal).anyTimes();
         EasyMock.replay(bc);
         EventProducer eventProducer = new EventProducer(bc);
 
         ExportRegistrationImpl ereg = new ExportRegistrationImpl(rsaCore, 
exportException);
         
eventProducer.publishNotification(Arrays.<ExportRegistration>asList(ereg));
+
+        EasyMock.verify(rsaCore, sref, bundle, rsal, rsalSref, bc);
     }
 }

Reply via email to