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