ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL/**
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * The contents of this file are subject to the terms of the Common Development and
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * Distribution License (the License). You may not use this file except in compliance with the
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * License.
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL *
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * specific language governing permission and limitations under the License.
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL *
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * When distributing Covered Software, include this CDDL Header Notice in each file and include
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * Header, with the fields enclosed by brackets [] replaced by your own identifying
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * information: "Portions copyright [year] [name of copyright owner]".
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL *
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * Copyright 2015-2016 ForgeRock AS.
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL */
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELpackage com.sun.identity.shared.debug.file.impl;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport com.sun.identity.shared.debug.DebugConstants;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport com.sun.identity.shared.debug.file.DebugConfiguration;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport org.forgerock.openam.utils.IOUtils;
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTELimport org.forgerock.openam.utils.StringUtils;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport java.io.IOException;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport java.io.InputStream;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport java.text.SimpleDateFormat;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport java.util.Calendar;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELimport java.util.Properties;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL/**
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * Read debug configuration from a properties file.
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL */
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTELpublic class DebugConfigurationFromProperties implements DebugConfiguration {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL private String debugPrefix = "";
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL private String debugSuffix = "";
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL private int rotationInterval = -1;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL private long maxFileSizeInByte = -1;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL /**
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * initialize the properties
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * It will reset the current properties for every Debug instance
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL *
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * @param debugFilePropertiesPath path to the debug configuration file
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL */
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL public DebugConfigurationFromProperties(String debugFilePropertiesPath) throws InvalidDebugConfigurationException {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL InputStream is = null;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL try {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL is = DebugConfigurationFromProperties.class.getResourceAsStream(debugFilePropertiesPath);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL if(is == null) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL throw new InvalidDebugConfigurationException("Can't find the configuration file '" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL debugFilePropertiesPath + "'.");
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL Properties rotationConfig = new Properties();
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL rotationConfig.load(is);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL debugPrefix = rotationConfig.getProperty(DebugConstants.CONFIG_DEBUG_LOGFILE_PREFIX);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL debugSuffix = rotationConfig.getProperty(DebugConstants.CONFIG_DEBUG_LOGFILE_SUFFIX);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL String maxFileSizedInMb = rotationConfig.getProperty(DebugConstants.CONFIG_DEBUG_LOGFILE_MAX_SIZE);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (!StringUtils.isEmpty(maxFileSizedInMb)) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL try {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL maxFileSizeInByte = Integer.parseInt(maxFileSizedInMb);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL //Convert MaxFileSize to byte
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL maxFileSizeInByte <<= 20;
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL } catch (NumberFormatException e) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL //Can't parse the number
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL String message = "The '" + DebugConstants.CONFIG_DEBUG_LOGFILE_MAX_SIZE + "' value : "
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL + maxFileSizedInMb + "' cannot be parsed. Please check the configuration file '"
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL + DebugConstants.CONFIG_DEBUG_PROPERTIES + "'.";
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL StdDebugFile.printError(DebugConfigurationFromProperties.class.getSimpleName(), message, e);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL String rotation = rotationConfig.getProperty(DebugConstants.CONFIG_DEBUG_LOGFILE_ROTATION);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (!StringUtils.isEmpty(rotation)) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL try {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL rotationInterval = Integer.parseInt(rotation);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL } catch (NumberFormatException e) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL //Can't parse the number
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL String message = "'" + DebugConstants.CONFIG_DEBUG_LOGFILE_ROTATION + "' value can't be parsed: '" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL rotation + "'. Please check the configuration file '" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL DebugConstants.CONFIG_DEBUG_PROPERTIES + "'.";
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL StdDebugFile.printError(DebugConfigurationFromProperties.class.getSimpleName(), message, e);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL rotationInterval = -1;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL validate();
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL } catch (IOException ex) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL //it's possible, that we don't have the config file
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL String message = "Can't load debug file properties. Please check the configuration file '" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL debugFilePropertiesPath + "'.";
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL throw new InvalidDebugConfigurationException(message);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL } finally {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL IOUtils.closeIfNotNull(is);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL @Override
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL public String getDebugPrefix() {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL return debugPrefix;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL @Override
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL public String getDebugSuffix() {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL return debugSuffix;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL @Override
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL public int getRotationInterval() {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL return rotationInterval;
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL @Override
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL public long getRotationFileSizeInByte() {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL return maxFileSizeInByte;
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL /**
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * Check if the configuration properties is valid
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL *
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL * @throws InvalidDebugConfigurationException
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL */
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL private void validate() throws InvalidDebugConfigurationException {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (getRotationFileSizeInByte() != -1) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (getRotationFileSizeInByte() <= 0) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL throw new InvalidDebugConfigurationException("File size rotation needs to be greater than " +
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL "zero. File size rotation = '" + getRotationFileSizeInByte() + "'", null);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (getDebugSuffix().isEmpty()) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL throw new InvalidDebugConfigurationException("Log size rotation is enabled (File size rotation = " +
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL getRotationFileSizeInByte() + ") but the debug suffix is empty");
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL // Check the rotation and suffix consistency
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL try {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (validateSuffix(Calendar.MILLISECOND, 1)) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL throw new InvalidDebugConfigurationException("This suffix '" + getDebugSuffix() + "' isn't " +
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL "compatible with the file size rotation enable.");
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL } catch (IllegalArgumentException e) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL throw new InvalidDebugConfigurationException("Suffix '" + getDebugSuffix() + "' can't be parsed.");
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL if (getRotationInterval() != -1) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL if (getRotationInterval() <= 0) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL throw new InvalidDebugConfigurationException("Rotation interval needs to be greater than zero. " +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL "rotationInterval = '" + rotationInterval + "'", null);
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL if (getDebugSuffix().isEmpty()) {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL throw new InvalidDebugConfigurationException("Log time rotation is enabled (rotation interval = " +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL getRotationInterval() + ") but the debug suffix is empty");
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL // Check the rotation and suffix consistency
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL try {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL if (validateSuffix(Calendar.MINUTE, getRotationInterval())) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL throw new InvalidDebugConfigurationException("Suffix '" + getDebugSuffix() + "' isn't compatible" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL " with the rotation interval requested '" + getRotationInterval() + "'.");
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL } catch (IllegalArgumentException e) {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL throw new InvalidDebugConfigurationException("Suffix '" + getDebugSuffix() + "' can't be parsed.");
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL /**
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * Validate Suffix
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * Suffix need to be parse. This function check that the suffix is compatible with the rotation period.
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * @param field Calendar field
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * @param amount number of unit
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * @return true if the suffix generated are different
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL * @throws IllegalArgumentException
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL */
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL private boolean validateSuffix(int field, int amount) throws IllegalArgumentException {
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL // Check the rotation and suffix consistency
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL SimpleDateFormat dateFormat = new SimpleDateFormat(getDebugSuffix());
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL Calendar cal = Calendar.getInstance();
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL cal.setTimeInMillis(0);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL String initialSuffix = dateFormat.format(cal.getTime());
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL cal.add(field, amount);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL String suffixAfterOneRotation = dateFormat.format(cal.getTime());
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL return suffixAfterOneRotation.equals(initialSuffix);
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL }
f3d7790986fe5842757b9e9165466387aa8de864Quentin CASTEL
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL @Override
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL public String toString() {
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL return "DebugConfigurationFromProperties{" +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL "debugPrefix='" + debugPrefix + '\'' +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL ", debugSuffix='" + debugSuffix + '\'' +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL ", rotationInterval=" + rotationInterval +
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL '}';
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL }
ce2e2c2c7126b18ccfce0fe69a3bfa2eafea68b7Quentin CASTEL}