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
019 package org.apache.hadoop.service;
020
021 import org.apache.hadoop.classification.InterfaceAudience.Public;
022 import org.apache.hadoop.classification.InterfaceStability.Evolving;
023 import org.apache.hadoop.conf.Configuration;
024
025 import java.io.Closeable;
026 import java.io.IOException;
027 import java.util.List;
028 import java.util.Map;
029
030 /**
031 * Service LifeCycle.
032 */
033 @Public
034 @Evolving
035 public 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->description values
223 */
224 public Map<String, String> getBlockers();
225 }