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