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 legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2015 ForgeRock AS 025 */ 026package org.opends.server.tools; 027 028import java.io.File; 029import java.util.ArrayList; 030import java.util.Collection; 031import java.util.LinkedList; 032import java.util.List; 033 034import org.forgerock.opendj.config.LDAPProfile; 035import org.forgerock.opendj.config.ManagedObjectDefinition; 036import org.forgerock.opendj.config.client.ManagementContext; 037import org.forgerock.opendj.config.client.ldap.LDAPManagementContext; 038import org.forgerock.opendj.ldap.DN; 039import org.forgerock.opendj.server.config.client.BackendCfgClient; 040import org.forgerock.opendj.server.config.client.BackendIndexCfgClient; 041import org.forgerock.opendj.server.config.client.LocalDBBackendCfgClient; 042import org.forgerock.opendj.server.config.client.LocalDBIndexCfgClient; 043import org.forgerock.opendj.server.config.client.PluggableBackendCfgClient; 044import org.forgerock.opendj.server.config.client.RootCfgClient; 045import org.forgerock.opendj.server.config.meta.BackendCfgDefn.WritabilityMode; 046import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn; 047import org.forgerock.opendj.server.config.meta.BackendIndexCfgDefn.IndexType; 048import org.forgerock.opendj.server.config.meta.LocalDBBackendCfgDefn; 049import org.forgerock.opendj.server.config.meta.LocalDBIndexCfgDefn; 050import org.forgerock.opendj.server.config.server.BackendCfg; 051import org.opends.guitools.controlpanel.util.Utilities; 052import org.opends.quicksetup.Installation; 053import org.opends.server.backends.jeb.RemoveOnceLocalDBBackendIsPluggable; 054 055/** 056 * Utility class which can be used by tools to create a new backend with default indexes. 057 */ 058public class BackendCreationHelper 059{ 060 /** Describes an attribute index which should be created during installation. */ 061 public static final class DefaultIndex 062 { 063 static DefaultIndex withEqualityAndSubstring(final String name) 064 { 065 return new DefaultIndex(name, true); 066 } 067 068 static DefaultIndex withEquality(final String name) 069 { 070 return new DefaultIndex(name, false); 071 } 072 073 private final String name; 074 private final boolean shouldCreateSubstringIndex; 075 076 private DefaultIndex(final String name, final boolean substringIndex) 077 { 078 this.name = name; 079 this.shouldCreateSubstringIndex = substringIndex; 080 } 081 082 /** 083 * Return the name of this default index. 084 * 085 * @return The name of this default index 086 */ 087 public String getName() 088 { 089 return name; 090 } 091 092 /** 093 * Return {@code true} if the substring index type should be enabled for 094 * this index. 095 * 096 * @return {@code true} if the substring index type should be enabled for 097 * this index. 098 */ 099 public boolean shouldCreateSubstringIndex() 100 { 101 return shouldCreateSubstringIndex; 102 } 103 } 104 105 /** Default indexes to add in a new backend. */ 106 public static final DefaultIndex[] DEFAULT_INDEXES = { 107 DefaultIndex.withEqualityAndSubstring("cn"), 108 DefaultIndex.withEqualityAndSubstring("givenName"), 109 DefaultIndex.withEqualityAndSubstring("mail"), 110 DefaultIndex.withEqualityAndSubstring("sn"), 111 DefaultIndex.withEqualityAndSubstring("telephoneNumber"), 112 DefaultIndex.withEquality("member"), 113 DefaultIndex.withEquality("uid"), 114 DefaultIndex.withEquality("uniqueMember") 115 }; 116 117 /** 118 * Add a new backend with the provided name in the config.ldif file. 119 * 120 * @param backendName 121 * The new backend name 122 * @param baseDNs 123 * The base dns to add in the new backend. 124 * @param backendType 125 * The backend type 126 * @throws Exception 127 * If any problems occurred 128 */ 129 public static void createBackendOffline(String backendName, Collection<DN> baseDNs, 130 ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType) throws Exception 131 { 132 Utilities.initializeConfigurationFramework(); 133 final File configFile = Installation.getLocal().getCurrentConfigurationFile(); 134 final LDAPProfile ldapProfile = LDAPProfile.getInstance(); 135 try (ManagementContext context = LDAPManagementContext.newLDIFManagementContext(configFile, ldapProfile)) 136 { 137 createBackend(context.getRootConfiguration(), backendName, baseDNs, backendType); 138 } 139 } 140 141 /** 142 * Create a backend with the provided name using the provided 143 * {@code RootCfgClient}. 144 * 145 * @param rootConfiguration 146 * The root configuration to use to create the new backend 147 * @param backendName 148 * The new backend name 149 * @param baseDNs 150 * The base dns to add in the new backend. 151 * @param backendType 152 * The backend type 153 * @throws Exception 154 * If any problems occurred 155 */ 156 public static void createBackend(RootCfgClient rootConfiguration, String backendName, Collection<DN> baseDNs, 157 ManagedObjectDefinition<? extends BackendCfgClient, ? extends BackendCfg> backendType) throws Exception 158 { 159 final BackendCfgClient backendCfgClient = rootConfiguration.createBackend(backendType, backendName, null); 160 backendCfgClient.setEnabled(true); 161 backendCfgClient.setBaseDN(baseDNs); 162 backendCfgClient.setWritabilityMode(WritabilityMode.ENABLED); 163 backendCfgClient.commit(); 164 165 if (backendType instanceof LocalDBBackendCfgDefn) 166 { 167 addJEDefaultIndexes((LocalDBBackendCfgClient) backendCfgClient); 168 } 169 else 170 { 171 addBackendDefaultIndexes((PluggableBackendCfgClient) backendCfgClient); 172 } 173 } 174 175 private static void addBackendDefaultIndexes(PluggableBackendCfgClient backendCfgClient) throws Exception 176 { 177 for (DefaultIndex defaultIndex : DEFAULT_INDEXES) 178 { 179 final BackendIndexCfgClient index = 180 backendCfgClient.createBackendIndex(BackendIndexCfgDefn.getInstance(), defaultIndex.name, null); 181 182 final List<IndexType> indexTypes = new LinkedList<>(); 183 indexTypes.add(IndexType.EQUALITY); 184 if (defaultIndex.shouldCreateSubstringIndex) 185 { 186 indexTypes.add(IndexType.SUBSTRING); 187 } 188 index.setIndexType(indexTypes); 189 190 index.commit(); 191 } 192 } 193 194 @RemoveOnceLocalDBBackendIsPluggable 195 private static void addJEDefaultIndexes(final LocalDBBackendCfgClient jeBackendCfgClient) throws Exception 196 { 197 for (DefaultIndex defaultIndex : DEFAULT_INDEXES) 198 { 199 final LocalDBIndexCfgClient jeIndex = 200 jeBackendCfgClient.createLocalDBIndex(LocalDBIndexCfgDefn.getInstance(), defaultIndex.name, null); 201 202 final List<LocalDBIndexCfgDefn.IndexType> indexTypes = new ArrayList<>(); 203 indexTypes.add(LocalDBIndexCfgDefn.IndexType.EQUALITY); 204 if (defaultIndex.shouldCreateSubstringIndex) 205 { 206 indexTypes.add(LocalDBIndexCfgDefn.IndexType.SUBSTRING); 207 } 208 jeIndex.setIndexType(indexTypes); 209 210 jeIndex.commit(); 211 } 212 } 213 214}