/*
* 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.lang.reflect.InvocationTargetException;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.fs.FileSystem;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.typesafe.config.Config;
import gobblin.data.management.dataset.Dataset;
import gobblin.data.management.policy.VersionSelectionPolicy;
import gobblin.data.management.retention.dataset.ConfigurableCleanableDataset;
import gobblin.data.management.retention.dataset.FsCleanableHelper;
import gobblin.data.management.version.DatasetVersion;
import gobblin.data.management.version.finder.VersionFinder;
import gobblin.dataset.DatasetsFinder;
import gobblin.util.ClassAliasResolver;
import gobblin.util.ConfigUtils;
import gobblin.util.reflection.GobblinConstructorUtils;
/**
* An abstraction to perform a retention action for a subset of {@link DatasetVersion}s.
* A few kinds of actions are deletion, access control, encryption, archival etc.
*/
public abstract class RetentionAction {
protected final FileSystem fs;
@SuppressWarnings("rawtypes")
protected final ClassAliasResolver<VersionSelectionPolicy> versionSelectionAliasResolver;
protected final boolean isSimulateMode;
public RetentionAction(Config actionConfig, FileSystem fs, Config jobConfig) {
this.versionSelectionAliasResolver = new ClassAliasResolver<>(VersionSelectionPolicy.class);
this.fs = fs;
this.isSimulateMode = ConfigUtils.getBoolean(jobConfig, FsCleanableHelper.SIMULATE_KEY,
Boolean.valueOf(FsCleanableHelper.SIMULATE_DEFAULT));
}
/**
* Execute the action on all {@link DatasetVersion}s or a subset of {@link DatasetVersion}s. Each {@link Dataset}
* uses the {@link VersionFinder} to find all the {@link DatasetVersion}s and calls this method to perform the necessary
* action on those {@link DatasetVersion}s
* <p>
* <b>Note</b> Any kind of {@link VersionSelectionPolicy} has <b>NOT</b> been applied to the list of {@link DatasetVersion}s
* being passed. It is the responsibility of the {@link RetentionAction} to filter the {@link DatasetVersion}s by
* applying {@link VersionSelectionPolicy}s and then perform the action.
* </p>
* @param allVersions list of all {@link DatasetVersion}s found by the {@link DatasetsFinder}.
*/
public abstract void execute(List<DatasetVersion> allVersions) throws IOException;
/**
* A factory to create new {@link RetentionAction}s
*
*/
public interface RetentionActionFactory {
/**
* A factory method to create a new {@link RetentionAction} using a <code>config</code>. The {@link Dataset} always
* calls {@link #canCreateWithConfig(Config)} before calling this method.
*
* @param config to use to create the {@link RetentionAction}
* @return A new {@link RetentionAction}
*/
RetentionAction createRetentionAction(Config config, FileSystem fs, Config jobConfig);
/**
* Method to check if a {@link RetentionAction} can be created/instantiated with the <code>config</code>.
* If the specific type of {@link RetentionAction} has been specified in the configuration the method returns
* <code>true</code>
* If the method returns <code>true</code>, {@link #createRetentionAction(Config, FileSystem)} can be called to create
* this {@link RetentionAction}.
*
* @param config to use to create the {@link RetentionAction}
* @param jobConfig is the job level config
* @return true if the specific type of {@link RetentionAction} has been specified in the configuration, false otherwise
*/
boolean canCreateWithConfig(Config config);
}
/*
* Since {@link VersionSelectionPolicy} does not have a factory to create new objects we need to use the legacy
* pattern of creating new objects using GobblinConstructorUtils
*/
@SuppressWarnings("unchecked")
protected VersionSelectionPolicy<DatasetVersion> createSelectionPolicy(Config selectionConfig, Config jobConfig) {
try {
String selectionPolicyKey =
StringUtils.substringAfter(ConfigurableCleanableDataset.SELECTION_POLICY_CLASS_KEY,
ConfigurableCleanableDataset.CONFIGURATION_KEY_PREFIX);
Preconditions.checkArgument(selectionConfig.hasPath(selectionPolicyKey));
String className = selectionConfig.getString(selectionPolicyKey);
return (VersionSelectionPolicy<DatasetVersion>) GobblinConstructorUtils.invokeFirstConstructor(
this.versionSelectionAliasResolver.resolveClass(className), ImmutableList.<Object> of(selectionConfig),
ImmutableList.<Object> of(selectionConfig, ConfigUtils.configToProperties(jobConfig)),
ImmutableList.<Object> of(ConfigUtils.configToProperties(jobConfig)));
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException
| ClassNotFoundException e) {
throw new IllegalArgumentException(e);
}
}
}