001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.tools;
028    import org.opends.messages.Message;
029    
030    import org.opends.server.api.Backend;
031    import org.opends.server.config.ConfigEntry;
032    import org.opends.server.config.ConfigException;
033    import org.opends.server.config.StringConfigAttribute;
034    import org.opends.server.config.DNConfigAttribute;
035    import org.opends.server.types.DN;
036    import org.opends.server.types.DirectoryException;
037    import org.opends.server.core.DirectoryServer;
038    
039    import static org.opends.server.config.ConfigConstants.*;
040    import static org.opends.server.loggers.ErrorLogger.*;
041    import static org.opends.messages.ToolMessages.*;
042    import static org.opends.messages.ConfigMessages.*;
043    import static org.opends.server.util.StaticUtils.*;
044    import org.opends.server.admin.std.server.BackendCfg;
045    import org.opends.server.admin.std.server.RootCfg;
046    import org.opends.server.admin.server.ServerManagementContext;
047    
048    import java.util.ArrayList;
049    import java.util.List;
050    
051    /**
052     * This class provides utility functions for all JE related client tools.
053     */
054    public class BackendToolUtils
055    {
056      /**
057       * Retrieves information about the backends defined in the Directory Server
058       * configuration.
059       *
060       * @param  backendList  A list into which instantiated (but not initialized)
061       *                      backend instances will be placed.
062       * @param  entryList    A list into which the config entries associated with
063       *                      the backends will be placed.
064       * @param  dnList       A list into which the set of base DNs for each backend
065       *                      will be placed.
066       *
067       * @return 0 if everything went fine. 1 if an error occurred.
068       *
069       */
070      @SuppressWarnings("unchecked")
071      public static int getBackends(ArrayList<Backend> backendList,
072                                    ArrayList<BackendCfg> entryList,
073                                    ArrayList<List<DN>> dnList)
074      {
075        // Get the base entry for all backend configuration.
076        DN backendBaseDN;
077        try
078        {
079          backendBaseDN = DN.decode(DN_BACKEND_BASE);
080        }
081        catch (DirectoryException de)
082        {
083          Message message = ERR_CANNOT_DECODE_BACKEND_BASE_DN.get(
084              DN_BACKEND_BASE, de.getMessageObject());
085          logError(message);
086          return 1;
087        }
088        catch (Exception e)
089        {
090          Message message = ERR_CANNOT_DECODE_BACKEND_BASE_DN.get(
091              DN_BACKEND_BASE, getExceptionMessage(e));
092          logError(message);
093          return 1;
094        }
095    
096        ConfigEntry baseEntry;
097        try
098        {
099          baseEntry = DirectoryServer.getConfigEntry(backendBaseDN);
100        }
101        catch (ConfigException ce)
102        {
103          Message message = ERR_CANNOT_RETRIEVE_BACKEND_BASE_ENTRY.get(
104              DN_BACKEND_BASE, ce.getMessage());
105          logError(message);
106          return 1;
107        }
108        catch (Exception e)
109        {
110          Message message = ERR_CANNOT_RETRIEVE_BACKEND_BASE_ENTRY.get(
111              DN_BACKEND_BASE, getExceptionMessage(e));
112          logError(message);
113          return 1;
114        }
115    
116    
117        // Iterate through the immediate children, attempting to parse them as
118        // backends.
119        RootCfg root = ServerManagementContext.getInstance().getRootConfiguration();
120        for (ConfigEntry configEntry : baseEntry.getChildren().values())
121        {
122          // Get the backend ID attribute from the entry.  If there isn't one, then
123          // skip the entry.
124          String backendID;
125          try
126          {
127    
128            StringConfigAttribute idStub =
129                 new StringConfigAttribute(ATTR_BACKEND_ID,
130                         INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BACKEND_ID.get(),
131                                           true, false, true);
132            StringConfigAttribute idAttr =
133                 (StringConfigAttribute) configEntry.getConfigAttribute(idStub);
134            if (idAttr == null)
135            {
136              continue;
137            }
138            else
139            {
140              backendID = idAttr.activeValue();
141            }
142          }
143          catch (ConfigException ce)
144          {
145            Message message = ERR_CANNOT_DETERMINE_BACKEND_ID.get(
146                String.valueOf(configEntry.getDN()), ce.getMessage());
147            logError(message);
148            return 1;
149          }
150          catch (Exception e)
151          {
152            Message message = ERR_CANNOT_DETERMINE_BACKEND_ID.get(
153                String.valueOf(configEntry.getDN()), getExceptionMessage(e));
154            logError(message);
155            return 1;
156          }
157    
158    
159          // Get the backend class name attribute from the entry.  If there isn't
160          // one, then just skip the entry.
161          String backendClassName;
162          try
163          {
164    
165            StringConfigAttribute classStub =
166                 new StringConfigAttribute(
167                         ATTR_BACKEND_CLASS,
168                         INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_CLASS.get(),
169                         true, false, false);
170            StringConfigAttribute classAttr =
171                 (StringConfigAttribute) configEntry.getConfigAttribute(classStub);
172            if (classAttr == null)
173            {
174              continue;
175            }
176            else
177            {
178              backendClassName = classAttr.activeValue();
179            }
180          }
181          catch (ConfigException ce)
182          {
183            Message message = ERR_CANNOT_DETERMINE_BACKEND_CLASS.get(
184                String.valueOf(configEntry.getDN()), ce.getMessage());
185            logError(message);
186            return 1;
187          }
188          catch (Exception e)
189          {
190            Message message = ERR_CANNOT_DETERMINE_BACKEND_CLASS.get(
191                String.valueOf(configEntry.getDN()), getExceptionMessage(e));
192            logError(message);
193            return 1;
194          }
195    
196          Class backendClass;
197          try
198          {
199            backendClass = Class.forName(backendClassName);
200          }
201          catch (Exception e)
202          {
203            Message message = ERR_CANNOT_LOAD_BACKEND_CLASS.
204                get(backendClassName, String.valueOf(configEntry.getDN()),
205                    getExceptionMessage(e));
206            logError(message);
207            return 1;
208          }
209    
210          Backend backend;
211          BackendCfg cfg;
212          try
213          {
214            backend = (Backend) backendClass.newInstance();
215            backend.setBackendID(backendID);
216            cfg = root.getBackend(backendID);
217            backend.configureBackend(cfg);
218          }
219          catch (Exception e)
220          {
221            Message message = ERR_CANNOT_INSTANTIATE_BACKEND_CLASS.
222                get(backendClassName, String.valueOf(configEntry.getDN()),
223                    getExceptionMessage(e));
224            logError(message);
225            return 1;
226          }
227    
228    
229          // Get the base DN attribute from the entry.  If there isn't one, then
230          // just skip this entry.
231          List<DN> baseDNs = null;
232          try
233          {
234    
235            DNConfigAttribute baseDNStub =
236                 new DNConfigAttribute(
237                         ATTR_BACKEND_BASE_DN,
238                         INFO_CONFIG_BACKEND_ATTR_DESCRIPTION_BASE_DNS.get(),
239                         true, true, true);
240            DNConfigAttribute baseDNAttr =
241                 (DNConfigAttribute) configEntry.getConfigAttribute(baseDNStub);
242            if (baseDNAttr == null)
243            {
244              Message message =
245                  ERR_NO_BASES_FOR_BACKEND.get(String.valueOf(configEntry.getDN()));
246              logError(message);
247            }
248            else
249            {
250              baseDNs = baseDNAttr.activeValues();
251            }
252          }
253          catch (Exception e)
254          {
255            Message message = ERR_CANNOT_DETERMINE_BASES_FOR_BACKEND.get(
256                String.valueOf(configEntry.getDN()), getExceptionMessage(e));
257            logError(message);
258            return 1;
259          }
260    
261    
262          backendList.add(backend);
263          entryList.add(cfg);
264          dnList.add(baseDNs);
265        }
266        return 0;
267      }
268    }