/*
* 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 gobblin.data.management.retention.action;
import java.io.IOException;
import java.util.List;
import org.apache.hadoop.fs.FileSystem;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.typesafe.config.Config;
import com.typesafe.config.ConfigRenderOptions;
import gobblin.data.management.policy.VersionSelectionPolicy;
import gobblin.data.management.retention.dataset.ConfigurableCleanableDataset;
import gobblin.data.management.version.DatasetVersion;
import gobblin.util.ConfigUtils;
/**
* A wrapper around {@link AccessControlAction} that delegates the {@link #execute(List)} call to multiple embedded
* {@link AccessControlAction}s.
* <p>
* The embedded {@link AccessControlAction}s are specified at key <code>policies</code> of the <code>actionConfig</code>.
* If {@link VersionSelectionPolicy}s of different embedded {@link AccessControlAction}s overlap, the last {@link AccessControlAction}
* in <code>policies</code> key wins.
* </p>
* Use {@link MultiAccessControlActionFactory} to create new {@link MultiAccessControlAction}s
*/
public class MultiAccessControlAction extends RetentionAction {
private final List<AccessControlAction> embeddedAccessControlActions;
private static final String POLICIES_KEY = "policies";
/**
* The expected paths in the <code>actionConfig</code> are shown below.
* <pre>
* {
* ## list all the policies, each policy should have a path in the config
* policies = [restricted, .....]
*
* restricted {
* selection {
* policy.class=gobblin.data.management.policy.SelectBeforeTimeBasedPolicy
* timeBased.lookbackTime = 7d
* }
* mode : 750
* owner : onr
* group : grp
* }
* }
* </pre>
* @param actionConfig to use while creating a new {@link MultiAccessControlAction}
* @param fs
*/
private MultiAccessControlAction(Config actionConfig, FileSystem fs, Config jobConfig) {
super(actionConfig, fs, jobConfig);
this.embeddedAccessControlActions = Lists.newArrayList();
for (String policy : ConfigUtils.getStringList(actionConfig, POLICIES_KEY)) {
Preconditions.checkArgument(
actionConfig.hasPath(policy),
String.format("Policy %s is specified at key %s but actionConfig does not have config for this policy."
+ "Complete actionConfig %s", policy, POLICIES_KEY,
actionConfig.root().render(ConfigRenderOptions.concise())));
embeddedAccessControlActions.add(new AccessControlAction(actionConfig.getConfig(policy), fs, jobConfig));
}
}
/**
* Calls {@link AccessControlAction#execute(List)} on each of the embedded {@link AccessControlAction}s
*
* {@inheritDoc}
* @see gobblin.data.management.retention.action.RetentionAction#execute(java.util.List)
*/
@Override
public void execute(List<DatasetVersion> allVersions) throws IOException {
for (AccessControlAction aca : this.embeddedAccessControlActions) {
aca.execute(allVersions);
}
}
/**
* A factory class to create {@link MultiAccessControlAction}s
*/
public static class MultiAccessControlActionFactory implements RetentionActionFactory {
private static String ACCESS_CONTROL_KEY = "accessControl";
private static String LEGACY_ACCESS_CONTROL_KEY = ConfigurableCleanableDataset.RETENTION_CONFIGURATION_KEY + "."
+ ACCESS_CONTROL_KEY;
@Override
public MultiAccessControlAction createRetentionAction(Config config, FileSystem fs, Config jobConfig) {
Preconditions.checkArgument(this.canCreateWithConfig(config),
"Can not create MultiAccessControlAction with config " + config.root().render(ConfigRenderOptions.concise()));
if (config.hasPath(LEGACY_ACCESS_CONTROL_KEY)) {
return new MultiAccessControlAction(config.getConfig(LEGACY_ACCESS_CONTROL_KEY), fs, jobConfig);
} else if (config.hasPath(ACCESS_CONTROL_KEY)) {
return new MultiAccessControlAction(config.getConfig(ACCESS_CONTROL_KEY), fs, jobConfig);
}
throw new IllegalStateException(
"RetentionActionFactory.canCreateWithConfig returned true but could not create MultiAccessControlAction");
}
@Override
public boolean canCreateWithConfig(Config config) {
return config.hasPath(LEGACY_ACCESS_CONTROL_KEY) || config.hasPath(ACCESS_CONTROL_KEY);
}
}
}