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