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; 018import java.util.List; 019 020import org.forgerock.i18n.LocalizableMessage; 021import org.forgerock.i18n.slf4j.LocalizedLogger; 022import org.opends.server.loggers.RotationPolicy; 023import org.opends.server.admin.server.ConfigurationAddListener; 024import org.opends.server.admin.server.ConfigurationDeleteListener; 025import org.opends.server.admin.server.ServerManagementContext; 026import org.opends.server.admin.server.ConfigurationChangeListener; 027import org.opends.server.admin.std.server.LogRotationPolicyCfg; 028import org.opends.server.admin.std.server.RootCfg; 029import org.opends.server.admin.std.meta.LogRotationPolicyCfgDefn; 030import org.opends.server.admin.ClassPropertyDefinition; 031import org.opends.server.types.InitializationException; 032import org.forgerock.opendj.config.server.ConfigChangeResult; 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 rotation 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 LogRotationPolicyConfigManager implements 045 ConfigurationAddListener<LogRotationPolicyCfg>, 046 ConfigurationDeleteListener<LogRotationPolicyCfg>, 047 ConfigurationChangeListener<LogRotationPolicyCfg> 048{ 049 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 050 051 private final ServerContext serverContext; 052 053 /** 054 * Creates this log rotation policy manager. 055 * 056 * @param serverContext 057 * The server context. 058 */ 059 public LogRotationPolicyConfigManager(ServerContext serverContext) 060 { 061 this.serverContext = serverContext; 062 } 063 064 /** 065 * Initializes all the log rotation 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 initializeLogRotationPolicyConfig() throws ConfigException, InitializationException 075 { 076 ServerManagementContext context = ServerManagementContext.getInstance(); 077 RootCfg root = context.getRootConfiguration(); 078 079 root.addLogRotationPolicyAddListener(this); 080 root.addLogRotationPolicyDeleteListener(this); 081 082 for(String name : root.listLogRotationPolicies()) 083 { 084 LogRotationPolicyCfg config = root.getLogRotationPolicy(name); 085 086 RotationPolicy rotationPolicy = getRotationPolicy(config); 087 088 DirectoryServer.registerRotationPolicy(config.dn(), rotationPolicy); 089 } 090 } 091 092 /** {@inheritDoc} */ 093 @Override 094 public boolean isConfigurationAddAcceptable( 095 LogRotationPolicyCfg configuration, 096 List<LocalizableMessage> unacceptableReasons) 097 { 098 return isJavaClassAcceptable(configuration, unacceptableReasons); 099 } 100 101 /** {@inheritDoc} */ 102 @Override 103 public boolean isConfigurationDeleteAcceptable( 104 LogRotationPolicyCfg configuration, 105 List<LocalizableMessage> unacceptableReasons) 106 { 107 // TODO: Make sure nothing is using this policy before deleting it. 108 return true; 109 } 110 111 /** {@inheritDoc} */ 112 @Override 113 public ConfigChangeResult applyConfigurationAdd(LogRotationPolicyCfg config) 114 { 115 final ConfigChangeResult ccr = new ConfigChangeResult(); 116 117 try 118 { 119 RotationPolicy rotationPolicy = getRotationPolicy(config); 120 121 DirectoryServer.registerRotationPolicy(config.dn(), rotationPolicy); 122 } 123 catch (ConfigException e) { 124 logger.traceException(e); 125 ccr.addMessage(e.getMessageObject()); 126 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 127 } catch (Exception e) { 128 logger.traceException(e); 129 130 ccr.addMessage(ERR_CONFIG_ROTATION_POLICY_CANNOT_CREATE_POLICY.get(config.dn(), 131 stackTraceToSingleLineString(e))); 132 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 133 } 134 135 return ccr; 136 } 137 138 /** {@inheritDoc} */ 139 @Override 140 public ConfigChangeResult applyConfigurationDelete( 141 LogRotationPolicyCfg config) 142 { 143 final ConfigChangeResult ccr = new ConfigChangeResult(); 144 145 RotationPolicy policy = DirectoryServer.getRotationPolicy(config.dn()); 146 if(policy != null) 147 { 148 DirectoryServer.deregisterRotationPolicy(config.dn()); 149 } 150 else 151 { 152 // TODO: Add message and check for usage 153 ccr.setResultCode(DirectoryServer.getServerErrorResultCode()); 154 } 155 156 return ccr; 157 } 158 159 /** {@inheritDoc} */ 160 @Override 161 public boolean isConfigurationChangeAcceptable( 162 LogRotationPolicyCfg configuration, 163 List<LocalizableMessage> unacceptableReasons) 164 { 165 return isJavaClassAcceptable(configuration, unacceptableReasons); 166 } 167 168 /** {@inheritDoc} */ 169 @Override 170 public ConfigChangeResult applyConfigurationChange( 171 LogRotationPolicyCfg configuration) 172 { 173 final ConfigChangeResult ccr = new ConfigChangeResult(); 174 175 RotationPolicy policy = 176 DirectoryServer.getRotationPolicy(configuration.dn()); 177 String className = configuration.getJavaClass(); 178 if(!className.equals(policy.getClass().getName())) 179 { 180 ccr.setAdminActionRequired(true); 181 } 182 183 return ccr; 184 } 185 186 private boolean isJavaClassAcceptable(LogRotationPolicyCfg config, 187 List<LocalizableMessage> unacceptableReasons) 188 { 189 String className = config.getJavaClass(); 190 LogRotationPolicyCfgDefn d = LogRotationPolicyCfgDefn.getInstance(); 191 ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); 192 try { 193 Class<? extends RotationPolicy> theClass = 194 pd.loadClass(className, RotationPolicy.class); 195 // Explicitly cast to check that implementation implements the correct interface. 196 RotationPolicy retentionPolicy = theClass.newInstance(); 197 // next line is here to ensure that eclipse does not remove the cast in the line above 198 retentionPolicy.hashCode(); 199 return true; 200 } catch (Exception e) { 201 unacceptableReasons.add( 202 ERR_CONFIG_ROTATION_POLICY_INVALID_CLASS.get(className, config.dn(), e)); 203 return false; 204 } 205 } 206 207 private RotationPolicy getRotationPolicy(LogRotationPolicyCfg config) 208 throws ConfigException { 209 String className = config.getJavaClass(); 210 LogRotationPolicyCfgDefn d = LogRotationPolicyCfgDefn.getInstance(); 211 ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); 212 try { 213 Class<? extends RotationPolicy> theClass = 214 pd.loadClass(className, RotationPolicy.class); 215 RotationPolicy rotationPolicy = theClass.newInstance(); 216 217 rotationPolicy.initializeLogRotationPolicy(config); 218 219 return rotationPolicy; 220 } catch (Exception e) { 221 LocalizableMessage message = ERR_CONFIG_ROTATION_POLICY_INVALID_CLASS.get( 222 className, config.dn(), e); 223 throw new ConfigException(message, e); 224 } 225 } 226}