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.loggers;
018import java.util.Arrays;
019import java.util.Calendar;
020import java.util.List;
021
022import org.forgerock.i18n.LocalizableMessage;
023import org.forgerock.i18n.slf4j.LocalizedLogger;
024import org.forgerock.opendj.config.server.ConfigurationChangeListener;
025import org.forgerock.opendj.server.config.server.FixedTimeLogRotationPolicyCfg;
026import org.forgerock.opendj.config.server.ConfigChangeResult;
027import org.opends.server.util.TimeThread;
028
029/** This class implements a rotation policy based on fixed day/time of day. */
030public class FixedTimeRotationPolicy implements
031    RotationPolicy<FixedTimeLogRotationPolicyCfg>,
032    ConfigurationChangeListener<FixedTimeLogRotationPolicyCfg>
033{
034  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
035
036  /** The scheduled rotation times as ms offsets from the beginning of the day. */
037  private int[] rotationTimes;
038
039  @Override
040  public void initializeLogRotationPolicy(FixedTimeLogRotationPolicyCfg config)
041  {
042    rotationTimes = new int[config.getTimeOfDay().size()];
043
044    int i = 0;
045    for(String time : config.getTimeOfDay())
046    {
047      rotationTimes[i++] = Integer.valueOf(time);
048    }
049
050    Arrays.sort(rotationTimes);
051
052    config.addFixedTimeChangeListener(this);
053  }
054
055  @Override
056  public boolean isConfigurationChangeAcceptable(
057      FixedTimeLogRotationPolicyCfg config, List<LocalizableMessage> unacceptableReasons)
058  {
059    // Changes should always be OK
060    return true;
061  }
062
063  @Override
064  public ConfigChangeResult applyConfigurationChange(
065      FixedTimeLogRotationPolicyCfg config)
066  {
067    final ConfigChangeResult ccr = new ConfigChangeResult();
068
069    rotationTimes = new int[config.getTimeOfDay().size()];
070
071    int i = 0;
072    for(String time : config.getTimeOfDay())
073    {
074      rotationTimes[i++] = Integer.valueOf(time);
075    }
076
077    Arrays.sort(rotationTimes);
078
079    return ccr;
080  }
081
082  @Override
083  public boolean rotateFile(RotatableLogFile writer)
084  {
085    Calendar lastRotationTime = writer.getLastRotationTime();
086
087    Calendar nextRotationTime = (Calendar)lastRotationTime.clone();
088    int i = 0;
089    nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
090    nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
091    nextRotationTime.set(Calendar.SECOND, 0);
092    while(lastRotationTime.after(nextRotationTime))
093    {
094      if(i == rotationTimes.length - 1)
095      {
096        nextRotationTime.add(Calendar.DATE, 1);
097        i = 0;
098      }
099      else
100      {
101        i++;
102      }
103
104      nextRotationTime.set(Calendar.HOUR_OF_DAY, rotationTimes[i] / 100);
105      nextRotationTime.set(Calendar.MINUTE, rotationTimes[i] % 100);
106    }
107
108    logger.trace("The next fixed rotation time is %s", rotationTimes[i]);
109
110    return TimeThread.getCalendar().after(nextRotationTime);
111  }
112}
113