Author: rmannibucau
Date: Tue Jul 11 12:56:54 2017
New Revision: 1801612
URL: http://svn.apache.org/viewvc?rev=1801612&view=rev
Log:
MEECROWAVE-53 StartListening/StopListening cdi events
Added:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/ListeningBase.java
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StartListening.java
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StopListening.java
openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/
openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/ListeningTest.java
Modified:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
Modified:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
URL:
http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java?rev=1801612&r1=1801611&r2=1801612&view=diff
==============================================================================
---
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
(original)
+++
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/Meecrowave.java
Tue Jul 11 12:56:54 2017
@@ -20,8 +20,10 @@ package org.apache.meecrowave;
import org.apache.catalina.Context;
import org.apache.catalina.Globals;
+import org.apache.catalina.Host;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
import org.apache.catalina.Manager;
import org.apache.catalina.Realm;
import org.apache.catalina.Server;
@@ -38,6 +40,8 @@ import org.apache.commons.lang3.text.Str
import org.apache.commons.lang3.text.StrSubstitutor;
import org.apache.coyote.http2.Http2Protocol;
import org.apache.johnzon.core.BufferStrategy;
+import org.apache.meecrowave.api.StartListening;
+import org.apache.meecrowave.api.StopListening;
import org.apache.meecrowave.cxf.CxfCdiAutoSetup;
import org.apache.meecrowave.io.IO;
import org.apache.meecrowave.logging.jul.Log4j2Logger;
@@ -59,6 +63,7 @@ import org.apache.tomcat.util.descriptor
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.apache.tomcat.util.modeler.Registry;
import org.apache.tomcat.util.net.SSLHostConfig;
+import org.apache.webbeans.config.WebBeansContext;
import org.apache.xbean.finder.ResourceFinder;
import org.apache.xbean.recipe.ObjectRecipe;
import org.xml.sax.Attributes;
@@ -147,6 +152,10 @@ public class Meecrowave implements AutoC
return tomcat;
}
+ public boolean isServing() {
+ return tomcat != null && tomcat.getHost().getState() ==
LifecycleState.STARTED;
+ }
+
public void undeploy(final String root) {
ofNullable(this.contexts.remove(root)).ifPresent(Runnable::run);
}
@@ -335,8 +344,17 @@ public class Meecrowave implements AutoC
ofNullable(meta.consumer).ifPresent(c -> c.accept(ctx));
- tomcat.getHost().addChild(ctx);
+ final Host host = tomcat.getHost();
+ host.addChild(ctx);
+
+ final ClassLoader classLoader = ctx.getLoader().getClassLoader();
+ if (host.getState().isAvailable()) {
+ fire(new StartListening(findFirstConnector(), host, ctx),
classLoader);
+ }
contexts.put(meta.context, () -> {
+ if (host.getState().isAvailable()) {
+ fire(new StopListening(findFirstConnector(), host, ctx),
classLoader);
+ }
ofNullable(releaseSCI.get()).ifPresent(Runnable::run);
tomcat.getHost().removeChild(ctx);
});
@@ -598,6 +616,14 @@ public class Meecrowave implements AutoC
if (!initialized) {
tomcat.init();
}
+
+ tomcat.getHost().addLifecycleListener(event -> {
+ if (!Host.class.isInstance(event.getSource())) {
+ return;
+ }
+ broadcastHostEvent(event.getType(),
Host.class.cast(event.getSource()));
+ });
+
tomcat.start();
} catch (final LifecycleException e) {
throw new IllegalStateException(e);
@@ -624,6 +650,51 @@ public class Meecrowave implements AutoC
return this;
}
+ private void broadcastHostEvent(final String event, final Host host) {
+ switch (event) {
+ case Lifecycle.AFTER_START_EVENT: {
+ final Connector connector = findFirstConnector();
+ findContexts(host).forEach(ctx -> fire(new
StartListening(connector, host, ctx), ctx.getLoader().getClassLoader()));
+ break;
+ }
+ case Lifecycle.BEFORE_STOP_EVENT: {
+ final Connector connector = findFirstConnector();
+ findContexts(host).forEach(ctx -> fire(new
StopListening(connector, host, ctx), ctx.getLoader().getClassLoader()));
+ break;
+ }
+ default:
+ }
+ }
+
+ private Connector findFirstConnector() {
+ return Stream.of(tomcat.getServer().findServices())
+ .flatMap(s -> Stream.of(s.findConnectors()))
+ .findFirst()
+ .orElse(null);
+ }
+
+ private Stream<Context> findContexts(final Host host) {
+ return Stream.of(host.findChildren())
+ .filter(Context.class::isInstance)
+ .map(Context.class::cast)
+ .filter(ctx -> ctx.getState().isAvailable());
+ }
+
+ private <T> void fire(final T event, final ClassLoader classLoader) {
+ final Thread thread = Thread.currentThread();
+ final ClassLoader loader = thread.getContextClassLoader();
+ thread.setContextClassLoader(classLoader);
+ try {
+ WebBeansContext.currentInstance()
+ .getBeanManagerImpl()
+ .getEvent()
+ .select(Class.class.cast(event.getClass()))
+ .fire(event);
+ } finally {
+ thread.setContextClassLoader(loader);
+ }
+ }
+
private void setupJmx(final boolean skip) {
try {
final Field registry = Registry.class.getDeclaredField("registry");
Added:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/ListeningBase.java
URL:
http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/ListeningBase.java?rev=1801612&view=auto
==============================================================================
---
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/ListeningBase.java
(added)
+++
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/ListeningBase.java
Tue Jul 11 12:56:54 2017
@@ -0,0 +1,53 @@
+/*
+ * 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.meecrowave.api;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Host;
+import org.apache.catalina.connector.Connector;
+
+public abstract class ListeningBase {
+ private final Connector connector;
+ private final Context context;
+ private final Host host;
+
+ ListeningBase(final Connector connector, final Host host, final Context
context) {
+ this.connector = connector;
+ this.host = host;
+ this.context = context;
+ }
+
+ public Context getContext() {
+ return context;
+ }
+
+ public Connector getConnector() {
+ return connector;
+ }
+
+ public Host getHost() {
+ return host;
+ }
+
+ public String getFirstBase() {
+ return (connector.getSecure() ? "https" : "http") + "://" +
+ host.getName() + (connector.getPort() > 0 ? ":" +
connector.getPort() : "") +
+ context.getPath();
+ }
+}
Added:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StartListening.java
URL:
http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StartListening.java?rev=1801612&view=auto
==============================================================================
---
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StartListening.java
(added)
+++
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StartListening.java
Tue Jul 11 12:56:54 2017
@@ -0,0 +1,29 @@
+/*
+ * 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.meecrowave.api;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Host;
+import org.apache.catalina.connector.Connector;
+
+public class StartListening extends ListeningBase {
+ public StartListening(final Connector connector, final Host host, final
Context context) {
+ super(connector, host, context);
+ }
+}
Added:
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StopListening.java
URL:
http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StopListening.java?rev=1801612&view=auto
==============================================================================
---
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StopListening.java
(added)
+++
openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/api/StopListening.java
Tue Jul 11 12:56:54 2017
@@ -0,0 +1,29 @@
+/*
+ * 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.meecrowave.api;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Host;
+import org.apache.catalina.connector.Connector;
+
+public class StopListening extends ListeningBase {
+ public StopListening(final Connector connector, final Host host, final
Context context) {
+ super(connector, host, context);
+ }
+}
Added:
openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/ListeningTest.java
URL:
http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/ListeningTest.java?rev=1801612&view=auto
==============================================================================
---
openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/ListeningTest.java
(added)
+++
openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/api/ListeningTest.java
Tue Jul 11 12:56:54 2017
@@ -0,0 +1,102 @@
+/*
+ * 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.meecrowave.api;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.meecrowave.Meecrowave;
+import org.junit.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.CDI;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.MediaType;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class ListeningTest {
+ @Test
+ public void events() throws LifecycleException {
+ final Listener listener;
+ final String base;
+ int count = 0;
+ try (final Meecrowave meecrowave = new Meecrowave(
+ new Meecrowave.Builder()
+ .randomHttpPort()
+
.includePackages(ListeningTest.class.getName())).bake()) {
+ count++;
+ listener = CDI.current().select(Listener.class).get();
+ assertEquals(count, listener.getEvents().size());
+
+ base = "http://localhost:" +
meecrowave.getConfiguration().getHttpPort();
+ assertEquals(base,
listener.getEvents().iterator().next().getFirstBase());
+ }
+
+ count++;
+ assertEquals(count, listener.getEvents().size());
+ assertEquals(base, listener.getEvents().get(count - 1).getFirstBase());
+ }
+
+ @Path("ping")
+ @ApplicationScoped
+ public static class Ping {
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String get() {
+ return "ping";
+ }
+ }
+
+ @ApplicationScoped
+ public static class Listener {
+ private final List<ListeningBase> events = new ArrayList<>();
+
+ public synchronized void onStart(@Observes final StartListening
listening) {
+ events.add(listening);
+ assertPing(listening);
+ }
+
+ public synchronized void onStop(@Observes final StopListening
listening) {
+ events.add(listening);
+ assertPing(listening);
+ }
+
+ private void assertPing(final ListeningBase listening) {
+ final Client actual = ClientBuilder.newClient();
+ try {
+ assertEquals("ping", actual.target(listening.getFirstBase())
+ .path("ping")
+ .request(MediaType.TEXT_PLAIN_TYPE)
+ .get(String.class).trim());
+ } finally {
+ actual.close();
+ }
+ }
+
+ List<ListeningBase> getEvents() {
+ return events;
+ }
+ }
+}