Bug 460639 - better failure handling
Signed-off-by: Raymond Auge <raymond.auge@liferay.com>
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
index 351cd3f..67774ad 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceRuntimeImpl.java
@@ -93,11 +93,15 @@
try {
if (contextName == null) {
- throw new IllegalContextNameException(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is null. Ignoring!"); //$NON-NLS-1$
+ throw new IllegalContextNameException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + " is null. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
if (contextPath == null) {
- throw new IllegalContextPathException(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is null. Ignoring!"); //$NON-NLS-1$
+ throw new IllegalContextPathException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + " is null. Ignoring!", //$NON-NLS-1$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
contextPath = adaptContextPath(contextPath, serviceReference);
@@ -110,6 +114,11 @@
result.set(contextController);
}
+ catch (HttpWhiteboardFailureException hwfe) {
+ parentServletContext.log(hwfe.getMessage(), hwfe);
+
+ recordFailedServletContextDTO(serviceReference, contextName, contextPath, hwfe.getFailureReason());
+ }
catch (Exception e) {
parentServletContext.log(e.getMessage(), e);
@@ -166,6 +175,7 @@
controllerMap.clear();
registeredObjects.clear();
+ failedListenerDTOs.clear();
failedServletContextDTOs.clear();
attributes = null;
@@ -206,7 +216,7 @@
runtimeDTO.failedErrorPageDTOs = null;
runtimeDTO.failedFilterDTOs = null;
- runtimeDTO.failedListenerDTOs = null;
+ runtimeDTO.failedListenerDTOs = getFailedListenerDTOs();
runtimeDTO.failedResourceDTOs = null;
runtimeDTO.failedServletContextDTOs = getFailedServletContextDTO();
runtimeDTO.failedServletDTOs = null;
@@ -451,6 +461,18 @@
return null;
}
+ private FailedListenerDTO[] getFailedListenerDTOs() {
+ Collection<FailedListenerDTO> flDTOs = failedListenerDTOs.values();
+
+ List<FailedListenerDTO> copies = new ArrayList<FailedListenerDTO>();
+
+ for (FailedListenerDTO failedListenerDTO : flDTOs) {
+ copies.add(DTOUtil.clone(failedListenerDTO));
+ }
+
+ return copies.toArray(new FailedListenerDTO[copies.size()]);
+ }
+
private FailedServletContextDTO[] getFailedServletContextDTO() {
Collection<FailedServletContextDTO> fscDTOs = failedServletContextDTOs.values();
@@ -933,6 +955,17 @@
return resourceServiceFilter;
}
+ public void recordFailedListenerDTO(
+ ServiceReference<EventListener> serviceReference,
+ FailedListenerDTO failedListenerDTO) {
+
+ if (failedListenerDTOs.containsKey(serviceReference)) {
+ return;
+ }
+
+ failedListenerDTOs.put(serviceReference, failedListenerDTO);
+ }
+
private void recordFailedServletContextDTO(
ServiceReference<ServletContextHelper> serviceReference, String contextName,
String contextPath, int failureReason) {
@@ -956,6 +989,12 @@
failedServletContextDTOs.put(serviceReference, failedServletContextDTO);
}
+ public void removeFailedListenerDTO(
+ ServiceReference<EventListener> serviceReference) {
+
+ failedListenerDTOs.remove(serviceReference);
+ }
+
private Map<String, Object> attributes;
private final String targetFilter;
private final ServiceRegistration<ServletContextHelper> defaultContextReg;
@@ -982,6 +1021,8 @@
private ConcurrentMap<ServiceReference<ServletContextHelper>, ContextController> controllerMap =
new ConcurrentHashMap<ServiceReference<ServletContextHelper>, ContextController>();
+ private final ConcurrentMap<ServiceReference<EventListener>, FailedListenerDTO> failedListenerDTOs =
+ new ConcurrentHashMap<ServiceReference<EventListener>, FailedListenerDTO>();
private final ConcurrentMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO> failedServletContextDTOs =
new ConcurrentHashMap<ServiceReference<ServletContextHelper>, FailedServletContextDTO>();
@@ -1199,4 +1240,5 @@
}
}
}
+
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
index 5b2b585..bb78547 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/context/ContextController.java
@@ -1078,7 +1078,9 @@
private void validate(String preValidationContextName, String preValidationContextPath) {
if (!contextNamePattern.matcher(preValidationContextName).matches()) {
- throw new IllegalContextNameException("The context name '" + preValidationContextName + "' does not follow Bundle-SymbolicName syntax."); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new IllegalContextNameException(
+ "The context name '" + preValidationContextName + "' does not follow Bundle-SymbolicName syntax.", //$NON-NLS-1$ //$NON-NLS-2$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
try {
@@ -1086,7 +1088,9 @@
URI uri = new URI(Const.HTTP, Const.LOCALHOST, preValidationContextPath, null);
}
catch (URISyntaxException use) {
- throw new IllegalContextPathException("The context path '" + preValidationContextPath + "' is not valid URI path syntax."); //$NON-NLS-1$ //$NON-NLS-2$
+ throw new IllegalContextPathException(
+ "The context path '" + preValidationContextPath + "' is not valid URI path syntax.", //$NON-NLS-1$ //$NON-NLS-2$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
}
}
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
index 6f1a254..5d179ae 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/customizer/ContextListenerTrackerCustomizer.java
@@ -13,12 +13,15 @@
import java.util.EventListener;
import java.util.concurrent.atomic.AtomicReference;
-import javax.servlet.ServletException;
import org.eclipse.equinox.http.servlet.internal.HttpServiceRuntimeImpl;
import org.eclipse.equinox.http.servlet.internal.context.ContextController;
+import org.eclipse.equinox.http.servlet.internal.error.HttpWhiteboardFailureException;
import org.eclipse.equinox.http.servlet.internal.registration.ListenerRegistration;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
+import org.eclipse.equinox.http.servlet.internal.util.Const;
+import org.osgi.framework.*;
+import org.osgi.service.http.runtime.dto.DTOConstants;
+import org.osgi.service.http.runtime.dto.FailedListenerDTO;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
/**
* @author Raymond Augé
@@ -49,12 +52,26 @@
return result;
}
+ String listener = (String)serviceReference.getProperty(HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER);
try {
+ if (!listener.equalsIgnoreCase(Const.TRUE)) {
+ throw new HttpWhiteboardFailureException(
+ HttpWhiteboardConstants.HTTP_WHITEBOARD_LISTENER + "=" + listener + " is not a valid option. Ignoring!", //$NON-NLS-1$ //$NON-NLS-2$
+ DTOConstants.FAILURE_REASON_VALIDATION_FAILED);
+ }
+
result.set(contextController.addListenerRegistration(serviceReference));
}
- catch (ServletException se) {
- httpServiceRuntime.log(se.getMessage(), se);
+ catch (HttpWhiteboardFailureException hwfe) {
+ httpServiceRuntime.log(hwfe.getMessage(), hwfe);
+
+ recordFailedListenerDTO(serviceReference, hwfe.getFailureReason());
+ }
+ catch (Exception e) {
+ httpServiceRuntime.log(e.getMessage(), e);
+
+ recordFailedListenerDTO(serviceReference, DTOConstants.FAILURE_REASON_EXCEPTION_ON_INIT);
}
return result;
@@ -80,6 +97,21 @@
// Destroy now ungets the object we are using
listenerRegistration.destroy();
}
+
+ contextController.getHttpServiceRuntime().removeFailedListenerDTO(serviceReference);
+ }
+
+ private void recordFailedListenerDTO(
+ ServiceReference<EventListener> serviceReference, int failureReason) {
+
+ FailedListenerDTO failedListenerDTO = new FailedListenerDTO();
+
+ failedListenerDTO.failureReason = failureReason;
+ failedListenerDTO.serviceId = (Long)serviceReference.getProperty(Constants.SERVICE_ID);
+ failedListenerDTO.servletContextId = contextController.getServiceId();
+ failedListenerDTO.types = new String[0];
+
+ contextController.getHttpServiceRuntime().recordFailedListenerDTO(serviceReference, failedListenerDTO);
}
private ContextController contextController;
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/HttpWhiteboardFailureException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/HttpWhiteboardFailureException.java
new file mode 100644
index 0000000..47ba32f
--- /dev/null
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/HttpWhiteboardFailureException.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) Feb 23, 2015 Raymond Augé and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Raymond Augé <raymond.auge@liferay.com> - Bug 460639
+ ******************************************************************************/
+
+package org.eclipse.equinox.http.servlet.internal.error;
+
+/**
+ * @author Raymond Augé
+ */
+public class HttpWhiteboardFailureException extends IllegalArgumentException {
+
+ private static final long serialVersionUID = 1944632136470074075L;
+
+ public HttpWhiteboardFailureException(String message, int failureReason) {
+ super(message);
+
+ this.failureReason = failureReason;
+ }
+
+ public int getFailureReason() {
+ return failureReason;
+ }
+
+ private final int failureReason;
+
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextNameException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextNameException.java
index 7e6f183..c0c4a1b 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextNameException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextNameException.java
@@ -14,12 +14,12 @@
/**
* @author Raymond Augé
*/
-public class IllegalContextNameException extends IllegalArgumentException {
+public class IllegalContextNameException extends HttpWhiteboardFailureException {
private static final long serialVersionUID = -8790109985246626513L;
- public IllegalContextNameException(String message) {
- super(message);
+ public IllegalContextNameException(String message, int failureReason) {
+ super(message, failureReason);
}
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextPathException.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextPathException.java
index 1f8244e..8b8410a 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextPathException.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/error/IllegalContextPathException.java
@@ -14,12 +14,12 @@
/**
* @author Raymond Augé
*/
-public class IllegalContextPathException extends IllegalArgumentException {
+public class IllegalContextPathException extends HttpWhiteboardFailureException {
private static final long serialVersionUID = 3286236189163243168L;
- public IllegalContextPathException(String message) {
- super(message);
+ public IllegalContextPathException(String message, int failureReason) {
+ super(message, failureReason);
}
}
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
index 8545e4a..63529b9 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/Const.java
@@ -28,6 +28,7 @@
public static final String SERVLET_NAME = "servlet-name"; //$NON-NLS-1$
public static final String SLASH = "/"; //$NON-NLS-1$
public static final String SLASH_STAR = "/*"; //$NON-NLS-1$
+ public static final String TRUE = "true"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_REGISTRATION_PROP = "equinox.legacy.registration"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_CONTEXT_SELECT = "equinox.context.select"; //$NON-NLS-1$
public static final String EQUINOX_LEGACY_CONTEXT_HELPER = "equinox.legacy.context.helper"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
index 68b7eb8..adea45e 100644
--- a/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
+++ b/bundles/org.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/util/DTOUtil.java
@@ -33,6 +33,17 @@
return clone;
}
+ public static FailedListenerDTO clone(FailedListenerDTO original) {
+ FailedListenerDTO clone = new FailedListenerDTO();
+
+ clone.failureReason = original.failureReason;
+ clone.serviceId = original.serviceId;
+ clone.servletContextId = original.servletContextId;
+ clone.types = original.types;
+
+ return clone;
+ }
+
public static FailedServletContextDTO clone(FailedServletContextDTO original) {
FailedServletContextDTO clone = new FailedServletContextDTO();