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 }