View Javadoc
1   /*
2    * JBoss, Home of Professional Open Source
3    * Copyright 2014, Red Hat, Inc. and/or its affiliates, and individual
4    * contributors by the @authors tag. See the copyright.txt in the
5    * distribution for a full listing of individual contributors.
6    *
7    * Licensed under the Apache License, Version 2.0 (the "License");
8    * you may not use this file except in compliance with the License.
9    * You may obtain a copy of the License at
10   * http://www.apache.org/licenses/LICENSE-2.0
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb;
18  
19  import java.util.Date;
20  import java.util.concurrent.atomic.AtomicBoolean;
21  
22  import javax.naming.InitialContext;
23  import javax.naming.NamingException;
24  
25  import org.jboss.logging.Logger;
26  import org.jboss.msc.service.Service;
27  import org.jboss.msc.service.ServiceName;
28  import org.jboss.msc.service.StartContext;
29  import org.jboss.msc.service.StartException;
30  import org.jboss.msc.service.StopContext;
31  
32  
33  /**
34   * <p>A service to start schedule-timer as HASingleton timer in a clustered environment.
35   * The {@link HATimerServiceActivator} will ensure that the timer is initialized only once in a cluster.</p>
36   * <p>
37   * The initialized timers must not persistent because it will be automatically restarted in case of a server restart
38   * and exists twice within the cluster.<br/>
39   * As this approach is no designed to interact with remote clients it is not possible to trigger reconfigurations.
40   * For this purpose it might be a solution to read the timer configuration from a datasource and create a scheduler
41   * which checks this configuration and trigger the reconfiguration.  
42   * </p>
43   *
44   * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a>
45   */
46  public class HATimerService implements Service<String> {
47      private static final Logger LOGGER = Logger.getLogger(HATimerService.class);
48      public static final ServiceName SINGLETON_SERVICE_NAME = ServiceName.JBOSS.append("quickstart", "ha", "singleton", "timer");
49  
50      /**
51       * A flag whether the service is started.
52       */
53      private final AtomicBoolean started = new AtomicBoolean(false);
54  
55      /**
56       * @return the name of the server node
57       */
58      public String getValue() throws IllegalStateException, IllegalArgumentException {
59          LOGGER.infof("%s is %s at %s", HATimerService.class.getSimpleName(), (started.get() ? "started" : "not started"), System.getProperty("jboss.node.name"));
60          return "";
61      }
62  
63      public void start(StartContext arg0) throws StartException {
64          if (!started.compareAndSet(false, true)) {
65              throw new StartException("The service is still started!");
66          }
67          LOGGER.info("Start HASingleton timer service '" + this.getClass().getName() + "'");
68  
69          final String node = System.getProperty("jboss.node.name");
70          try {
71              InitialContext ic = new InitialContext();
72              ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).initialize("HASingleton timer @" + node + " " + new Date());
73          } catch (NamingException e) {
74              throw new StartException("Could not initialize timer", e);
75          }
76      }
77  
78      public void stop(StopContext arg0) {
79          if (!started.compareAndSet(true, false)) {
80              LOGGER.warn("The service '" + this.getClass().getName() + "' is not active!");
81          } else {
82              LOGGER.info("Stop HASingleton timer service '" + this.getClass().getName() + "'");
83              try {
84                  InitialContext ic = new InitialContext();
85                  ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).stop();
86              } catch (NamingException e) {
87                  LOGGER.error("Could not stop timer", e);
88              }
89          }
90      }
91  }