001/**
002* Licensed to the Apache Software Foundation (ASF) under one
003* or more contributor license agreements.  See the NOTICE file
004* distributed with this work for additional information
005* regarding copyright ownership.  The ASF licenses this file
006* to you under the Apache License, Version 2.0 (the
007* "License"); you may not use this file except in compliance
008* with the License.  You may obtain a copy of the License at
009*
010*     http://www.apache.org/licenses/LICENSE-2.0
011*
012* Unless required by applicable law or agreed to in writing, software
013* distributed under the License is distributed on an "AS IS" BASIS,
014* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015* See the License for the specific language governing permissions and
016* limitations under the License.
017*/
018
019package org.apache.hadoop.service;
020
021import org.apache.hadoop.classification.InterfaceAudience.Public;
022import org.apache.hadoop.classification.InterfaceStability.Evolving;
023import org.apache.hadoop.conf.Configuration;
024
025import java.io.Closeable;
026import java.io.IOException;
027import java.util.List;
028import java.util.Map;
029
030/**
031 * Service LifeCycle.
032 */
033@Public
034@Evolving
035public interface Service extends Closeable {
036
037  /**
038   * Service states
039   */
040  public enum STATE {
041    /** Constructed but not initialized */
042    NOTINITED(0, "NOTINITED"),
043
044    /** Initialized but not started or stopped */
045    INITED(1, "INITED"),
046
047    /** started and not stopped */
048    STARTED(2, "STARTED"),
049
050    /** stopped. No further state transitions are permitted */
051    STOPPED(3, "STOPPED");
052
053    /**
054     * An integer value for use in array lookup and JMX interfaces.
055     * Although {@link Enum#ordinal()} could do this, explicitly
056     * identify the numbers gives more stability guarantees over time.
057     */
058    private final int value;
059
060    /**
061     * A name of the state that can be used in messages
062     */
063    private final String statename;
064
065    private STATE(int value, String name) {
066      this.value = value;
067      this.statename = name;
068    }
069
070    /**
071     * Get the integer value of a state
072     * @return the numeric value of the state
073     */
074    public int getValue() {
075      return value;
076    }
077
078    /**
079     * Get the name of a state
080     * @return the state's name
081     */
082    @Override
083    public String toString() {
084      return statename;
085    }
086  }
087
088  /**
089   * Initialize the service.
090   *
091   * The transition MUST be from {@link STATE#NOTINITED} to {@link STATE#INITED}
092   * unless the operation failed and an exception was raised, in which case
093   * {@link #stop()} MUST be invoked and the service enter the state
094   * {@link STATE#STOPPED}.
095   * @param config the configuration of the service
096   * @throws RuntimeException on any failure during the operation
097
098   */
099  void init(Configuration config);
100
101
102  /**
103   * Start the service.
104   *
105   * The transition MUST be from {@link STATE#INITED} to {@link STATE#STARTED}
106   * unless the operation failed and an exception was raised, in which case
107   * {@link #stop()} MUST be invoked and the service enter the state
108   * {@link STATE#STOPPED}.
109   * @throws RuntimeException on any failure during the operation
110   */
111
112  void start();
113
114  /**
115   * Stop the service. This MUST be a no-op if the service is already
116   * in the {@link STATE#STOPPED} state. It SHOULD be a best-effort attempt
117   * to stop all parts of the service.
118   *
119   * The implementation must be designed to complete regardless of the service
120   * state, including the initialized/uninitialized state of all its internal
121   * fields.
122   * @throws RuntimeException on any failure during the stop operation
123   */
124  void stop();
125
126  /**
127   * A version of stop() that is designed to be usable in Java7 closure
128   * clauses.
129   * Implementation classes MUST relay this directly to {@link #stop()}
130   * @throws IOException never
131   * @throws RuntimeException on any failure during the stop operation
132   */
133  void close() throws IOException;
134
135  /**
136   * Register a listener to the service state change events.
137   * If the supplied listener is already listening to this service,
138   * this method is a no-op.
139   * @param listener a new listener
140   */
141  void registerServiceListener(ServiceStateChangeListener listener);
142
143  /**
144   * Unregister a previously registered listener of the service state
145   * change events. No-op if the listener is already unregistered.
146   * @param listener the listener to unregister.
147   */
148  void unregisterServiceListener(ServiceStateChangeListener listener);
149
150  /**
151   * Get the name of this service.
152   * @return the service name
153   */
154  String getName();
155
156  /**
157   * Get the configuration of this service.
158   * This is normally not a clone and may be manipulated, though there are no
159   * guarantees as to what the consequences of such actions may be
160   * @return the current configuration, unless a specific implentation chooses
161   * otherwise.
162   */
163  Configuration getConfig();
164
165  /**
166   * Get the current service state
167   * @return the state of the service
168   */
169  STATE getServiceState();
170
171  /**
172   * Get the service start time
173   * @return the start time of the service. This will be zero if the service
174   * has not yet been started.
175   */
176  long getStartTime();
177
178  /**
179   * Query to see if the service is in a specific state.
180   * In a multi-threaded system, the state may not hold for very long.
181   * @param state the expected state
182   * @return true if, at the time of invocation, the service was in that state.
183   */
184  boolean isInState(STATE state);
185
186  /**
187   * Get the first exception raised during the service failure. If null,
188   * no exception was logged
189   * @return the failure logged during a transition to the stopped state
190   */
191  Throwable getFailureCause();
192
193  /**
194   * Get the state in which the failure in {@link #getFailureCause()} occurred.
195   * @return the state or null if there was no failure
196   */
197  STATE getFailureState();
198
199  /**
200   * Block waiting for the service to stop; uses the termination notification
201   * object to do so.
202   *
203   * This method will only return after all the service stop actions
204   * have been executed (to success or failure), or the timeout elapsed
205   * This method can be called before the service is inited or started; this is
206   * to eliminate any race condition with the service stopping before
207   * this event occurs.
208   * @param timeout timeout in milliseconds. A value of zero means "forever"
209   * @return true iff the service stopped in the time period
210   */
211  boolean waitForServiceToStop(long timeout);
212
213  /**
214   * Get a snapshot of the lifecycle history; it is a static list
215   * @return a possibly empty but never null list of lifecycle events.
216   */
217  public List<LifecycleEvent> getLifecycleHistory();
218
219  /**
220   * Get the blockers on a service -remote dependencies
221   * that are stopping the service from being <i>live</i>.
222   * @return a (snapshotted) map of blocker name-&gt;description values
223   */
224  public Map<String, String> getBlockers();
225}