From 68965c1d91aa5776f125b568b81d552ae7a962ab Mon Sep 17 00:00:00 2001 From: Paul Ferraro Date: Wed, 12 Dec 2012 09:19:30 -0500 Subject: [PATCH] Simplify HATimerService installation using a ServiceActivator. --- .../service/ejb/HATimerServiceActivator.java | 57 +++++++ .../cluster/hasingleton/service/ejb/Init.java | 141 ------------------ .../org.jboss.msc.service.ServiceActivator | 1 + 3 files changed, 58 insertions(+), 141 deletions(-) create mode 100644 cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/HATimerServiceActivator.java delete mode 100644 cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/Init.java create mode 100644 cluster-ha-singleton/service/src/main/resources/META-INF/services/org.jboss.msc.service.ServiceActivator diff --git a/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/HATimerServiceActivator.java b/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/HATimerServiceActivator.java new file mode 100644 index 0000000000..16a1115b95 --- /dev/null +++ b/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/HATimerServiceActivator.java @@ -0,0 +1,57 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2012, Red Hat, Inc. and/or its affiliates, and individual + * contributors by the @authors tag. See the copyright.txt in the + * distribution for a full listing of individual contributors. + * + * Licensed 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.jboss.as.quickstarts.cluster.hasingleton.service.ejb; + +import org.jboss.as.clustering.singleton.SingletonService; +import org.jboss.as.server.ServerEnvironment; +import org.jboss.as.server.ServerEnvironmentService; +import org.jboss.logging.Logger; +import org.jboss.msc.service.DelegatingServiceContainer; +import org.jboss.msc.service.ServiceActivator; +import org.jboss.msc.service.ServiceActivatorContext; +import org.jboss.msc.service.ServiceController; + +/** + * Service activator that installs the HATimerService as a clustered singleton service + * during deployment. + * @author Paul Ferraro + */ +public class HATimerServiceActivator implements ServiceActivator { + private final Logger log = Logger.getLogger(this.getClass()); + + @Override + public void activate(ServiceActivatorContext context) { + log.info("HATimerService will be installed!"); + + HATimerService service = new HATimerService(); + SingletonService singleton = new SingletonService(service, HATimerService.SINGLETON_SERVICE_NAME); + /* + * We can pass a chain of election policies to the singleton, for example to tell JGroups to prefer running the singleton on a node with a + * particular name + */ + // singleton.setElectionPolicy(new PreferredSingletonElectionPolicy(new SimpleSingletonElectionPolicy(), new NamePreference("node2/cluster"))); + + // Workaround for JBoss AS 7.1.2 + // In later releases, SingleService.build(...) accepts a service target + singleton.build(new DelegatingServiceContainer(context.getServiceTarget(), context.getServiceRegistry())) + // singleton.build(context.getServiceTarget()) + .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.env) + .setInitialMode(ServiceController.Mode.ACTIVE) + .install() + ; + } +} diff --git a/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/Init.java b/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/Init.java deleted file mode 100644 index ed3699d51d..0000000000 --- a/cluster-ha-singleton/service/src/main/java/org/jboss/as/quickstarts/cluster/hasingleton/service/ejb/Init.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * JBoss, Home of Professional Open Source - * Copyright 2012, Red Hat, Inc. and/or its affiliates, and individual - * contributors by the @authors tag. See the copyright.txt in the - * distribution for a full listing of individual contributors. - * - * Licensed 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.jboss.as.quickstarts.cluster.hasingleton.service.ejb; - -import java.util.Collection; -import java.util.EnumSet; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; -import javax.ejb.Singleton; -import javax.ejb.Startup; - -import org.jboss.as.clustering.singleton.SingletonService; -import org.jboss.as.server.CurrentServiceContainer; -import org.jboss.as.server.ServerEnvironment; -import org.jboss.as.server.ServerEnvironmentService; -import org.jboss.msc.service.AbstractServiceListener; -import org.jboss.msc.service.ServiceController; -import org.jboss.msc.service.ServiceController.Transition; -import org.jboss.msc.service.ServiceListener; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A Singleton EJB to create the SingletonService during startup. - * - * @author Wolf-Dieter Fink - */ -@Singleton -@Startup -public class Init { - private static final Logger LOGGER = LoggerFactory.getLogger(Init.class); - - /** - * Create the Service and wait until it is started.
- * Will log a message if the service will not start in 10sec. - */ - @PostConstruct - protected void startup() { - LOGGER.info("StartupSingleton will be initialized!"); - - HATimerService service = new HATimerService(); - SingletonService singleton = new SingletonService(service, HATimerService.SINGLETON_SERVICE_NAME); - /* - * We can pass a policy to the singleton, for example to tell JGroups to prefer running the singleton on a node with a - * particular name - */ - // singleton.setElectionPolicy(new PreferredSingletonElectionPolicy(new NamePreference("node2/cluster"), new SimpleSingletonElectionPolicy())); - ServiceController controller = singleton.build(CurrentServiceContainer.getServiceContainer()) - .addDependency(ServerEnvironmentService.SERVICE_NAME, ServerEnvironment.class, service.env).install(); - - controller.setMode(ServiceController.Mode.ACTIVE); - try { - wait(controller, EnumSet.of(ServiceController.State.DOWN, ServiceController.State.STARTING), - ServiceController.State.UP); - LOGGER.info("StartupSingleton has started the Service"); - } catch (IllegalStateException e) { - LOGGER.warn("Singleton Service {} not started, are you sure to start in a cluster (HA) environment?", - HATimerService.SINGLETON_SERVICE_NAME); - } - } - - /** - * Remove the service during undeploy or shutdown - */ - @PreDestroy - protected void destroy() { - LOGGER.info("StartupSingleton will be removed!"); - ServiceController controller = CurrentServiceContainer.getServiceContainer().getRequiredService( - HATimerService.SINGLETON_SERVICE_NAME); - controller.setMode(ServiceController.Mode.REMOVE); - try { - wait(controller, - EnumSet.of(ServiceController.State.UP, ServiceController.State.STOPPING, ServiceController.State.DOWN), - ServiceController.State.REMOVED); - } catch (IllegalStateException e) { - LOGGER.warn("Singleton Service {} has not be stopped correctly!", HATimerService.SINGLETON_SERVICE_NAME); - } - } - - /** - * It is not necessary to wait for the service controller. This is only done to be sure that the action is successful and - * give hints in this quickstart. - * - * @param controller the service controller to wait for - * @param expectedStates A list of expected final states of the service controller during transition - * @param targetState the expected final state after complete transition - */ - private static void wait(ServiceController controller, Collection expectedStates, - ServiceController.State targetState) { - if (controller.getState() != targetState) { - ServiceListener listener = new NotifyingServiceListener(); - controller.addListener(listener); - try { - synchronized (controller) { - int maxRetry = 2; - while (expectedStates.contains(controller.getState()) && maxRetry > 0) { - LOGGER.info("Service controller state is {}, waiting for transition to {}", - new Object[] { controller.getState(), targetState }); - controller.wait(5000); - maxRetry--; - } - } - } catch (InterruptedException e) { - LOGGER.warn("Wait on startup is interrupted!"); - Thread.currentThread().interrupt(); - } - controller.removeListener(listener); - ServiceController.State state = controller.getState(); - LOGGER.info("Service controller state is now {}", state); - if (state != targetState) { - throw new IllegalStateException(String.format( - "Failed to wait for state to transition to %s. Current state is %s", targetState, state), - controller.getStartException()); - } - } - } - - private static class NotifyingServiceListener extends AbstractServiceListener { - @Override - public void transition(ServiceController controller, Transition transition) { - synchronized (controller) { - controller.notify(); - } - } - } -} diff --git a/cluster-ha-singleton/service/src/main/resources/META-INF/services/org.jboss.msc.service.ServiceActivator b/cluster-ha-singleton/service/src/main/resources/META-INF/services/org.jboss.msc.service.ServiceActivator new file mode 100644 index 0000000000..759a574454 --- /dev/null +++ b/cluster-ha-singleton/service/src/main/resources/META-INF/services/org.jboss.msc.service.ServiceActivator @@ -0,0 +1 @@ +org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.HATimerServiceActivator