killbill-aplcache
Changes
osgi/pom.xml 4(+4 -0)
Details
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index 08813a4..71b62fa 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -130,5 +130,9 @@ public interface JaxrsResource {
public static final String EXPORT = "export";
public static final String EXPORT_PATH = PREFIX + "/" + EXPORT;
+ public static final String PLUGINS = "plugins";
+ // No PREFIX here!
+ public static final String PLUGINS_PATH = "/" + PLUGINS;
+
public static final String CBA_REBALANCING = "cbaRebalancing";
}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java
new file mode 100644
index 0000000..9fee49d
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/PluginResource.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.jaxrs.resources;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.HEAD;
+import javax.ws.rs.OPTIONS;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Response;
+
+import com.ning.billing.jaxrs.util.Context;
+import com.ning.billing.jaxrs.util.JaxrsUriBuilder;
+import com.ning.billing.util.api.AuditUserApi;
+import com.ning.billing.util.api.CustomFieldUserApi;
+import com.ning.billing.util.api.TagUserApi;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
+
+@Singleton
+@Path(JaxrsResource.PLUGINS_PATH)
+public class PluginResource extends JaxRsResourceBase {
+
+ private final HttpServlet osgiServlet;
+
+ @Inject
+ public PluginResource(@Named("osgi") final HttpServlet osgiServlet,
+ final JaxrsUriBuilder uriBuilder,
+ final TagUserApi tagUserApi,
+ final CustomFieldUserApi customFieldUserApi,
+ final AuditUserApi auditUserApi,
+ final Context context) {
+ super(uriBuilder, tagUserApi, customFieldUserApi, auditUserApi, context);
+ this.osgiServlet = osgiServlet;
+ }
+
+ @DELETE
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doDELETE(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(pluginName, request, response);
+ }
+
+ @GET
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doGET(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(pluginName, request, response);
+ }
+
+ @OPTIONS
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doOPTIONS(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(pluginName, request, response);
+ }
+
+ @POST
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doPOST(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(pluginName, request, response);
+ }
+
+ @PUT
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doPUT(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ return serviceViaOSGIPlugin(pluginName, request, response);
+ }
+
+ @HEAD
+ @Path("/{pluginName:" + STRING_PATTERN + "}/{rest:.+}")
+ public Response doHEAD(@PathParam("pluginName") final String pluginName,
+ @javax.ws.rs.core.Context final HttpServletRequest request,
+ @javax.ws.rs.core.Context final HttpServletResponse response) throws ServletException, IOException {
+ prepareOSGIRequest(pluginName, request);
+ osgiServlet.service(request, response);
+
+ // Make sure to return 204
+ return Response.noContent().build();
+ }
+
+ private Response serviceViaOSGIPlugin(final String pluginName, final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
+ prepareOSGIRequest(pluginName, request);
+ osgiServlet.service(request, response);
+
+ return Response.status(response.getStatus()).build();
+ }
+
+ private void prepareOSGIRequest(final String pluginName, final HttpServletRequest request) {
+ request.setAttribute("killbill.osgi.pluginName", pluginName);
+ }
+}
osgi/pom.xml 4(+4 -0)
diff --git a/osgi/pom.xml b/osgi/pom.xml
index b21699c..f3303b1 100644
--- a/osgi/pom.xml
+++ b/osgi/pom.xml
@@ -49,6 +49,10 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.skife.config</groupId>
<artifactId>config-magic</artifactId>
</dependency>
diff --git a/osgi/src/main/java/com/ning/billing/osgi/glue/DefaultOSGIModule.java b/osgi/src/main/java/com/ning/billing/osgi/glue/DefaultOSGIModule.java
index 0655cf9..b2c3408 100644
--- a/osgi/src/main/java/com/ning/billing/osgi/glue/DefaultOSGIModule.java
+++ b/osgi/src/main/java/com/ning/billing/osgi/glue/DefaultOSGIModule.java
@@ -16,12 +16,14 @@
package com.ning.billing.osgi.glue;
+import javax.servlet.http.HttpServlet;
import javax.sql.DataSource;
import org.skife.config.ConfigurationObjectFactory;
import com.ning.billing.osgi.DefaultOSGIKillbill;
import com.ning.billing.osgi.KillbillActivator;
+import com.ning.billing.osgi.OSGIServlet;
import com.ning.billing.osgi.api.OSGIKillbill;
import com.ning.billing.osgi.api.config.PluginConfigServiceApi;
import com.ning.billing.osgi.pluginconf.DefaultPluginConfigServiceApi;
@@ -43,9 +45,15 @@ public class DefaultOSGIModule extends AbstractModule {
bind(OSGIDataSourceConfig.class).toInstance(osgiDataSourceConfig);
}
+ protected void installOSGIServlet() {
+ bind(HttpServlet.class).annotatedWith(Names.named(OSGI_NAMED)).to(OSGIServlet.class).asEagerSingleton();
+ }
+
@Override
protected void configure() {
installConfig();
+ installOSGIServlet();
+
bind(KillbillActivator.class).asEagerSingleton();
bind(PluginFinder.class).asEagerSingleton();
bind(PluginConfigServiceApi.class).to(DefaultPluginConfigServiceApi.class).asEagerSingleton();
diff --git a/osgi/src/main/java/com/ning/billing/osgi/OSGIServlet.java b/osgi/src/main/java/com/ning/billing/osgi/OSGIServlet.java
new file mode 100644
index 0000000..d8420a9
--- /dev/null
+++ b/osgi/src/main/java/com/ning/billing/osgi/OSGIServlet.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.osgi;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class OSGIServlet extends HttpServlet {
+
+ private final Map<String, HttpServlet> pluginServlets = new HashMap<String, HttpServlet>();
+
+ public void registerResource(final String pluginName, final HttpServlet httpServlet) {
+ pluginServlets.put(pluginName, httpServlet);
+ }
+
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ @Override
+ protected void doHead(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ @Override
+ protected void doPut(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ @Override
+ protected void doDelete(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ @Override
+ protected void doOptions(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ serviceViaPlugin(req, resp);
+ }
+
+ private void serviceViaPlugin(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ final HttpServlet pluginServlet = getPluginServlet(req);
+ if (pluginServlet != null) {
+ pluginServlet.service(req, resp);
+ } else {
+ resp.sendError(404);
+ }
+ }
+
+ private HttpServlet getPluginServlet(final HttpServletRequest req) {
+ final String pluginName = (String) req.getAttribute("killbill.osgi.pluginName");
+ if (pluginName != null) {
+ return pluginServlets.get(pluginName);
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
index f8c1567..aaf22b7 100644
--- a/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
+++ b/server/src/main/java/com/ning/billing/server/listeners/KillbillGuiceListener.java
@@ -37,6 +37,7 @@ import com.ning.billing.util.svcsapi.bus.InternalBus;
import com.ning.jetty.base.modules.ServerModuleBuilder;
import com.ning.jetty.core.listeners.SetupServer;
+import com.google.common.annotations.VisibleForTesting;
import com.google.inject.Injector;
import com.google.inject.Module;
import net.sf.ehcache.CacheManager;
@@ -47,6 +48,7 @@ public class KillbillGuiceListener extends SetupServer {
public static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
public static final String KILLBILL_MULTITENANT_PROPERTY = "killbill.server.multitenant";
+ private Injector injector;
private DefaultLifecycle killbillLifecycle;
private BusService killbillBusService;
private KillbillEventHandler killbilleventHandler;
@@ -86,12 +88,15 @@ public class KillbillGuiceListener extends SetupServer {
super.contextInitialized(event);
logger.info("KillbillLifecycleListener : contextInitialized");
- final Injector theInjector = injector(event);
- killbillLifecycle = theInjector.getInstance(DefaultLifecycle.class);
- killbillBusService = theInjector.getInstance(BusService.class);
- killbilleventHandler = theInjector.getInstance(KillbillEventHandler.class);
- registerMBeansForCache(theInjector.getInstance(CacheManager.class));
+ injector = injector(event);
+ event.getServletContext().setAttribute(Injector.class.getName(), injector);
+
+ killbillLifecycle = injector.getInstance(DefaultLifecycle.class);
+ killbillBusService = injector.getInstance(BusService.class);
+ killbilleventHandler = injector.getInstance(KillbillEventHandler.class);
+
+ registerMBeansForCache(injector.getInstance(CacheManager.class));
/*
ObjectMapper mapper = theInjector.getInstance(ObjectMapper.class);
@@ -137,4 +142,9 @@ public class KillbillGuiceListener extends SetupServer {
// Complete shutdown sequence
killbillLifecycle.fireShutdownSequencePostEventUnRegistration();
}
+
+ @VisibleForTesting
+ public Injector getInstantiatedInjector() {
+ return injector;
+ }
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
index e4ee470..94cb566 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
@@ -812,6 +812,58 @@ public abstract class KillbillClient extends ServerTestSuiteWithEmbeddedDB {
}
//
+ // PLUGINS
+ //
+
+ protected Response pluginGET(final String uri) throws Exception {
+ return pluginGET(uri, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginGET(final String uri, final Map<String, String> queryParams) throws Exception {
+ return doGet(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ protected Response pluginHEAD(final String uri) throws Exception {
+ return pluginHEAD(uri, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginHEAD(final String uri, final Map<String, String> queryParams) throws Exception {
+ return doHead(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ protected Response pluginPOST(final String uri, @Nullable final String body) throws Exception {
+ return pluginPOST(uri, body, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginPOST(final String uri, @Nullable final String body, final Map<String, String> queryParams) throws Exception {
+ return doPost(JaxrsResource.PLUGINS_PATH + "/" + uri, body, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ protected Response pluginPUT(final String uri, @Nullable final String body) throws Exception {
+ return pluginPUT(uri, body, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginPUT(final String uri, @Nullable final String body, final Map<String, String> queryParams) throws Exception {
+ return doPut(JaxrsResource.PLUGINS_PATH + "/" + uri, body, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ protected Response pluginDELETE(final String uri) throws Exception {
+ return pluginDELETE(uri, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginDELETE(final String uri, final Map<String, String> queryParams) throws Exception {
+ return doDelete(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ protected Response pluginOPTIONS(final String uri) throws Exception {
+ return pluginOPTIONS(uri, DEFAULT_EMPTY_QUERY);
+ }
+
+ protected Response pluginOPTIONS(final String uri, final Map<String, String> queryParams) throws Exception {
+ return doOptions(JaxrsResource.PLUGINS_PATH + "/" + uri, queryParams, DEFAULT_HTTP_TIMEOUT_SEC);
+ }
+
+ //
// HTTP CLIENT HELPERS
//
protected Response doPost(final String uri, @Nullable final String body, final Map<String, String> queryParams, final int timeoutSec) {
@@ -846,11 +898,31 @@ public abstract class KillbillClient extends ServerTestSuiteWithEmbeddedDB {
return doGetWithUrl(url, queryParams, timeoutSec);
}
+ protected Response doHead(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
+ final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+ return doHeadWithUrl(url, queryParams, timeoutSec);
+ }
+
+ protected Response doOptions(final String uri, final Map<String, String> queryParams, final int timeoutSec) {
+ final String url = String.format("http://%s:%d%s", config.getServerHost(), config.getServerPort(), uri);
+ return doOptionsWithUrl(url, queryParams, timeoutSec);
+ }
+
protected Response doGetWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("GET", url, queryParams);
return executeAndWait(builder, timeoutSec, false);
}
+ protected Response doHeadWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
+ final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("HEAD", url, queryParams);
+ return executeAndWait(builder, timeoutSec, false);
+ }
+
+ protected Response doOptionsWithUrl(final String url, final Map<String, String> queryParams, final int timeoutSec) {
+ final BoundRequestBuilder builder = getBuilderWithHeaderAndQuery("OPTIONS", url, queryParams);
+ return executeAndWait(builder, timeoutSec, false);
+ }
+
private Response executeAndWait(final BoundRequestBuilder builder, final int timeoutSec, final boolean addContextHeader) {
if (addContextHeader) {
@@ -890,6 +962,10 @@ public abstract class KillbillClient extends ServerTestSuiteWithEmbeddedDB {
builder = httpClient.preparePut(url);
} else if (verb.equals("DELETE")) {
builder = httpClient.prepareDelete(url);
+ } else if (verb.equals("HEAD")) {
+ builder = httpClient.prepareHead(url);
+ } else if (verb.equals("OPTIONS")) {
+ builder = httpClient.prepareOptions(url);
} else {
Assert.fail("Unknown verb " + verb);
}
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
index 25e1f10..15df041 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestJaxrsBase.java
@@ -23,6 +23,10 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.servlet.http.HttpServlet;
+
import org.eclipse.jetty.servlet.FilterHolder;
import org.joda.time.LocalDate;
import org.skife.config.ConfigurationObjectFactory;
@@ -47,12 +51,14 @@ import com.ning.billing.invoice.api.InvoiceNotifier;
import com.ning.billing.invoice.glue.DefaultInvoiceModule;
import com.ning.billing.invoice.notification.NullInvoiceNotifier;
import com.ning.billing.junction.glue.DefaultJunctionModule;
+import com.ning.billing.osgi.glue.DefaultOSGIModule;
import com.ning.billing.overdue.glue.DefaultOverdueModule;
import com.ning.billing.payment.glue.PaymentModule;
import com.ning.billing.payment.provider.MockPaymentProviderPluginModule;
import com.ning.billing.server.listeners.KillbillGuiceListener;
import com.ning.billing.server.modules.KillbillServerModule;
import com.ning.billing.tenant.glue.TenantModule;
+import com.ning.billing.usage.glue.UsageModule;
import com.ning.billing.util.clock.Clock;
import com.ning.billing.util.clock.ClockMock;
import com.ning.billing.util.config.PaymentConfig;
@@ -87,6 +93,10 @@ public class TestJaxrsBase extends KillbillClient {
protected static final int DEFAULT_HTTP_TIMEOUT_SEC = 6000; // 5;
+ @Inject
+ @Named("osgi")
+ protected HttpServlet osgiServlet;
+
protected static TestKillbillGuiceListener listener;
private final DBTestingHelper helper = KillbillTestSuiteWithEmbeddedDB.getDBTestingHelper();
@@ -188,6 +198,8 @@ public class TestJaxrsBase extends KillbillClient {
install(new DefaultOverdueModule());
install(new TenantModule());
install(new ExportModule());
+ install(new DefaultOSGIModule());
+ install(new UsageModule());
installClock();
}
@@ -248,6 +260,8 @@ public class TestJaxrsBase extends KillbillClient {
server.configure(config, getListeners(), getFilters());
server.start();
+
+ listener.getInstantiatedInjector().injectMembers(this);
}
protected Iterable<EventListener> getListeners() {
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java b/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java
new file mode 100644
index 0000000..f8da0a7
--- /dev/null
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestPlugin.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.jaxrs;
+
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.annotation.Nullable;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.ning.billing.jaxrs.resources.JaxrsResource;
+import com.ning.billing.osgi.OSGIServlet;
+import com.ning.http.client.Response;
+
+public class TestPlugin extends TestJaxrsBase {
+
+ private static final String TEST_PLUGIN_NAME = "test-osgi";
+
+ private static final byte[] TEST_PLUGIN_RESPONSE_BYTES = new byte[]{0xC, 0x0, 0xF, 0xF, 0xE, 0xE};
+
+ private static final String TEST_PLUGIN_VALID_GET_PATH = "setGETMarkerToTrue";
+ private static final String TEST_PLUGIN_VALID_HEAD_PATH = "setHEADMarkerToTrue";
+ private static final String TEST_PLUGIN_VALID_POST_PATH = "setPOSTMarkerToTrue";
+ private static final String TEST_PLUGIN_VALID_PUT_PATH = "setPUTMarkerToTrue";
+ private static final String TEST_PLUGIN_VALID_DELETE_PATH = "setDELETEMarkerToTrue";
+ private static final String TEST_PLUGIN_VALID_OPTIONS_PATH = "setOPTIONSMarkerToTrue";
+
+ private final AtomicBoolean requestGETMarker = new AtomicBoolean(false);
+ private final AtomicBoolean requestHEADMarker = new AtomicBoolean(false);
+ private final AtomicBoolean requestPOSTMarker = new AtomicBoolean(false);
+ private final AtomicBoolean requestPUTMarker = new AtomicBoolean(false);
+ private final AtomicBoolean requestDELETEMarker = new AtomicBoolean(false);
+ private final AtomicBoolean requestOPTIONSMarker = new AtomicBoolean(false);
+
+ @BeforeMethod(groups = "slow")
+ public void setUp() throws Exception {
+ setupOSGIPlugin();
+ resetAllMarkers();
+ }
+
+ @Test(groups = "slow")
+ public void testPassRequestsToUnknownPlugin() throws Exception {
+ final String uri = "pluginDoesNotExist/something";
+ Response response;
+
+ // We don't test the output here as it is some Jetty specific HTML blurb
+
+ response = pluginGET(uri);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+
+ response = pluginHEAD(uri);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+
+ response = pluginPOST(uri, null);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+
+ response = pluginPUT(uri, null);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+
+ response = pluginDELETE(uri);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+
+ response = pluginOPTIONS(uri);
+ testAndResetAllMarkers(response, 404, null, false, false, false, false, false, false);
+ }
+
+ @Test(groups = "slow")
+ public void testPassRequestsToKnownPluginButWrongPath() throws Exception {
+ final String uri = TEST_PLUGIN_NAME + "/somethingSomething";
+ Response response;
+
+ response = pluginGET(uri);
+ testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
+
+ response = pluginHEAD(uri);
+ testAndResetAllMarkers(response, 204, new byte[]{}, false, false, false, false, false, false);
+
+ response = pluginPOST(uri, null);
+ testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
+
+ response = pluginPUT(uri, null);
+ testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
+
+ response = pluginDELETE(uri);
+ testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
+
+ response = pluginOPTIONS(uri);
+ testAndResetAllMarkers(response, 200, new byte[]{}, false, false, false, false, false, false);
+ }
+
+ @Test(groups = "slow")
+ public void testPassRequestsToKnownPluginAndKnownPath() throws Exception {
+ Response response;
+
+ response = pluginGET(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_GET_PATH);
+ testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, true, false, false, false, false, false);
+
+ response = pluginHEAD(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_HEAD_PATH);
+ testAndResetAllMarkers(response, 204, new byte[]{}, false, true, false, false, false, false);
+
+ response = pluginPOST(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_POST_PATH, null);
+ testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, true, false, false, false);
+
+ response = pluginPUT(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_PUT_PATH, null);
+ testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, true, false, false);
+
+ response = pluginDELETE(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_DELETE_PATH);
+ testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, false, true, false);
+
+ response = pluginOPTIONS(TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_OPTIONS_PATH);
+ testAndResetAllMarkers(response, 230, TEST_PLUGIN_RESPONSE_BYTES, false, false, false, false, false, true);
+ }
+
+ private void testAndResetAllMarkers(final Response response, final int responseCode, @Nullable final byte[] responseBytes, final boolean get, final boolean head,
+ final boolean post, final boolean put, final boolean delete, final boolean options) throws IOException {
+ Assert.assertEquals(response.getStatusCode(), responseCode);
+ if (responseBytes != null) {
+ Assert.assertEquals(response.getResponseBodyAsBytes(), responseBytes);
+ }
+
+ Assert.assertEquals(requestGETMarker.get(), get);
+ Assert.assertEquals(requestHEADMarker.get(), head);
+ Assert.assertEquals(requestPOSTMarker.get(), post);
+ Assert.assertEquals(requestPUTMarker.get(), put);
+ Assert.assertEquals(requestDELETEMarker.get(), delete);
+ Assert.assertEquals(requestOPTIONSMarker.get(), options);
+
+ resetAllMarkers();
+ }
+
+ private void resetAllMarkers() {
+ requestGETMarker.set(false);
+ requestHEADMarker.set(false);
+ requestPOSTMarker.set(false);
+ requestPUTMarker.set(false);
+ requestDELETEMarker.set(false);
+ requestOPTIONSMarker.set(false);
+ }
+
+ private void setupOSGIPlugin() {
+ ((OSGIServlet) osgiServlet).registerResource(TEST_PLUGIN_NAME, new HttpServlet() {
+ @Override
+ protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_GET_PATH).equals(req.getPathInfo())) {
+ requestGETMarker.set(true);
+ resp.getOutputStream().write(TEST_PLUGIN_RESPONSE_BYTES);
+ resp.setStatus(230);
+ }
+ }
+
+ @Override
+ protected void doHead(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_HEAD_PATH).equals(req.getPathInfo())) {
+ requestHEADMarker.set(true);
+ }
+ }
+
+ @Override
+ protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_POST_PATH).equals(req.getPathInfo())) {
+ requestPOSTMarker.set(true);
+ resp.getOutputStream().write(TEST_PLUGIN_RESPONSE_BYTES);
+ resp.setStatus(230);
+ }
+ }
+
+ @Override
+ protected void doPut(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_PUT_PATH).equals(req.getPathInfo())) {
+ requestPUTMarker.set(true);
+ resp.getOutputStream().write(TEST_PLUGIN_RESPONSE_BYTES);
+ resp.setStatus(230);
+ }
+ }
+
+ @Override
+ protected void doDelete(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_DELETE_PATH).equals(req.getPathInfo())) {
+ requestDELETEMarker.set(true);
+ resp.getOutputStream().write(TEST_PLUGIN_RESPONSE_BYTES);
+ resp.setStatus(230);
+ }
+ }
+
+ @Override
+ protected void doOptions(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
+ if ((JaxrsResource.PLUGINS_PATH + "/" + TEST_PLUGIN_NAME + "/" + TEST_PLUGIN_VALID_OPTIONS_PATH).equals(req.getPathInfo())) {
+ requestOPTIONSMarker.set(true);
+ resp.getOutputStream().write(TEST_PLUGIN_RESPONSE_BYTES);
+ resp.setStatus(230);
+ }
+ }
+ });
+ }
+}