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.conf.Configuration;
022    import org.apache.hadoop.lib.util.ConfigurationUtils;
023    
024    import java.util.Map;
025    
026    /**
027     * Convenience class implementing the {@link Service} interface.
028     */
029    public 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    }