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.lib.server;
020
021import org.apache.hadoop.conf.Configuration;
022import org.apache.hadoop.lib.util.ConfigurationUtils;
023
024import java.util.Map;
025
026/**
027 * Convenience class implementing the {@link Service} interface.
028 */
029public abstract class BaseService implements Service {
030  private String prefix;
031  private Server server;
032  private Configuration serviceConfig;
033
034  /**
035   * Service constructor.
036   *
037   * @param prefix service prefix.
038   */
039  public BaseService(String prefix) {
040    this.prefix = prefix;
041  }
042
043  /**
044   * Initializes the service.
045   * <p/>
046   * It collects all service properties (properties having the
047   * <code>#SERVER#.#SERVICE#.</code> prefix). The property names are then
048   * trimmed from the <code>#SERVER#.#SERVICE#.</code> prefix.
049   * <p/>
050   * After collecting  the service properties it delegates to the
051   * {@link #init()} method.
052   *
053   * @param server the server initializing the service, give access to the
054   * server context.
055   *
056   * @throws ServiceException thrown if the service could not be initialized.
057   */
058  @Override
059  public final void init(Server server) throws ServiceException {
060    this.server = server;
061    String servicePrefix = getPrefixedName("");
062    serviceConfig = new Configuration(false);
063    for (Map.Entry<String, String> entry : ConfigurationUtils.resolve(server.getConfig())) {
064      String key = entry.getKey();
065      if (key.startsWith(servicePrefix)) {
066        serviceConfig.set(key.substring(servicePrefix.length()), entry.getValue());
067      }
068    }
069    init();
070  }
071
072
073  /**
074   * Post initializes the service. This method is called by the
075   * {@link Server} after all services of the server have been initialized.
076   * <p/>
077   * This method does a NOP.
078   *
079   * @throws ServiceException thrown if the service could not be
080   * post-initialized.
081   */
082  @Override
083  public void postInit() throws ServiceException {
084  }
085
086  /**
087   * Destroy the services.  This method is called once, when the
088   * {@link Server} owning the service is being destroyed.
089   * <p/>
090   * This method does a NOP.
091   */
092  @Override
093  public void destroy() {
094  }
095
096  /**
097   * Returns the service dependencies of this service. The service will be
098   * instantiated only if all the service dependencies are already initialized.
099   * <p/>
100   * This method returns an empty array (size 0)
101   *
102   * @return an empty array (size 0).
103   */
104  @Override
105  public Class[] getServiceDependencies() {
106    return new Class[0];
107  }
108
109  /**
110   * Notification callback when the server changes its status.
111   * <p/>
112   * This method returns an empty array (size 0)
113   *
114   * @param oldStatus old server status.
115   * @param newStatus new server status.
116   *
117   * @throws ServiceException thrown if the service could not process the status change.
118   */
119  @Override
120  public void serverStatusChange(Server.Status oldStatus, Server.Status newStatus) throws ServiceException {
121  }
122
123  /**
124   * Returns the service prefix.
125   *
126   * @return the service prefix.
127   */
128  protected String getPrefix() {
129    return prefix;
130  }
131
132  /**
133   * Returns the server owning the service.
134   *
135   * @return the server owning the service.
136   */
137  protected Server getServer() {
138    return server;
139  }
140
141  /**
142   * Returns the full prefixed name of a service property.
143   *
144   * @param name of the property.
145   *
146   * @return prefixed name of the property.
147   */
148  protected String getPrefixedName(String name) {
149    return server.getPrefixedName(prefix + "." + name);
150  }
151
152  /**
153   * Returns the service configuration properties. Property
154   * names are trimmed off from its prefix.
155   * <p/>
156   * The sevice configuration properties are all properties
157   * with names starting with <code>#SERVER#.#SERVICE#.</code>
158   * in the server configuration.
159   *
160   * @return the service configuration properties with names
161   *         trimmed off from their <code>#SERVER#.#SERVICE#.</code>
162   *         prefix.
163   */
164  protected Configuration getServiceConfig() {
165    return serviceConfig;
166  }
167
168  /**
169   * Initializes the server.
170   * <p/>
171   * This method is called by {@link #init(Server)} after all service properties
172   * (properties prefixed with
173   *
174   * @throws ServiceException thrown if the service could not be initialized.
175   */
176  protected abstract void init() throws ServiceException;
177
178}