001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2006-2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.server.tasks; 018 019import static org.opends.server.config.ConfigConstants.ATTR_BACKEND_ID; 020 021import java.util.ArrayList; 022import java.util.HashMap; 023import java.util.List; 024import java.util.Map; 025 026import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1; 027import org.forgerock.i18n.slf4j.LocalizedLogger; 028import org.forgerock.opendj.adapter.server3x.Converters; 029import org.forgerock.opendj.config.server.ConfigException; 030import org.forgerock.opendj.ldap.ByteString; 031import org.forgerock.opendj.ldap.ResultCode; 032import org.forgerock.opendj.ldap.requests.ModifyRequest; 033import org.forgerock.opendj.server.config.server.BackendCfg; 034import org.forgerock.opendj.server.config.server.RootCfg; 035import org.opends.server.api.Backend; 036import org.opends.server.tools.BackendToolUtils; 037import org.opends.server.types.Entry; 038import org.opends.server.config.ConfigurationHandler; 039import org.opends.server.core.DirectoryServer; 040import org.opends.server.core.ModifyOperation; 041import org.opends.server.types.Attribute; 042import org.forgerock.opendj.ldap.DN; 043import org.opends.server.types.DirectoryException; 044 045import static org.forgerock.opendj.ldap.ModificationType.*; 046import static org.forgerock.opendj.ldap.requests.Requests.*; 047import static org.opends.messages.TaskMessages.*; 048import static org.opends.messages.ToolMessages.*; 049import static org.opends.server.config.ConfigConstants.*; 050import static org.opends.server.protocols.internal.InternalClientConnection.*; 051import static org.opends.server.util.ServerConstants.*; 052import static org.opends.server.util.StaticUtils.*; 053 054/** 055 * This class defines a number of static utility methods for server tasks. 056 */ 057public class TaskUtils 058{ 059 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 060 061 062 063 064 /** 065 * Get the backend ID of a backend configuration entry. 066 * 067 * @param configEntry A backend configuration entry. 068 * @return The backend ID. 069 */ 070 public static String getBackendID(Entry configEntry) 071 { 072 try 073 { 074 return BackendToolUtils.getStringSingleValuedAttribute(configEntry, ATTR_BACKEND_ID); 075 } 076 catch (Exception e) 077 { 078 logger.error(ERR_CANNOT_DETERMINE_BACKEND_ID, configEntry.getName(), getExceptionMessage(e)); 079 return null; 080 } 081 } 082 083 /** 084 * Get all the backend configuration entries defined in the server mapped 085 * by their backend ID. 086 * @return A map of backend IDs to their corresponding configuration entries. 087 */ 088 public static Map<String,Entry> getBackendConfigEntries() 089 { 090 Map<String,Entry> configEntries = new HashMap<>(); 091 092 // FIXME The error messages should not be the LDIF import messages 093 094 // Get the base entry for all backend configuration. 095 DN backendBaseDN; 096 try 097 { 098 backendBaseDN = DN.valueOf(DN_BACKEND_BASE); 099 } 100 catch (Exception e) 101 { 102 logger.error(ERR_CANNOT_DECODE_BACKEND_BASE_DN, DN_BACKEND_BASE, getExceptionMessage(e)); 103 return configEntries; 104 } 105 106 // Iterate through the immediate children, attempting to parse them as 107 // backends. 108 try 109 { 110 ConfigurationHandler configHandler = DirectoryServer.getConfigurationHandler(); 111 for (DN childrenDn : configHandler.getChildren(backendBaseDN)) 112 { 113 // Get the backend ID attribute from the entry. If there isn't one, then 114 // skip the entry. 115 Entry configEntry = null; 116 String backendID; 117 try 118 { 119 configEntry = Converters.to(configHandler.getEntry(childrenDn)); 120 backendID = BackendToolUtils.getStringSingleValuedAttribute(configEntry, ATTR_BACKEND_ID); 121 if (backendID == null) 122 { 123 continue; 124 } 125 } 126 catch (Exception e) 127 { 128 logger.error(ERR_CANNOT_DETERMINE_BACKEND_ID, childrenDn, getExceptionMessage(e)); 129 continue; 130 } 131 132 configEntries.put(backendID, configEntry); 133 } 134 } 135 catch (ConfigException e) 136 { 137 logger.error(ERR_CANNOT_RETRIEVE_BACKEND_BASE_ENTRY, DN_BACKEND_BASE, e.getMessage()); 138 } 139 140 return configEntries; 141 } 142 143 /** 144 * Get the configuration entry for a given backend. 145 * 146 * @param backend The backend whose configuration entry is wanted. 147 * @return The configuration entry of the backend, or null if it could not 148 * be found. 149 */ 150 public static BackendCfg getConfigEntry(Backend<?> backend) 151 { 152 try 153 { 154 return getRootConfig().getBackend(backend.getBackendID()); 155 } 156 catch (ConfigException e) 157 { 158 return null; 159 } 160 } 161 162 private static RootCfg getRootConfig() 163 { 164 return DirectoryServer.getInstance().getServerContext().getRootConfig(); 165 } 166 167 /** 168 * Enables a backend using an internal modify operation on the 169 * backend configuration entry. 170 * 171 * @param backendID Identifies the backend to be enabled. 172 * @throws DirectoryException If the internal modify operation failed. 173 */ 174 public static void enableBackend(String backendID) 175 throws DirectoryException 176 { 177 enableBackend(backendID, TRUE_VALUE, ERR_TASK_CANNOT_ENABLE_BACKEND); 178 } 179 180 181 182 /** 183 * Disables a backend using an internal modify operation on the 184 * backend configuration entry. 185 * 186 * @param backendID Identifies the backend to be disabled. 187 * @throws DirectoryException If the internal modify operation failed. 188 */ 189 public static void disableBackend(String backendID) throws DirectoryException 190 { 191 enableBackend(backendID, FALSE_VALUE, ERR_TASK_CANNOT_DISABLE_BACKEND); 192 } 193 194 private static void enableBackend(String backendID, ByteString enableValue, Arg1<Object> errorMsg) 195 throws DirectoryException { 196 DN configEntryDN; 197 try 198 { 199 configEntryDN = getRootConfig().getBackend(backendID).dn(); 200 } 201 catch (ConfigException e) 202 { 203 throw new DirectoryException(DirectoryServer.getServerErrorResultCode(), e.getMessageObject(), e); 204 } 205 206 ModifyRequest modifyRequest = newModifyRequest(configEntryDN) 207 .addModification(REPLACE, ATTR_BACKEND_ENABLED, enableValue); 208 ModifyOperation modifyOp = getRootConnection().processModify(modifyRequest); 209 210 ResultCode resultCode = modifyOp.getResultCode(); 211 if (resultCode != ResultCode.SUCCESS) 212 { 213 throw new DirectoryException(resultCode, errorMsg.get(configEntryDN)); 214 } 215 } 216 217 218 219 /** 220 * Get the single boolean value of an entry attribute that is defined in the 221 * schema as a single valued boolean attribute, and that is not expected to 222 * have attribute options. 223 * 224 * @param attrList The attribute value of the entry attribute. 225 * @param defaultValue The default value to be returned if there is no 226 * recognizable boolean attribute value. 227 * @return The boolean value of the attribute, or the provided default value 228 * if there is no value. 229 */ 230 public static boolean getBoolean(List<Attribute> attrList, 231 boolean defaultValue) 232 { 233 for (Attribute a : attrList) 234 { 235 for (ByteString v : a) 236 { 237 String valueString = toLowerCase(v.toString()); 238 if (valueString.equals("true") || valueString.equals("yes") || 239 valueString.equals("on") || valueString.equals("1")) 240 { 241 return true; 242 } 243 else if (valueString.equals("false") || valueString.equals("no") || 244 valueString.equals("off") || valueString.equals("0")) 245 { 246 return false; 247 } 248 } 249 } 250 251 return defaultValue; 252 } 253 254 255 256 /** 257 * Get the multiple string values of an entry attribute that is defined in the 258 * schema as a multi-valued string attribute, and that is not expected to 259 * have attribute options. 260 * 261 * @param attrList The attribute values of the entry attribute. 262 * @return The string values of the attribute, empty if there are none. 263 */ 264 public static ArrayList<String> getMultiValueString(List<Attribute> attrList) 265 { 266 ArrayList<String> valueStrings = new ArrayList<>(); 267 if (!attrList.isEmpty()) 268 { 269 Attribute attr = attrList.get(0); 270 if (!attr.isEmpty()) 271 { 272 for (ByteString value : attr) 273 { 274 valueStrings.add(value.toString()); 275 } 276 } 277 } 278 return valueStrings; 279 } 280 281 282 283 /** 284 * Get the single string value of an entry attribute that is defined in the 285 * schema as a single valued string attribute, and that is not expected to 286 * have attribute options. 287 * 288 * @param attrList The attribute value of the entry attribute. 289 * @return The string value of the attribute, or null if there is none. 290 */ 291 public static String getSingleValueString(List<Attribute> attrList) 292 { 293 if (!attrList.isEmpty()) 294 { 295 Attribute attr = attrList.get(0); 296 if (!attr.isEmpty()) 297 { 298 return attr.iterator().next().toString(); 299 } 300 } 301 return null; 302 } 303 304 305 /** 306 * Get the single integer value of an entry attribute that is defined in the 307 * schema as a single valued integer attribute, and that is not expected to 308 * have attribute options. 309 * 310 * @param attrList The attribute value of the entry attribute. 311 * @param defaultValue The default value to be returned if there is no 312 * recognizable integer attribute value. 313 * @return The integer value of the attribute, or the provided default value 314 * if there is no value. 315 */ 316 public static int getSingleValueInteger(List<Attribute> attrList, int defaultValue) 317 { 318 if (!attrList.isEmpty()) 319 { 320 Attribute attr = attrList.get(0); 321 if (!attr.isEmpty()) 322 { 323 try 324 { 325 return Integer.parseInt(attr.iterator().next().toString()); 326 } 327 catch (NumberFormatException e) 328 { 329 logger.traceException(e); 330 } 331 } 332 } 333 334 return defaultValue; 335 } 336}