You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2017/11/21 16:40:10 UTC

svn commit: r1815955 - in /felix/trunk/osgi-r7/http: base/src/main/java/org/apache/felix/http/base/internal/logger/ base/src/main/java/org/apache/felix/http/base/internal/whiteboard/ jetty/ jetty/src/main/java/org/apache/felix/http/jetty/internal/

Author: cziegeler
Date: Tue Nov 21 16:40:10 2017
New Revision: 1815955

URL: http://svn.apache.org/viewvc?rev=1815955&view=rev
Log:
FELIX-5746 : Make optional dependencies runtime optional

Modified:
    felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/logger/SystemLogger.java
    felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FailureStateHandler.java
    felix/trunk/osgi-r7/http/jetty/pom.xml
    felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
    felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/WebEvent.java

Modified: felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/logger/SystemLogger.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/logger/SystemLogger.java?rev=1815955&r1=1815954&r2=1815955&view=diff
==============================================================================
--- felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/logger/SystemLogger.java (original)
+++ felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/logger/SystemLogger.java Tue Nov 21 16:40:10 2017
@@ -18,7 +18,11 @@
  */
 package org.apache.felix.http.base.internal.logger;
 
+import java.lang.reflect.Array;
+
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.log.LogService;
 
@@ -37,40 +41,121 @@ public final class SystemLogger
         }
     }
 
-    private static void log(final int level, final String message, final Throwable cause) {
+    private static String getMessage(final ServiceReference<?> ref, final String message)
+    {
+        if ( ref == null )
+        {
+            return message;
+        }
+        final Bundle bundle = ref.getBundle();
+        final StringBuilder ib = new StringBuilder();
+        ib.append("[ServiceReference ");
+        ib.append(String.valueOf(ref.getProperty(Constants.SERVICE_ID)));
+        ib.append(" from bundle ");
+        if ( bundle == null )
+        {
+            ib.append("<uninstalled>");
+        }
+        else
+        {
+            ib.append(bundle.getBundleId());
+            if ( bundle.getSymbolicName() != null )
+            {
+                ib.append(" : ");
+                ib.append(bundle.getSymbolicName());
+                ib.append(":");
+                ib.append(bundle.getVersion());
+            }
+        }
+        ib.append(" ref=");
+        ib.append(ref);
+        ib.append(" properties={");
+        boolean first = true;
+        for(final String name : ref.getPropertyKeys())
+        {
+            if ( first )
+            {
+                first = false;
+            }
+            else
+            {
+                ib.append(", ");
+            }
+            final Object val = ref.getProperty(name);
+            ib.append(name);
+            ib.append("=");
+            if ( val.getClass().isArray() )
+            {
+                boolean fa = true;
+                ib.append('[');
+                for(int i=0;i<Array.getLength(val);i++)
+                {
+                    if ( fa )
+                    {
+                        fa = false;
+                    }
+                    else
+                    {
+                        ib.append(", ");
+                    }
+                    ib.append(Array.get(val, i));
+                }
+            ib.append(']');
+            }
+            else
+            {
+                ib.append(val);
+            }
+        }
+        ib.append("}] ");
+        ib.append(message);
+
+        return ib.toString();
+    }
+
+    private static void log(
+            final int level,
+            final ServiceReference<?> ref,
+            final String message,
+            final Throwable cause) {
         final LogServiceEnabledLogger l = LOGGER;
         if ( l != null ) {
-            l.log(level, message, cause);
+            l.log(level, getMessage(ref, message), cause);
         }
     }
 
     public static void debug(final String message)
     {
-        log(LogService.LOG_DEBUG, message, null);
+        log(LogService.LOG_DEBUG, null, message, null);
+    }
+
+    public static void debug(final ServiceReference<?> ref,  final String message)
+    {
+        log(LogService.LOG_DEBUG, ref, message, null);
     }
 
     public static void debug(final String message, final Throwable cause)
     {
-        log(LogService.LOG_DEBUG, message, cause);
+        log(LogService.LOG_DEBUG, null, message, cause);
     }
 
     public static void info(final String message)
     {
-        log(LogService.LOG_INFO, message, null);
+        log(LogService.LOG_INFO, null, message, null);
     }
 
     public static void warning(final String message, final Throwable cause)
     {
-        log(LogService.LOG_WARNING, message, cause);
+        log(LogService.LOG_WARNING, null, message, cause);
     }
 
     public static void error(final String message, final Throwable cause)
     {
-        log(LogService.LOG_ERROR, message, cause);
+        log(LogService.LOG_ERROR, null, message, cause);
     }
 
     public static void error(final ServiceReference<?> ref, final String message, final Throwable cause)
     {
-        log(LogService.LOG_ERROR, message, cause);
+        log(LogService.LOG_ERROR, ref, message, cause);
     }
 }

Modified: felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FailureStateHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FailureStateHandler.java?rev=1815955&r1=1815954&r2=1815955&view=diff
==============================================================================
--- felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FailureStateHandler.java (original)
+++ felix/trunk/osgi-r7/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/FailureStateHandler.java Tue Nov 21 16:40:10 2017
@@ -23,7 +23,6 @@ import static org.osgi.service.http.runt
 import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_UNKNOWN;
 import static org.osgi.service.http.runtime.dto.DTOConstants.FAILURE_REASON_VALIDATION_FAILED;
 
-import java.lang.reflect.Array;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -33,7 +32,6 @@ import java.util.concurrent.ConcurrentHa
 import org.apache.felix.http.base.internal.logger.SystemLogger;
 import org.apache.felix.http.base.internal.runtime.AbstractInfo;
 import org.apache.felix.http.base.internal.runtime.dto.FailedDTOHolder;
-import org.osgi.framework.Bundle;
 import org.osgi.framework.ServiceReference;
 
 public class FailureStateHandler {
@@ -70,102 +68,41 @@ public class FailureStateHandler {
 
     public void addFailure(final AbstractInfo<?> info, final long contextId, final int reason, final Exception ex)
     {
-    	final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
+        final String type = info.getClass().getSimpleName().substring(0, info.getClass().getSimpleName().length() - 4);
         final String serviceInfo;
         final ServiceReference<?> ref = info.getServiceReference();
         if ( ref == null ) {
-            serviceInfo = "with id " + String.valueOf(info.getServiceId());
+            serviceInfo = " with id " + String.valueOf(info.getServiceId());
         } else {
-        	    final Bundle bundle = ref.getBundle();
-        	    final StringBuilder ib = new StringBuilder();
-        	    ib.append(String.valueOf(info.getServiceId()));
-        	    ib.append(" (bundle ");
-        	    if ( bundle == null )
-        	    {
-        	        ib.append("<uninstalled>");
-        	    }
-        	    else
-        	    {
-        	        ib.append(bundle.getBundleId());
-        	        if ( bundle.getSymbolicName() != null )
-        	        {
-        	            ib.append(" : ");
-        	            ib.append(bundle.getSymbolicName());
-        	            ib.append(":");
-        	            ib.append(bundle.getVersion());
-        	        }
-        	    }
-        	    ib.append(" reference=");
-        	    ib.append(ref);
-        	    ib.append(" properties={");
-        	    boolean first = true;
-        	    for(final String name : ref.getPropertyKeys())
-        	    {
-        	        if ( first )
-        	        {
-        	            first = false;
-        	        }
-        	        else
-        	        {
-                        ib.append(", ");
-        	        }
-        	        final Object val = ref.getProperty(name);
-        	        ib.append(name);
-        	        ib.append("=");
-        	        if ( val.getClass().isArray() )
-        	        {
-        	            boolean fa = true;
-        	            ib.append('[');
-        	            for(int i=0;i<Array.getLength(val);i++)
-        	            {
-        	                if ( fa )
-        	                {
-        	                    fa = false;
-        	                }
-        	                else
-        	                {
-        	                    ib.append(", ");
-        	                }
-        	                ib.append(Array.get(val, i));
-        	            }
-                    ib.append(']');
-        	        }
-        	        else
-        	        {
-        	            ib.append(val);
-        	        }
-        	    }
-        	    ib.append("})");
-
-        	    serviceInfo = ib.toString();
+            serviceInfo = "";
         }
         if ( reason == FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING )
         {
-            SystemLogger.debug("Ignoring unmatching " + type + " service " + serviceInfo);
+            SystemLogger.debug(ref, "Ignoring unmatching " + type + " service" + serviceInfo);
         }
         else if ( reason == FAILURE_REASON_SHADOWED_BY_OTHER_SERVICE )
         {
-            SystemLogger.debug("Ignoring shadowed " + type + " service " + serviceInfo);
+            SystemLogger.debug(ref, "Ignoring shadowed " + type + " service" + serviceInfo);
         }
         else if ( reason == FAILURE_REASON_SERVICE_NOT_GETTABLE )
         {
-            SystemLogger.error("Ignoring ungettable " + type + " service " + serviceInfo, ex);
+            SystemLogger.error(ref, "Ignoring ungettable " + type + " service" + serviceInfo, ex);
         }
         else if ( reason == FAILURE_REASON_VALIDATION_FAILED )
         {
-            SystemLogger.debug("Ignoring invalid " + type + " service " + serviceInfo);
+            SystemLogger.debug(ref, "Ignoring invalid " + type + " service" + serviceInfo);
         }
         else if ( reason == FAILURE_REASON_NO_SERVLET_CONTEXT_MATCHING )
         {
-            SystemLogger.debug("Ignoring unmatched " + type + " service " + serviceInfo);
+            SystemLogger.debug(ref, "Ignoring unmatched " + type + " service" + serviceInfo);
         }
         else if ( reason == FAILURE_REASON_SERVLET_CONTEXT_FAILURE )
         {
-            SystemLogger.debug("Servlet context " + String.valueOf(contextId) + " failure: Ignoring " + type + " service " + serviceInfo);
+            SystemLogger.debug(ref,  "Servlet context " + String.valueOf(contextId) + " failure: Ignoring " + type + " service" + serviceInfo);
         }
         else if ( reason == FAILURE_REASON_UNKNOWN)
         {
-            SystemLogger.error("Exception while registering " + type + " service " + serviceInfo, ex);
+            SystemLogger.error(ref, "Exception while registering " + type + " service" + serviceInfo, ex);
         }
 
         FailureStatus status = serviceFailures.get(info);

Modified: felix/trunk/osgi-r7/http/jetty/pom.xml
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/http/jetty/pom.xml?rev=1815955&r1=1815954&r2=1815955&view=diff
==============================================================================
--- felix/trunk/osgi-r7/http/jetty/pom.xml (original)
+++ felix/trunk/osgi-r7/http/jetty/pom.xml Tue Nov 21 16:40:10 2017
@@ -83,9 +83,9 @@
                             org.mortbay.log;resolution:=optional;version="[6.1,7)",
                             org.mortbay.util.ajax;resolution:=optional;version="[6.1,7)",
                             org.osgi.service.cm;version="[1.3,2)",                        	
-                            org.osgi.service.event;version="[1.2,2)",
+                            org.osgi.service.event;resolution:=optional;version="[1.2,2)",
                             org.osgi.service.log;resolution:=optional;version="[1.3,2)",
-                            org.osgi.service.metatype;version="[1.1,2)";resolution:=optional,
+                            org.osgi.service.metatype;resolution:=optional;version="[1.1,2)",
                             org.osgi.service.useradmin;resolution:=optional,
                             org.apache.felix.http.api;version="[2.0,2.1)",
                             org.osgi.service.http;version="[1.2.1,1.3)",
@@ -95,6 +95,7 @@
                             *
                         </Import-Package>
                         <DynamicImport-Package>
+                            org.osgi.service.event;version="[1.2,2)",
                             org.osgi.service.log;version="[1.3,2)",
                             org.osgi.service.metatype;version="[1.1,2)"
                         </DynamicImport-Package>

Modified: felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java?rev=1815955&r1=1815954&r2=1815955&view=diff
==============================================================================
--- felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java (original)
+++ felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/JettyService.java Tue Nov 21 16:40:10 2017
@@ -69,8 +69,6 @@ import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.event.Event;
-import org.osgi.service.event.EventAdmin;
 import org.osgi.service.http.runtime.HttpServiceRuntimeConstants;
 import org.osgi.util.tracker.BundleTracker;
 import org.osgi.util.tracker.BundleTrackerCustomizer;
@@ -100,16 +98,15 @@ public final class JettyService extends
     private volatile ContextHandlerCollection parent;
     private volatile MBeanServerTracker mbeanServerTracker;
     private volatile BundleTracker<Deployment> bundleTracker;
-    private volatile ServiceTracker<EventAdmin, EventAdmin> eventAdmintTracker;
+    private volatile ServiceTracker<Object, Object> eventAdmintTracker;
     private volatile ConnectorFactoryTracker connectorTracker;
     private volatile RequestLogTracker requestLogTracker;
     private volatile LogServiceRequestLog osgiRequestLog;
     private volatile FileRequestLog fileRequestLog;
     private volatile LoadBalancerCustomizerFactoryTracker loadBalancerCustomizerTracker;
     private volatile CustomizerWrapper customizerWrapper;
-    private volatile EventAdmin eventAdmin;
     private boolean registerManagedService = true;
-
+    private volatile Object eventAdmin;
 
     public JettyService(final BundleContext context,
             final HttpServiceController controller)
@@ -134,9 +131,9 @@ public final class JettyService extends
             final HttpServiceController controller,
             final Dictionary<String,?> props)
     {
-    	this(context, controller);
-    	this.config.update(props);
-    	this.registerManagedService = false;
+        this(context, controller);
+   	    this.config.update(props);
+   	    this.registerManagedService = false;
     }
 
     public void start() throws Exception
@@ -151,28 +148,29 @@ public final class JettyService extends
 			        new JettyManagedService(this), props);
         }
 
-        this.eventAdmintTracker = new ServiceTracker<>(this.context, EventAdmin.class,
-                new ServiceTrackerCustomizer<EventAdmin, EventAdmin>()
+        // we use the class name as a String to make the dependency on event admin optional
+        this.eventAdmintTracker = new ServiceTracker<>(this.context, "org.osgi.service.event.EventAdmin",
+                new ServiceTrackerCustomizer<Object, Object>()
         {
             @Override
-            public EventAdmin addingService(final ServiceReference<EventAdmin> reference)
+            public Object addingService(final ServiceReference<Object> reference)
             {
-                EventAdmin service = context.getService(reference);
-                modifiedService(reference, service);
+                final Object service = context.getService(reference);
+                eventAdmin = service;
                 return service;
             }
 
             @Override
-            public void modifiedService(final ServiceReference<EventAdmin> reference, final EventAdmin service)
+            public void modifiedService(final ServiceReference<Object> reference, final Object service)
             {
-                eventAdmin = service;
+                // nothing to do
             }
 
             @Override
-            public void removedService(final ServiceReference<EventAdmin> reference, final EventAdmin service)
+            public void removedService(final ServiceReference<Object> reference, final Object service)
             {
-                context.ungetService(reference);
                 eventAdmin = null;
+                context.ungetService(reference);
             }
         });
         this.eventAdmintTracker.open();
@@ -799,14 +797,14 @@ public final class JettyService extends
 
     private Deployment startWebAppBundle(Bundle bundle, String contextPath)
     {
-        postEvent(WebEvent.DEPLOYING(bundle, this.context.getBundle()));
+        postEvent(WebEvent.TOPIC_DEPLOYING, bundle, this.context.getBundle(), null, null, null);
 
         // check existing deployments
         Deployment deployment = this.deployments.get(contextPath);
         if (deployment != null)
         {
             SystemLogger.warning(String.format("Web application bundle %s has context path %s which is already registered", bundle.getSymbolicName(), contextPath), null);
-            postEvent(WebEvent.FAILED(bundle, this.context.getBundle(), null, contextPath, deployment.getBundle().getBundleId()));
+            postEvent(WebEvent.TOPIC_FAILED, bundle, this.context.getBundle(), null, contextPath, deployment.getBundle().getBundleId());
             return null;
         }
 
@@ -814,7 +812,7 @@ public final class JettyService extends
         if (contextPath.equals("/"))
         {
             SystemLogger.warning(String.format("Web application bundle %s has context path %s which is reserved", bundle.getSymbolicName(), contextPath), null);
-            postEvent(WebEvent.FAILED(bundle, this.context.getBundle(), null, contextPath, this.context.getBundle().getBundleId()));
+            postEvent(WebEvent.TOPIC_FAILED, bundle, this.context.getBundle(), null, contextPath, this.context.getBundle().getBundleId());
             return null;
         }
 
@@ -824,7 +822,7 @@ public final class JettyService extends
             if (contextPath.startsWith(path))
             {
                 SystemLogger.warning(String.format("Web application bundle %s has context path %s which clashes with excluded path prefix %s", bundle.getSymbolicName(), contextPath, path), null);
-                postEvent(WebEvent.FAILED(bundle, this.context.getBundle(), null, path, null));
+                postEvent(WebEvent.TOPIC_FAILED, bundle, this.context.getBundle(), null, path, null);
                 return null;
             }
         }
@@ -866,12 +864,12 @@ public final class JettyService extends
                     props.put(WEB_CONTEXT_PATH, deployment.getContextPath());
                     deployment.setRegistration(webAppBundle.getBundleContext().registerService(ServletContext.class, context.getServletContext(), props));
 
-                    postEvent(WebEvent.DEPLOYED(webAppBundle, extenderBundle));
+                    postEvent(WebEvent.TOPIC_DEPLOYED, webAppBundle, extenderBundle, null, null, null);
                 }
                 catch (Exception e)
                 {
                     SystemLogger.error(String.format("Deploying web application bundle %s failed.", webAppBundle.getSymbolicName()), e);
-                    postEvent(WebEvent.FAILED(webAppBundle, extenderBundle, e, null, null));
+                    postEvent(WebEvent.TOPIC_FAILED, webAppBundle, extenderBundle, e, null, null);
                     deployment.setContext(null);
                 }
             }
@@ -897,7 +895,7 @@ public final class JettyService extends
 
                 try
                 {
-                    postEvent(WebEvent.UNDEPLOYING(webAppBundle, extenderBundle));
+                    postEvent(WebEvent.TOPIC_UNDEPLOYING, webAppBundle, extenderBundle, null, null, null);
 
                     context.getServletContext().removeAttribute(OSGI_BUNDLE_CONTEXT);
 
@@ -916,17 +914,23 @@ public final class JettyService extends
                 }
                 finally
                 {
-                    postEvent(WebEvent.UNDEPLOYED(webAppBundle, extenderBundle));
+                    postEvent(WebEvent.TOPIC_UNDEPLOYED, webAppBundle, extenderBundle, null, null, null);
                 }
             }
         });
     }
 
-    private void postEvent(Event event)
+    private void postEvent(final String topic,
+            final Bundle webAppBundle,
+            final Bundle extenderBundle,
+            final Throwable exception,
+            final String collision,
+            final Long collisionBundles)
     {
-        if (this.eventAdmin != null)
+        final Object ea = this.eventAdmin;
+        if (ea != null)
         {
-            this.eventAdmin.postEvent(event);
+            WebEvent.postEvent(ea, topic, webAppBundle, extenderBundle, exception, collision, collisionBundles);
         }
     }
 
@@ -937,7 +941,7 @@ public final class JettyService extends
         {
             if (deployment.getContext() == null)
             {
-                postEvent(WebEvent.DEPLOYING(deployment.getBundle(), this.context.getBundle()));
+                postEvent(WebEvent.TOPIC_DEPLOYING, deployment.getBundle(), this.context.getBundle(), null, null, null);
                 WebAppBundleContext context = new WebAppBundleContext(deployment.getContextPath(), deployment.getBundle(), this.getClass().getClassLoader());
                 deploy(deployment, context);
             }

Modified: felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/WebEvent.java
URL: http://svn.apache.org/viewvc/felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/WebEvent.java?rev=1815955&r1=1815954&r2=1815955&view=diff
==============================================================================
--- felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/WebEvent.java (original)
+++ felix/trunk/osgi-r7/http/jetty/src/main/java/org/apache/felix/http/jetty/internal/WebEvent.java Tue Nov 21 16:40:10 2017
@@ -16,21 +16,22 @@
  */
 package org.apache.felix.http.jetty.internal;
 
+import java.util.Dictionary;
+import java.util.Hashtable;
+
 import org.osgi.framework.Bundle;
 import org.osgi.service.event.Event;
+import org.osgi.service.event.EventAdmin;
 import org.osgi.service.event.EventConstants;
 
-import java.util.Dictionary;
-import java.util.Hashtable;
-
 public abstract class WebEvent
 {
     private static final String TOPIC_WEB_EVENT = "org/osgi/service/web";
-    private static final String TOPIC_DEPLOYING = TOPIC_WEB_EVENT + "/DEPLOYING";
-    private static final String TOPIC_DEPLOYED = TOPIC_WEB_EVENT + "/DEPLOYED";
-    private static final String TOPIC_UNDEPLOYING = TOPIC_WEB_EVENT + "/UNDEPLOYING";
-    private static final String TOPIC_UNDEPLOYED = TOPIC_WEB_EVENT + "/UNDEPLOYED";
-    private static final String TOPIC_FAILED = TOPIC_WEB_EVENT + "/FAILED";
+    public static final String TOPIC_DEPLOYING = TOPIC_WEB_EVENT + "/DEPLOYING";
+    public static final String TOPIC_DEPLOYED = TOPIC_WEB_EVENT + "/DEPLOYED";
+    public static final String TOPIC_UNDEPLOYING = TOPIC_WEB_EVENT + "/UNDEPLOYING";
+    public static final String TOPIC_UNDEPLOYED = TOPIC_WEB_EVENT + "/UNDEPLOYED";
+    public static final String TOPIC_FAILED = TOPIC_WEB_EVENT + "/FAILED";
 
     private static final String CONTEXT_PATH = "context.path";
     private static final String EXCEPTION = "exception";
@@ -44,29 +45,30 @@ public abstract class WebEvent
 
     private static final String HEADER_WEB_CONTEXT_PATH = "Web-ContextPath";
 
-    static Event DEPLOYING(Bundle webAppBundle, Bundle extenderBundle)
+    private static Dictionary<String, Object> createBaseProperties(final Bundle webAppBundle, final Bundle extenderBundle)
     {
-        return new Event(TOPIC_DEPLOYING, createBaseProperties(webAppBundle, extenderBundle));
-    }
-
-    static Event DEPLOYED(Bundle webAppBundle, Bundle extenderBundle)
-    {
-        return new Event(TOPIC_DEPLOYED, createBaseProperties(webAppBundle, extenderBundle));
-    }
-
-    static Event UNDEPLOYING(Bundle webAppBundle, Bundle extenderBundle)
-    {
-        return new Event(TOPIC_UNDEPLOYING, createBaseProperties(webAppBundle, extenderBundle));
-    }
-
-    static Event UNDEPLOYED(Bundle webAppBundle, Bundle extenderBundle)
-    {
-        return new Event(TOPIC_UNDEPLOYED, createBaseProperties(webAppBundle, extenderBundle));
+        Dictionary<String, Object> props = new Hashtable<>();
+        props.put(EventConstants.BUNDLE_SYMBOLICNAME, webAppBundle.getSymbolicName());
+        props.put(EventConstants.BUNDLE_ID, webAppBundle.getBundleId());
+        props.put(EventConstants.BUNDLE, webAppBundle);
+        props.put(EventConstants.BUNDLE_VERSION, webAppBundle.getVersion());
+        props.put(CONTEXT_PATH, webAppBundle.getHeaders().get(HEADER_WEB_CONTEXT_PATH));
+        props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
+        props.put(EXTENDER_BUNDLE, extenderBundle);
+        props.put(EXTENDER_BUNDLE_ID, extenderBundle.getBundleId());
+        props.put(EXTENDER_BUNDLE_SYMBOLICNAME, extenderBundle.getSymbolicName());
+        props.put(EXTENDER_BUNDLE_VERSION, extenderBundle.getVersion());
+        return props;
     }
 
-    static Event FAILED(Bundle webAppBundle, Bundle extenderBundle, Throwable exception, String collision, Long collisionBundles)
-    {
-        Dictionary<String, Object> props = createBaseProperties(webAppBundle, extenderBundle);
+    public static void postEvent(final Object eventAdmin,
+            final String topic,
+            final Bundle webAppBundle,
+            final Bundle extenderBundle,
+            final Throwable exception,
+            final String collision,
+            final Long collisionBundles) {
+        final Dictionary<String, Object> props = createBaseProperties(webAppBundle, extenderBundle);
         if (exception != null)
         {
             props.put(EXCEPTION, exception);
@@ -79,22 +81,7 @@ public abstract class WebEvent
         {
             props.put(COLLISION_BUNDLES, collisionBundles);
         }
-        return new Event(TOPIC_FAILED, props);
-    }
-
-    private static Dictionary<String, Object> createBaseProperties(Bundle webAppBundle, Bundle extenderBundle)
-    {
-        Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put(EventConstants.BUNDLE_SYMBOLICNAME, webAppBundle.getSymbolicName());
-        props.put(EventConstants.BUNDLE_ID, webAppBundle.getBundleId());
-        props.put(EventConstants.BUNDLE, webAppBundle);
-        props.put(EventConstants.BUNDLE_VERSION, webAppBundle.getVersion());
-        props.put(CONTEXT_PATH, webAppBundle.getHeaders().get(HEADER_WEB_CONTEXT_PATH));
-        props.put(EventConstants.TIMESTAMP, System.currentTimeMillis());
-        props.put(EXTENDER_BUNDLE, extenderBundle);
-        props.put(EXTENDER_BUNDLE_ID, extenderBundle.getBundleId());
-        props.put(EXTENDER_BUNDLE_SYMBOLICNAME, extenderBundle.getSymbolicName());
-        props.put(EXTENDER_BUNDLE_VERSION, extenderBundle.getVersion());
-        return props;
+        final Event event = new Event(topic, props);
+        ((EventAdmin)eventAdmin).postEvent(event);
     }
 }