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.core; 018 019import java.util.List; 020 021import org.forgerock.opendj.server.config.server.LogRetentionPolicyCfg; 022import org.forgerock.opendj.server.config.server.RootCfg; 023import org.forgerock.opendj.server.config.meta.LogRetentionPolicyCfgDefn; 024import org.forgerock.i18n.LocalizableMessage; 025import org.forgerock.i18n.slf4j.LocalizedLogger; 026import org.forgerock.opendj.config.server.ConfigurationAddListener; 027import org.forgerock.opendj.config.server.ConfigurationChangeListener; 028import org.forgerock.opendj.config.server.ConfigurationDeleteListener; 029import org.forgerock.opendj.config.ClassPropertyDefinition; 030import org.opends.server.types.InitializationException; 031import org.forgerock.opendj.config.server.ConfigChangeResult; 032import org.opends.server.loggers.RetentionPolicy; 033import org.forgerock.opendj.config.server.ConfigException; 034 035import static org.opends.messages.ConfigMessages.*; 036import static org.opends.server.util.StaticUtils.*; 037 038/** 039 * This class defines a utility that will be used to manage the set of 040 * log retention policies used in the Directory Server. It will perform the 041 * initialization when the server is starting, and then will manage any 042 * additions, and removals of policies while the server is running. 043 */ 044public class LogRetentionPolicyConfigManager implements 045 ConfigurationAddListener<LogRetentionPolicyCfg>, 046 ConfigurationDeleteListener<LogRetentionPolicyCfg>, 047 ConfigurationChangeListener<LogRetentionPolicyCfg> 048{ 049 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 050 051 private final ServerContext serverContext; 052 053 /** 054 * Creates this log retention policy manager. 055 * 056 * @param serverContext 057 * The server context. 058 */ 059 public LogRetentionPolicyConfigManager(ServerContext serverContext) 060 { 061 this.serverContext = serverContext; 062 } 063 064 /** 065 * Initializes all the log retention policies. 066 * 067 * @throws ConfigException 068 * If an unrecoverable problem arises in the process of performing 069 * the initialization as a result of the server configuration. 070 * @throws InitializationException 071 * If a problem occurs during initialization that is not related to 072 * the server configuration. 073 */ 074 public void initializeLogRetentionPolicyConfig() throws ConfigException, InitializationException 075 { 076 RootCfg root = serverContext.getRootConfig(); 077 root.addLogRetentionPolicyAddListener(this); 078 root.addLogRetentionPolicyDeleteListener(this); 079 080 for(String name : root.listLogRetentionPolicies()) 081 { 082 LogRetentionPolicyCfg config = root.getLogRetentionPolicy(name); 083 084 RetentionPolicy<LogRetentionPolicyCfg> RetentionPolicy = getRetentionPolicy(config); 085 DirectoryServer.registerRetentionPolicy(config.dn(), RetentionPolicy); 086 } 087 } 088 089 @Override 090 public boolean isConfigurationAddAcceptable( 091 LogRetentionPolicyCfg configuration, 092 List<LocalizableMessage> unacceptableReasons) 093 { 094 return isJavaClassAcceptable(configuration, unacceptableReasons); 095 } 096 097 @Override 098 public boolean isConfigurationDeleteAcceptable( 099 LogRetentionPolicyCfg configuration, 100 List<LocalizableMessage> unacceptableReasons) 101 { 102 // TODO: Make sure nothing is using this policy before deleting it. 103 return true; 104 } 105 106 @Override 107 public ConfigChangeResult applyConfigurationAdd(LogRetentionPolicyCfg config) 108 { 109 final ConfigChangeResult ccr = new ConfigChangeResult(); 110 111 try 112 { 113 RetentionPolicy<LogRetentionPolicyCfg> retentionPolicy = getRetentionPolicy(config); 114 DirectoryServer.registerRetentionPolicy(config.dn(), retentionPolicy); 115 } 116 catch (ConfigException e) { 117 logger.traceException(e); 118 ccr.addMessage(e.getMessageObject()); 119 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 120 } catch (Exception e) { 121 logger.traceException(e); 122 123 ccr.addMessage(ERR_CONFIG_RETENTION_POLICY_CANNOT_CREATE_POLICY.get( 124 config.dn(),stackTraceToSingleLineString(e))); 125 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 126 } 127 128 return ccr; 129 } 130 131 @Override 132 public ConfigChangeResult applyConfigurationDelete( 133 LogRetentionPolicyCfg config) 134 { 135 final ConfigChangeResult ccr = new ConfigChangeResult(); 136 137 RetentionPolicy<?> policy = DirectoryServer.getRetentionPolicy(config.dn()); 138 if(policy != null) 139 { 140 DirectoryServer.deregisterRetentionPolicy(config.dn()); 141 } 142 else 143 { 144 // TODO: Add message and check for usage 145 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 146 } 147 148 return ccr; 149 } 150 151 @Override 152 public boolean isConfigurationChangeAcceptable( 153 LogRetentionPolicyCfg configuration, 154 List<LocalizableMessage> unacceptableReasons) 155 { 156 return isJavaClassAcceptable(configuration, unacceptableReasons); 157 } 158 159 @Override 160 public ConfigChangeResult applyConfigurationChange( 161 LogRetentionPolicyCfg configuration) 162 { 163 final ConfigChangeResult ccr = new ConfigChangeResult(); 164 165 RetentionPolicy policy = 166 DirectoryServer.getRetentionPolicy(configuration.dn()); 167 String className = configuration.getJavaClass(); 168 if(!className.equals(policy.getClass().getName())) 169 { 170 ccr.setAdminActionRequired(true); 171 } 172 173 return ccr; 174 } 175 176 private boolean isJavaClassAcceptable(LogRetentionPolicyCfg config, 177 List<LocalizableMessage> unacceptableReasons) 178 { 179 String className = config.getJavaClass(); 180 LogRetentionPolicyCfgDefn d = LogRetentionPolicyCfgDefn.getInstance(); 181 ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); 182 try { 183 Class<? extends RetentionPolicy> theClass = 184 pd.loadClass(className, RetentionPolicy.class); 185 // Explicitly cast to check that implementation implements the correct interface. 186 RetentionPolicy<?> retentionPolicy = theClass.newInstance(); 187 // next line is here to ensure that eclipse does not remove the cast in the line above 188 retentionPolicy.hashCode(); 189 return true; 190 } catch (Exception e) { 191 unacceptableReasons.add( 192 ERR_CONFIG_RETENTION_POLICY_INVALID_CLASS.get(className, config.dn(), e)); 193 return false; 194 } 195 } 196 197 private RetentionPolicy<LogRetentionPolicyCfg> getRetentionPolicy(LogRetentionPolicyCfg config) 198 throws ConfigException { 199 String className = config.getJavaClass(); 200 LogRetentionPolicyCfgDefn d = LogRetentionPolicyCfgDefn.getInstance(); 201 ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); 202 try { 203 Class<? extends RetentionPolicy> theClass = 204 pd.loadClass(className, RetentionPolicy.class); 205 RetentionPolicy<LogRetentionPolicyCfg> retentionPolicy = theClass.newInstance(); 206 retentionPolicy.initializeLogRetentionPolicy(config); 207 return retentionPolicy; 208 } catch (Exception e) { 209 LocalizableMessage message = ERR_CONFIG_RETENTION_POLICY_INVALID_CLASS.get( 210 className, config.dn(), e); 211 throw new ConfigException(message, e); 212 } 213 } 214}