blob: 6812e71ca01f5c0729469ad2cf1bea5af8f1cabf [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.audit;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import org.apache.cassandra.config.ParameterizedClass;
import org.apache.cassandra.utils.Pair;
import static org.apache.cassandra.audit.AuditLogOptionsCompositeData.AuditLogOption.option;
public class AuditLogOptionsCompositeData
{
public static class AuditLogOption
{
// TODO these constants will be used in upcoming audit log vtable too, see CASSANDRA-16725
public static final String AUDIT_LOGS_DIR = "audit_logs_dir";
public static final String ARCHIVE_COMMAND = "archive_command";
public static final String ROLL_CYCLE = "roll_cycle";
public static final String BLOCK = "block";
public static final String MAX_QUEUE_WEIGHT = "max_queue_weight";
public static final String MAX_LOG_SIZE = "max_log_size";
public static final String MAX_ARCHIVE_RETRIES = "max_archive_retries";
public static final String ENABLED = "enabled";
public static final String INCLUDED_KEYSPACES = "included_keyspaces";
public static final String EXCLUDED_KEYSPACES = "excluded_keyspaces";
public static final String INCLUDED_CATEGORIES = "included_categories";
public static final String EXCLUDED_CATEGORIES = "excluded_categories";
public static final String INCLUDED_USERS = "included_users";
public static final String EXCLUDED_USERS = "excluded_users";
public static final String LOGGER = "logger";
private final String name;
private final String description;
private final OpenType<?> type;
private final Function<AuditLogOptions, Object> toCompositeMapping;
private final BiConsumer<AuditLogOptions, Object> fromCompositeMapping;
public AuditLogOption(final String name,
final String description,
final OpenType<?> type,
final Function<AuditLogOptions, Object> toCompositeMapping,
final BiConsumer<AuditLogOptions, Object> fromCompositeMapping)
{
this.name = name;
this.description = description;
this.type = type;
this.toCompositeMapping = toCompositeMapping;
this.fromCompositeMapping = fromCompositeMapping;
}
public static AuditLogOption option(final String name,
final String description,
final OpenType<?> type,
final Function<AuditLogOptions, Object> toCompositeMapping,
final BiConsumer<AuditLogOptions, Object> fromCompositeMapping)
{
return new AuditLogOption(name, description, type, toCompositeMapping, fromCompositeMapping);
}
}
private static final AuditLogOption[] options = new AuditLogOption[]{
option(AuditLogOption.AUDIT_LOGS_DIR,
"directory where audit data are stored",
SimpleType.STRING,
o -> o.audit_logs_dir,
(opts, obj) -> opts.audit_logs_dir = (String) obj),
option(AuditLogOption.ARCHIVE_COMMAND,
"archive command for audit data",
SimpleType.STRING,
o -> o.archive_command,
(opts, obj) -> opts.archive_command = (String) obj),
option(AuditLogOption.ROLL_CYCLE,
"how often to roll BinLog segments so they can potentially be reclaimed",
SimpleType.STRING,
o -> o.roll_cycle,
(opts, obj) -> opts.roll_cycle = (String) obj),
option(AuditLogOption.BLOCK,
"indicates if the BinLog should block if it falls behind or should drop bin log records",
SimpleType.BOOLEAN,
o -> o.block,
(opts, obj) -> opts.block = (Boolean) obj),
option(AuditLogOption.MAX_QUEUE_WEIGHT,
"maximum weight of in-memory queue for records waiting to be written to the binlog file before blocking or dropping the log records",
SimpleType.INTEGER,
o -> o.max_queue_weight,
(opts, obj) -> opts.max_queue_weight = (Integer) obj),
option(AuditLogOption.MAX_LOG_SIZE,
"maximum size of the rolled files to retain on disk before deleting the oldest file",
SimpleType.LONG,
o -> o.max_log_size,
(opts, obj) -> opts.max_log_size = (Long) obj),
option(AuditLogOption.MAX_ARCHIVE_RETRIES,
"number of times to retry an archive command",
SimpleType.INTEGER,
o -> o.max_archive_retries,
(opts, obj) -> opts.max_archive_retries = (Integer) obj),
option(AuditLogOption.ENABLED,
"boolean telling if we are enabled or not",
SimpleType.BOOLEAN,
o -> o.enabled,
(opts, obj) -> opts.enabled = (Boolean) obj),
option(AuditLogOption.INCLUDED_KEYSPACES,
"included keyspaces",
SimpleType.STRING,
o -> o.included_keyspaces,
(opts, obj) -> opts.included_keyspaces = (String) obj),
option(AuditLogOption.EXCLUDED_KEYSPACES,
"excluded keyspaces",
SimpleType.STRING,
o -> o.excluded_keyspaces,
(opts, obj) -> opts.excluded_keyspaces = (String) obj),
option(AuditLogOption.INCLUDED_CATEGORIES,
"included categories",
SimpleType.STRING,
o -> o.included_categories,
(opts, obj) -> opts.included_categories = (String) obj),
option(AuditLogOption.EXCLUDED_CATEGORIES,
"excluded categories",
SimpleType.STRING,
o -> o.excluded_categories,
(opts, obj) -> opts.excluded_categories = (String) obj),
option(AuditLogOption.INCLUDED_USERS,
"included users",
SimpleType.STRING,
o -> o.included_users,
(opts, obj) -> opts.included_users = (String) obj),
option(AuditLogOption.EXCLUDED_USERS,
"excluded users",
SimpleType.STRING,
o -> o.excluded_users,
(opts, obj) -> opts.excluded_users = (String) obj),
option(AuditLogOption.LOGGER,
"audit logger implementation class name",
SimpleType.STRING,
o -> o.logger.class_name,
(opts, obj) -> opts.logger = new ParameterizedClass((String) obj, new HashMap<>()))
};
public static final CompositeType COMPOSITE_TYPE;
static
{
try
{
COMPOSITE_TYPE = new CompositeType(AuditLogOptions.class.getName(),
"AuditLogOptions",
Arrays.stream(options).map(o -> o.name).toArray(String[]::new),
Arrays.stream(options).map(o -> o.description).toArray(String[]::new),
Arrays.stream(options).map(o -> o.type).toArray(OpenType[]::new));
}
catch (final OpenDataException e)
{
throw new RuntimeException(e);
}
}
public static CompositeData toCompositeData(final AuditLogOptions opts)
{
try
{
final Map<String, Object> valueMap = new HashMap<>();
for (final Pair<String, Function<AuditLogOptions, Object>> pair : Arrays.stream(options).map(o -> Pair.create(o.name, o.toCompositeMapping)).collect(Collectors.toList()))
{
valueMap.put(pair.left, pair.right.apply(opts));
}
return new CompositeDataSupport(COMPOSITE_TYPE, valueMap);
}
catch (final OpenDataException e)
{
throw new RuntimeException(e);
}
}
public static AuditLogOptions fromCompositeData(final CompositeData data)
{
assert data.getCompositeType().equals(COMPOSITE_TYPE);
final Object[] values = data.getAll(Arrays.stream(options).map(o -> o.name).toArray(String[]::new));
final AuditLogOptions opts = new AuditLogOptions();
for (int i = 0; i < values.length; i++)
{
options[i].fromCompositeMapping.accept(opts, values[i]);
}
return opts;
}
}