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