http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ActionAttributesBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ActionAttributesBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ActionAttributesBuilder.java new file mode 100644 index 0000000..d52b9c9 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ActionAttributesBuilder.java @@ -0,0 +1,567 @@ +/** + * 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.oozie.fluentjob.api.action; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.oozie.fluentjob.api.ModifyOnce; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * A builder class for {@link ActionAttributes}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link ActionAttributesBuilder#build} either. + */ [email protected] [email protected] +public class ActionAttributesBuilder implements Builder<ActionAttributes> { + private final ModifyOnce<String> resourceManager; + private final ModifyOnce<String> nameNode; + private final ModifyOnce<Prepare> prepare; + private final ModifyOnce<Streaming> streaming; + private final ModifyOnce<Pipes> pipes; + private final List<String> jobXmls; + private final Map<String, ModifyOnce<String>> configuration; + private final ModifyOnce<String> configClass; + private final List<String> files; + private final List<String> archives; + private final List<Delete> deletes; + private final List<Mkdir> mkdirs; + private final List<Move> moves; + private final List<Chmod> chmods; + private final List<Touchz> touchzs; + private final List<Chgrp> chgrps; + private final ModifyOnce<String> javaOpts; + private final List<String> args; + private final ModifyOnce<Launcher> launcher; + private final ModifyOnce<Boolean> captureOutput; + + /** + * Creates and returns an empty builder. + * @return An empty builder. + */ + public static ActionAttributesBuilder create() { + final ModifyOnce<String> resourceManager = new ModifyOnce<>(); + final ModifyOnce<String> nameNode = new ModifyOnce<>(); + final ModifyOnce<Prepare> prepare = new ModifyOnce<>(); + final ModifyOnce<Streaming> streaming = new ModifyOnce<>(); + final ModifyOnce<Pipes> pipes = new ModifyOnce<>(); + final List<String> jobXmls = new ArrayList<>(); + final Map<String, ModifyOnce<String>> configuration = new LinkedHashMap<>(); + final ModifyOnce<String> configClass = new ModifyOnce<>(); + final List<String> files = new ArrayList<>(); + final List<String> archives = new ArrayList<>(); + final List<Delete> deletes = new ArrayList<>(); + final List<Mkdir> mkdirs = new ArrayList<>(); + final List<Move> moves = new ArrayList<>(); + final List<Chmod> chmods = new ArrayList<>(); + final List<Touchz> touchzs = new ArrayList<>(); + final List<Chgrp> chgrps = new ArrayList<>(); + final ModifyOnce<String> javaOpts = new ModifyOnce<>(); + final List<String> args = new ArrayList<>(); + final ModifyOnce<Launcher> launcher = new ModifyOnce<>(); + final ModifyOnce<Boolean> captureOutput = new ModifyOnce<>(); + + return new ActionAttributesBuilder( + resourceManager, + prepare, + streaming, + pipes, + jobXmls, + configuration, + configClass, + files, + archives, + deletes, + mkdirs, + moves, + chmods, + touchzs, + chgrps, + javaOpts, + args, + nameNode, + launcher, + captureOutput); + } + + /** + * Create and return a new {@link ActionAttributesBuilder} that is based on an already built + * {@link ActionAttributes} object. The properties of the builder will initially be the same as those of the + * provided {@link ActionAttributes} object, but it is possible to modify them once. + * @param attributes The {@link ActionAttributes} object on which this {@link ActionAttributesBuilder} will be based. + * @return A new {@link ActionAttributesBuilder} that is based on a previously built + * {@link ActionAttributes} object. + */ + public static ActionAttributesBuilder createFromExisting(final ActionAttributes attributes) { + final ModifyOnce<String> resourceManager = new ModifyOnce<>(attributes.getResourceManager()); + final ModifyOnce<String> nameNode = new ModifyOnce<>(attributes.getNameNode()); + final ModifyOnce<Prepare> prepare = new ModifyOnce<>(attributes.getPrepare()); + final ModifyOnce<Streaming> streaming = new ModifyOnce<>(attributes.getStreaming()); + final ModifyOnce<Pipes> pipes = new ModifyOnce<>(attributes.getPipes()); + final List<String> jobXmls = new ArrayList<>(attributes.getJobXmls()); + final Map<String, ModifyOnce<String>> configuration = convertToModifyOnceMap(attributes.getConfiguration()); + final ModifyOnce<String> configClass = new ModifyOnce<>(attributes.getConfigClass()); + final List<String> files = new ArrayList<>(attributes.getFiles()); + final List<String> archives = new ArrayList<>(attributes.getArchives()); + final List<Delete> deletes = new ArrayList<>(attributes.getDeletes()); + final List<Mkdir> mkdirs = new ArrayList<>(attributes.getMkdirs()); + final List<Move> moves = new ArrayList<>(attributes.getMoves()); + final List<Chmod> chmods = new ArrayList<>(attributes.getChmods()); + final List<Touchz> touchzs = new ArrayList<>(attributes.getTouchzs()); + final List<Chgrp> chgrps = new ArrayList<>(attributes.getChgrps()); + final ModifyOnce<String> javaOpts = new ModifyOnce<>(attributes.getJavaOpts()); + final List<String> args = new ArrayList<>(attributes.getArgs()); + final ModifyOnce<Launcher> launcher = new ModifyOnce<>(attributes.getLauncher()); + final ModifyOnce<Boolean> captureOutput = new ModifyOnce<>(attributes.isCaptureOutput()); + + return new ActionAttributesBuilder( + resourceManager, + prepare, + streaming, + pipes, + jobXmls, + configuration, + configClass, + files, + archives, + deletes, + mkdirs, + moves, + chmods, + touchzs, + chgrps, + javaOpts, + args, + nameNode, + launcher, + captureOutput); + } + + public static ActionAttributesBuilder createFromAction(final Node action) { + if (HasAttributes.class.isAssignableFrom(action.getClass()) && action instanceof HasAttributes) { + return ActionAttributesBuilder.createFromExisting(((HasAttributes) action).getAttributes()); + } + + return ActionAttributesBuilder.create(); + } + + private ActionAttributesBuilder(final ModifyOnce<String> resourceManager, + final ModifyOnce<Prepare> prepare, + final ModifyOnce<Streaming> streaming, + final ModifyOnce<Pipes> pipes, + final List<String> jobXmls, + final Map<String, ModifyOnce<String>> configuration, + final ModifyOnce<String> configClass, + final List<String> files, + final List<String> archives, + final List<Delete> deletes, + final List<Mkdir> mkdirs, + final List<Move> moves, + final List<Chmod> chmods, + final List<Touchz> touchzs, + final List<Chgrp> chgrps, + final ModifyOnce<String> javaOpts, + final List<String> args, + final ModifyOnce<String> nameNode, + final ModifyOnce<Launcher> launcher, + final ModifyOnce<Boolean> captureOutput) { + this.nameNode = nameNode; + this.prepare = prepare; + this.streaming = streaming; + this.pipes = pipes; + this.jobXmls = jobXmls; + this.configuration = configuration; + this.configClass = configClass; + this.files = files; + this.archives = archives; + this.deletes = deletes; + this.mkdirs = mkdirs; + this.moves = moves; + this.chmods = chmods; + this.touchzs = touchzs; + this.chgrps = chgrps; + this.javaOpts = javaOpts; + this.args = args; + this.resourceManager = resourceManager; + this.launcher = launcher; + this.captureOutput = captureOutput; + } + + public void withResourceManager(final String resourceManager) { + this.resourceManager.set(resourceManager); + } + + /** + * Registers a name node. + * @param nameNode The string representing the name node. + * @throws IllegalStateException if a name node has already been set on this builder. + */ + public void withNameNode(final String nameNode) { + this.nameNode.set(nameNode); + } + + /** + * Registers a {@link Prepare} object. + * @param prepare The {@link Prepare} object to register. + * @throws IllegalStateException if a {@link Prepare} object has already been set on this builder. + */ + void withPrepare(final Prepare prepare) { + this.prepare.set(prepare); + } + + /** + * Registers a {@link Streaming} object. + * @param streaming The {@link Streaming} object to register. + * @throws IllegalStateException if a {@link Streaming} object has already been set on this builder. + */ + void withStreaming(final Streaming streaming) { + this.streaming.set(streaming); + } + + /** + * Registers a {@link Pipes} object. + * @param pipes The {@link Pipes} object to register. + * @throws IllegalStateException if a {@link Pipes} object has already been set on this builder. + */ + void withPipes(final Pipes pipes) { + this.pipes.set(pipes); + } + + /** + * Registers a job XML with this builder. + * @param jobXml The job XML to register. + */ + public void withJobXml(final String jobXml) { + this.jobXmls.add(jobXml); + } + + /** + * Removes a job XML if it is registered with this builder, otherwise does nothing. + * @param jobXml The job XML to remove. + */ + public void withoutJobXml(final String jobXml) { + jobXmls.remove(jobXml); + } + + /** + * Removes all job XMLs that are registered with this builder. + */ + public void clearJobXmls() { + jobXmls.clear(); + } + + /** + * Registers a configuration property (a key-value pair) with this builder. If the provided key has already been + * set on this builder, an exception is thrown. Setting a key to null means deleting it. + * @param key The name of the property to set. + * @param value The value of the property to set. + * @throws IllegalStateException if the provided key has already been set on this builder. + */ + public void withConfigProperty(final String key, final String value) { + ModifyOnce<String> mappedValue = this.configuration.get(key); + + if (mappedValue == null) { + mappedValue = new ModifyOnce<>(value); + this.configuration.put(key, mappedValue); + } + + mappedValue.set(value); + } + + /** + * Registers a configuration class with this builder. + * @param configClass The string representing the configuration class. + * @throws IllegalStateException if a configuration class has already been set on this builder. + */ + void withConfigClass(final String configClass) { + this.configClass.set(configClass); + } + + /** + * Registers a file with this builder. + * @param file The file to register. + */ + void withFile(final String file) { + this.files.add(file); + } + + /** + * Removes a file if it is registered with this builder, otherwise does nothing. + * @param file The file to remove. + */ + void withoutFile(final String file) { + files.remove(file); + } + + /** + * Removes all files that are registered with this builder. + */ + void clearFiles() { + files.clear(); + } + + /** + * Registers an archive with this builder. + * @param archive The archive to register. + */ + void withArchive(final String archive) { + this.archives.add(archive); + } + + /** + * Removes an archive if it is registered with this builder, otherwise does nothing. + * @param archive The archive to remove. + */ + void withoutArchive(final String archive) { + archives.remove(archive); + } + + /** + * Removes all archives that are registered with this builder. + */ + void clearArchives() { + archives.clear(); + } + + /** + * Registers a {@link Delete} object with this builder. + * @param delete The {@link Delete} object to register. + */ + void withDelete(final Delete delete) { + this.deletes.add(delete); + } + + /** + * Removes a {@link Delete} object if it is registered with this builder, otherwise does nothing. + * @param delete The {@link Delete} object to remove. + */ + void withoutDelete(final Delete delete) { + deletes.remove(delete); + } + + /** + * Removes all {@link Delete} objects that are registered with this builder. + */ + void clearDeletes() { + deletes.clear(); + } + + /** + * Registers a {@link Mkdir} object with this builder. + * @param mkdir The {@link Mkdir} object to register. + */ + void withMkdir(final Mkdir mkdir) { + this.mkdirs.add(mkdir); + } + + /** + * Removes a {@link Mkdir} object if it is registered with this builder, otherwise does nothing. + * @param mkdir The {@link Mkdir} object to remove. + */ + void withoutMkdir(final Mkdir mkdir) { + mkdirs.remove(mkdir); + } + + /** + * Removes all {@link Mkdir} objects that are registered with this builder. + */ + void clearMkdirs() { + mkdirs.clear(); + } + + /** + * Registers a {@link Move} object with this builder. + * @param move The {@link Move} object to register. + */ + void withMove(final Move move) { + this.moves.add(move); + } + + /** + * Removes a {@link Move} object if it is registered with this builder, otherwise does nothing. + * @param move The {@link Move} object to remove. + */ + void withoutMove(final Move move) { + moves.remove(move); + } + + /** + * Removes all {@link Move} objects that are registered with this builder. + */ + void clearMoves() { + moves.clear(); + } + + /** + * Registers a {@link Chmod} object with this builder. + * @param chmod The {@link Chmod} object to register. + */ + void withChmod(final Chmod chmod) { + this.chmods.add(chmod); + } + + /** + * Removes a {@link Chmod} object if it is registered with this builder, otherwise does nothing. + * @param chmod The {@link Chmod} object to remove. + */ + void withoutChmod(final Chmod chmod) { + chmods.remove(chmod); + } + + /** + * Removes all {@link Chmod} objects that are registered with this builder. + */ + void clearChmods() { + chmods.clear(); + } + + /** + * Registers a {@link Touchz} object with this builder. + * @param touchz The {@link Touchz} object to register. + */ + void withTouchz(final Touchz touchz) { + this.touchzs.add(touchz); + } + + /** + * Removes a {@link Touchz} object if it is registered with this builder, otherwise does nothing. + * @param touchz The {@link Touchz} object to remove. + */ + void withoutTouchz(final Touchz touchz) { + touchzs.remove(touchz); + } + + /** + * Removes all {@link Touchz} objects that are registered with this builder. + */ + void clearTouchzs() { + touchzs.clear(); + } + + /** + * Registers a {@link Chgrp} object with this builder. + * @param chgrp The {@link Chgrp} object to register. + */ + void withChgrp(final Chgrp chgrp) { + this.chgrps.add(chgrp); + } + + /** + * Removes a {@link Chgrp} object if it is registered with this builder, otherwise does nothing. + * @param chgrp The {@link Chgrp} object to remove. + */ + void withoutChgrp(final Chgrp chgrp) { + chgrps.remove(chgrp); + } + + /** + * Removes all {@link Chgrp} objects that are registered with this builder. + */ + void clearChgrps() { + chgrps.clear(); + } + + void withJavaOpts(final String javaOpts) { + this.javaOpts.set(javaOpts); + } + + void withArg(final String arg) { + this.args.add(arg); + } + + void withoutArg(final String arg) { + this.args.remove(arg); + } + + void clearArgs() { + args.clear(); + } + + public void withLauncher(final Launcher launcher) { + this.launcher.set(launcher); + } + + void withCaptureOutput(final Boolean captureOutput) { + this.captureOutput.set(captureOutput); + } + + /** + * Creates a new {@link ActionAttributes} object with the properties stores in this builder. + * The new {@link ActionAttributes} object is independent of this builder and the builder can be used to build + * new instances. + * @return A new {@link ActionAttributes} object with the propertied stores in this builder. + */ + public ActionAttributes build() { + return new ActionAttributes( + resourceManager.get(), + nameNode.get(), + prepare.get(), + streaming.get(), + pipes.get(), + ImmutableList.copyOf(jobXmls), + convertToConfigurationMap(configuration), + configClass.get(), + ImmutableList.copyOf(files), + ImmutableList.copyOf(archives), + ImmutableList.copyOf(deletes), + ImmutableList.copyOf(mkdirs), + ImmutableList.copyOf(moves), + ImmutableList.copyOf(chmods), + ImmutableList.copyOf(touchzs), + ImmutableList.copyOf(chgrps), + javaOpts.get(), + ImmutableList.copyOf(args), + launcher.get(), + captureOutput.get()); + } + + static Map<String, ModifyOnce<String>> convertToModifyOnceMap(final Map<String, String> configurationMap) { + final Map<String, ModifyOnce<String>> modifyOnceEntries = new LinkedHashMap<>(); + + for (final Map.Entry<String, String> keyAndValue : configurationMap.entrySet()) { + modifyOnceEntries.put(keyAndValue.getKey(), new ModifyOnce<>(keyAndValue.getValue())); + } + + return modifyOnceEntries; + } + + static ImmutableMap<String, String> convertToConfigurationMap(final Map<String, ModifyOnce<String>> map) { + final Map<String, String> mutableConfiguration = new LinkedHashMap<>(); + + for (final Map.Entry<String, ModifyOnce<String>> modifyOnceEntry : map.entrySet()) { + if (modifyOnceEntry.getValue().get() != null) { + mutableConfiguration.put(modifyOnceEntry.getKey(), modifyOnceEntry.getValue().get()); + } + } + + return ImmutableMap.copyOf(mutableConfiguration); + } +}
http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Builder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Builder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Builder.java new file mode 100644 index 0000000..c71a04b --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Builder.java @@ -0,0 +1,31 @@ +/** + * 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.oozie.fluentjob.api.action; + +/** + * A common interface for builders. + * @param <T> The type of the object that is build using this builder. + */ +public interface Builder<T> { + /** + * Builds and returns an object. + * @return The built object. + */ + T build(); +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBase.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBase.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBase.java new file mode 100644 index 0000000..2fc1ff6 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBase.java @@ -0,0 +1,81 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A base class for {@link Chgrp} and {@link Chmod}. + */ [email protected] [email protected] +public class ChFSBase { + private final boolean recursive; + private final String path; + private final String dirFiles; + + ChFSBase(final ConstructionData constructionData) { + this.recursive = constructionData.recursive; + this.path = constructionData.path; + this.dirFiles = constructionData.dirFiles; + } + + /** + * Returns whether this file system operation is recursive. + * @return {@code true} if this file system operation is recursive; {@code false} otherwise. + */ + public boolean isRecursive() { + return recursive; + } + + /** + * Returns the path of the target of this file system operation. + * @return The path of the target of this file system operation. + */ + public String getPath() { + return path; + } + + /** + * Returns whether this file system operation should be applied to all files in the given directory. + * @return "true" if this file system operation should be applied to all files in the given directory; + * "false" otherwise. + */ + public String getDirFiles() { + return dirFiles; + } + + /** + * Helper class that is used by the subclasses of this class and their builders. + */ + public static class ConstructionData { + private final boolean recursive; + private final String path; + private final String dirFiles; + + public ConstructionData(final boolean recursive, + final String path, + final String dirFiles) { + this.recursive = recursive; + this.path = path; + this.dirFiles = dirFiles; + } + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBaseBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBaseBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBaseBuilder.java new file mode 100644 index 0000000..d1303ac --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChFSBaseBuilder.java @@ -0,0 +1,95 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.oozie.fluentjob.api.ModifyOnce; + +/** + * A base class for {@link ChgrpBuilder} and {@link ChmodBuilder}. + */ [email protected] [email protected] +public abstract class ChFSBaseBuilder <B extends ChFSBaseBuilder<B>> { + private final ModifyOnce<Boolean> recursive; + private final ModifyOnce<String> path; + private final ModifyOnce<String> dirFiles; + + public ChFSBaseBuilder() { + recursive = new ModifyOnce<>(false); + path = new ModifyOnce<>(); + dirFiles = new ModifyOnce<>("true"); + } + + /** + * Sets this file system operation to be recursive. + * @return This builder. + */ + public B setRecursive() { + this.recursive.set(true); + return ensureRuntimeSelfReference(); + } + + /** + * Sets this file system operation to be non-recursive. + * @return This builder. + */ + public B setNonRecursive() { + this.recursive.set(false); + return ensureRuntimeSelfReference(); + } + + /** + * Sets the path of the target of this file system operation. + * @param path the path of the target + * @return This builder. + */ + public B withPath(final String path) { + this.path.set(path); + return ensureRuntimeSelfReference(); + } + + /** + * Sets whether this file system operation should be applied to all files in the given directory. + * @param dirFiles {@code true} if the operation should be applied to all files in the given directory; + * {@code false} if it shouldn't. + * @return This builder. + */ + public B setDirFiles(final boolean dirFiles) { + this.dirFiles.set(Boolean.toString(dirFiles)); + return ensureRuntimeSelfReference(); + } + + final B ensureRuntimeSelfReference() { + final B concrete = getRuntimeSelfReference(); + if (concrete != this) { + throw new IllegalStateException( + "The builder type B doesn't extend ChFSBaseBuilder<B>."); + } + + return concrete; + } + + protected ChFSBase.ConstructionData getConstructionData() { + return new ChFSBase.ConstructionData(recursive.get(), path.get(), dirFiles.get()); + } + + protected abstract B getRuntimeSelfReference(); +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chgrp.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chgrp.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chgrp.java new file mode 100644 index 0000000..1fa77eb --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chgrp.java @@ -0,0 +1,53 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A class representing the chgrp command of {@link FSAction}. + * Instances of this class should be built using the builder {@link ChgrpBuilder}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link ChgrpBuilder#build} either. + */ [email protected] [email protected] +public class Chgrp extends ChFSBase { + private String group; + + Chgrp(final ChFSBase.ConstructionData constructionData, + final String group) { + super(constructionData); + this.group = group; + } + + + /** + * Returns the new group that will be set by the command. + * @return The new group that will be set by the command. + */ + public String getGroup() { + return group; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChgrpBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChgrpBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChgrpBuilder.java new file mode 100644 index 0000000..05cbe9b --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChgrpBuilder.java @@ -0,0 +1,68 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.oozie.fluentjob.api.ModifyOnce; + +/** + * A builder class for {@link Chgrp}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link ChgrpBuilder#build} either. + */ [email protected] [email protected] +public class ChgrpBuilder extends ChFSBaseBuilder<ChgrpBuilder> implements Builder<Chgrp> { + private final ModifyOnce<String> group; + + public ChgrpBuilder() { + this.group = new ModifyOnce<>(); + } + + /** + * Sets the new group that will be set by the operation. + * @param group The group that will be set by the operation. + * @return This builder. + */ + public ChgrpBuilder withGroup(final String group) { + this.group.set(group); + return this; + } + + /** + * Builds and returns a new {@link Chgrp} object with the properties set in this builder. + * The new {@link Chgrp} object is independent of this builder and the builder can be used to build new instances. + * @return The newly built {@link Chgrp} object. + */ + @Override + public Chgrp build() { + return new Chgrp(getConstructionData(), group.get()); + } + + @Override + protected ChgrpBuilder getRuntimeSelfReference() { + return this; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chmod.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chmod.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chmod.java new file mode 100644 index 0000000..b0e998b --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Chmod.java @@ -0,0 +1,52 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A class representing the chmod command of {@link FSAction}. + * Instances of this class should be built using the builder {@link ChmodBuilder}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link ChmodBuilder#build} either. + */ [email protected] [email protected] +public class Chmod extends ChFSBase { + private final String permissions; + + Chmod(final ChFSBase.ConstructionData constructionData, + final String permissions) { + super(constructionData); + this.permissions = permissions; + } + + /** + * Returns the new permissions that will be set by the command. + * @return The new permissions that will be set by the command. + */ + public String getPermissions() { + return permissions; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChmodBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChmodBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChmodBuilder.java new file mode 100644 index 0000000..a6b439a --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ChmodBuilder.java @@ -0,0 +1,68 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.oozie.fluentjob.api.ModifyOnce; + +/** + * A builder class for {@link Chmod}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link ChmodBuilder#build} either. + */ [email protected] [email protected] +public class ChmodBuilder extends ChFSBaseBuilder<ChmodBuilder> implements Builder<Chmod> { + private final ModifyOnce<String> permissions; + + public ChmodBuilder() { + super(); + permissions = new ModifyOnce<>(); + } + + /** + * Sets the new permissions that will be set by the operation. + * @param permissions The new permissions that will be set by the operation. + * @return This builder. + */ + public ChmodBuilder withPermissions(final String permissions) { + this.permissions.set(permissions); + return this; + } + + /** + * Builds and returns a new {@link Chmod} object with the properties set in this builder. + * The new {@link Chmod} object is independent of this builder and the builder can be used to build new instances. + * @return The newly built {@link Chmod} object. + */ + public Chmod build() { + return new Chmod(getConstructionData(), permissions.get()); + } + + @Override + protected ChmodBuilder getRuntimeSelfReference() { + return this; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Delete.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Delete.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Delete.java new file mode 100644 index 0000000..17aab7f --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/Delete.java @@ -0,0 +1,60 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A class representing the delete operation of {@link FSAction} and the prepare section of other actions. + */ [email protected] [email protected] +public class Delete { + private final String path; + private final Boolean skipTrash; + + /** + * Creates a new {@link Delete} object. + * @param path The path of the file or directory to be deleted. + * @param skipTrash {@code true} if the deleted items should NOT be moved to the trash but deleted completely; + * {@code false} if the items should be moved to trash instead of deleting them conpletely. + */ + public Delete(final String path, final Boolean skipTrash) { + this.path = path; + this.skipTrash = skipTrash; + } + + /** + * Returns the path of the item to be deleted. + * @return The path of the item to be deleted. + */ + public String getPath() { + return path; + } + + /** + * Returns whether the trash should be skipped when deleting the items. + * @return {@code true} if the deleted items should NOT be moved to the trash but deleted completely; + * {@code false} if the items should be moved to trash instead of deleting them conpletely. + */ + public Boolean getSkipTrash() { + return skipTrash; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpAction.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpAction.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpAction.java new file mode 100644 index 0000000..3886af6 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpAction.java @@ -0,0 +1,80 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +import java.util.List; +import java.util.Map; + +/** + * Represents the Oozie DistCp action. + * Instances of this class should be built using the builder {@link DistcpActionBuilder}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link DistcpActionBuilder#build} either. + */ [email protected] [email protected] +public class DistcpAction extends Node implements HasAttributes { + private final ActionAttributes attributes; + + DistcpAction(final ConstructionData constructionData, + final ActionAttributes attributes) { + super(constructionData); + + this.attributes = attributes; + } + + public String getResourceManager() { + return attributes.getResourceManager(); + } + + public String getNameNode() { + return attributes.getNameNode(); + } + + public Prepare getPrepare() { + return attributes.getPrepare(); + } + + public String getConfigProperty(final String property) { + return attributes.getConfiguration().get(property); + } + + public Map<String, String> getConfiguration() { + return attributes.getConfiguration(); + } + + public String getJavaOpts() { + return attributes.getJavaOpts(); + } + + public List<String> getArgs() { + return attributes.getArgs(); + } + + public ActionAttributes getAttributes() { + return attributes; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpActionBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpActionBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpActionBuilder.java new file mode 100644 index 0000000..42731ef --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/DistcpActionBuilder.java @@ -0,0 +1,118 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A builder class for {@link DistcpAction}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link DistcpActionBuilder#build} either. + */ [email protected] [email protected] +public class DistcpActionBuilder extends NodeBuilderBaseImpl<DistcpActionBuilder> implements Builder<DistcpAction> { + private final ActionAttributesBuilder attributesBuilder; + + public static DistcpActionBuilder create() { + final ActionAttributesBuilder builder = ActionAttributesBuilder.create(); + + return new DistcpActionBuilder( + null, + builder); + } + + public static DistcpActionBuilder createFromExistingAction(final Node action) { + final ActionAttributesBuilder builder = ActionAttributesBuilder.createFromAction(action); + + return new DistcpActionBuilder(action, + builder); + } + + DistcpActionBuilder(final Node action, + final ActionAttributesBuilder attributesBuilder) { + super(action); + + this.attributesBuilder = attributesBuilder; + } + + public DistcpActionBuilder withResourceManager(final String resourceManager) { + attributesBuilder.withResourceManager(resourceManager); + return this; + } + + public DistcpActionBuilder withNameNode(final String nameNode) { + attributesBuilder.withNameNode(nameNode); + return this; + } + + public DistcpActionBuilder withPrepare(final Prepare prepare) { + attributesBuilder.withPrepare(prepare); + return this; + } + + public DistcpActionBuilder withConfigProperty(final String key, final String value) { + attributesBuilder.withConfigProperty(key, value); + return this; + } + + public DistcpActionBuilder withJavaOpts(final String javaOpts) { + attributesBuilder.withJavaOpts(javaOpts); + return this; + } + + public DistcpActionBuilder withArg(final String arg) { + attributesBuilder.withArg(arg); + return this; + } + + public DistcpActionBuilder withoutArg(final String arg) { + attributesBuilder.withoutArg(arg); + return this; + } + + public DistcpActionBuilder clearArgs() { + attributesBuilder.clearArgs(); + return this; + } + + @Override + public DistcpAction build() { + final Node.ConstructionData constructionData = getConstructionData(); + + final DistcpAction instance = new DistcpAction( + constructionData, + attributesBuilder.build()); + + addAsChildToAllParents(instance); + + return instance; + } + + @Override + protected DistcpActionBuilder getRuntimeSelfReference() { + return this; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailAction.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailAction.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailAction.java new file mode 100644 index 0000000..bbaecbc --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailAction.java @@ -0,0 +1,118 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A class representing the Oozie email action. + * Instances of this class should be built using the builder {@link EmailActionBuilder}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link EmailActionBuilder#build} either. + */ [email protected] [email protected] +public class EmailAction extends Node { + private final String to; + private final String cc; + private final String bcc; + private final String subject; + private final String body; + private final String contentType; + private final String attachment; + + EmailAction(final Node.ConstructionData constructionData, + final String to, + final String cc, + final String bcc, + final String subject, + final String body, + final String contentType, + final String attachment) { + super(constructionData); + this.to = to; + this.cc = cc; + this.bcc = bcc; + this.subject = subject; + this.body = body; + this.contentType = contentType; + this.attachment = attachment; + } + + /** + * Returns the address of the recipient of the email. + * @return The address of the recipient of the email. + */ + public String getRecipient() { + return to; + } + + /** + * Returns the address of the recipient of a copy of the email. + * @return The address of the recipient of a copy of the email. + */ + public String getCc() { + return cc; + } + + /** + * Returns the address of the secret recipient of a copy of the email. + * @return The address of the secret recipient of a copy of the email. + */ + public String getBcc() { + return bcc; + } + + /** + * Returns the subject of the email. + * @return The subject of the email. + */ + public String getSubject() { + return subject; + } + + /** + * Returns the body of the email. + * @return The body of the email. + */ + public String getBody() { + return body; + } + + /** + * Returns the content type of the email. + * @return The content type of the email. + */ + public String getContentType() { + return contentType; + } + + /** + * Returns the attachment of the email. + * @return The attachment of the email. + */ + public String getAttachment() { + return attachment; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailActionBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailActionBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailActionBuilder.java new file mode 100644 index 0000000..fb78f97 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/EmailActionBuilder.java @@ -0,0 +1,234 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; +import org.apache.oozie.fluentjob.api.ModifyOnce; + +/** + * A builder class for {@link EmailAction}. + * <p> + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * <p> + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link EmailActionBuilder#build} either. + */ [email protected] [email protected] +public class EmailActionBuilder extends NodeBuilderBaseImpl<EmailActionBuilder> implements Builder<EmailAction> { + private final ModifyOnce<String> to; + private final ModifyOnce<String> cc; + private final ModifyOnce<String> bcc; + private final ModifyOnce<String> subject; + private final ModifyOnce<String> body; + private final ModifyOnce<String> contentType; + private final ModifyOnce<String> attachment; + + /** + * Creates and returns an empty builder. + * @return An empty builder. + */ + public static EmailActionBuilder create() { + final ModifyOnce<String> to = new ModifyOnce<>(); + final ModifyOnce<String> cc = new ModifyOnce<>(); + final ModifyOnce<String> bcc = new ModifyOnce<>(); + final ModifyOnce<String> subject = new ModifyOnce<>(); + final ModifyOnce<String> body = new ModifyOnce<>(); + final ModifyOnce<String> contentType = new ModifyOnce<>(); + final ModifyOnce<String> attachment = new ModifyOnce<>(); + + return new EmailActionBuilder( + null, + to, + cc, + bcc, + subject, + body, + contentType, + attachment); + } + + /** + * Create and return a new {@link EmailActionBuilder} that is based on an already built + * {@link EmailAction} object. The properties of the builder will initially be the same as those of the + * provided {@link EmailAction} object, but it is possible to modify them once. + * @param action The {@link EmailAction} object on which this {@link EmailActionBuilder} will be based. + * @return A new {@link EmailActionBuilder} that is based on a previously built {@link EmailAction} object. + */ + public static EmailActionBuilder createFromExistingAction(final EmailAction action) { + final ModifyOnce<String> to = new ModifyOnce<>(action.getRecipient()); + final ModifyOnce<String> cc = new ModifyOnce<>(action.getCc()); + final ModifyOnce<String> bcc = new ModifyOnce<>(action.getBcc()); + final ModifyOnce<String> subject = new ModifyOnce<>(action.getSubject()); + final ModifyOnce<String> body = new ModifyOnce<>(action.getBody()); + final ModifyOnce<String> contentType = new ModifyOnce<>(action.getContentType()); + final ModifyOnce<String> attachment = new ModifyOnce<>(action.getAttachment()); + + return new EmailActionBuilder( + action, + to, + cc, + bcc, + subject, + body, + contentType, + attachment); + } + + public static EmailActionBuilder createFromExistingAction(final Node action) { + final ModifyOnce<String> to = new ModifyOnce<>(); + final ModifyOnce<String> cc = new ModifyOnce<>(); + final ModifyOnce<String> bcc = new ModifyOnce<>(); + final ModifyOnce<String> subject = new ModifyOnce<>(); + final ModifyOnce<String> body = new ModifyOnce<>(); + final ModifyOnce<String> contentType = new ModifyOnce<>(); + final ModifyOnce<String> attachment = new ModifyOnce<>(); + + return new EmailActionBuilder( + action, + to, + cc, + bcc, + subject, + body, + contentType, + attachment); + } + + EmailActionBuilder(final Node action, + final ModifyOnce<String> to, + final ModifyOnce<String> cc, + final ModifyOnce<String> bcc, + final ModifyOnce<String> subject, + final ModifyOnce<String> body, + final ModifyOnce<String> contentType, + final ModifyOnce<String> attachment) { + super(action); + this.to = to; + this.cc = cc; + this.bcc = bcc; + this.subject = subject; + this.body = body; + this.contentType = contentType; + this.attachment = attachment; + } + + /** + * Sets the address of the recipient of the email. + * @param to the recipient in To: field + * @return This builder. + */ + public EmailActionBuilder withRecipient(final String to) { + this.to.set(to); + return this; + } + + /** + * Sets the address of the recipient of a copy of the email. + * @param cc the recipient in CC: field + * @return This builder. + */ + public EmailActionBuilder withCc(final String cc) { + this.cc.set(cc); + return this; + } + + /** + * Sets the address of the secret recipient of a copy of the email. + * @param bcc the recipient in BCC: field + * @return This builder. + */ + public EmailActionBuilder withBcc(final String bcc) { + this.bcc.set(bcc); + return this; + } + + /** + * Sets the subject of the email. + * @param subject the email subject + * @return This builder. + */ + public EmailActionBuilder withSubject(final String subject) { + this.subject.set(subject); + return this; + } + + /** + * Sets the body of the email. + * @param body the email body + * @return This builder. + */ + public EmailActionBuilder withBody(final String body) { + this.body.set(body); + return this; + } + + /** + * Sets the content type of the email. + * @param contentType the email content type + * @return This builder + */ + public EmailActionBuilder withContentType(final String contentType) { + this.contentType.set(contentType); + return this; + } + + /** + * Sets the attachment of the email. + * @param attachment the email attachment path + * @return This builder. + */ + public EmailActionBuilder withAttachment(final String attachment) { + this.attachment.set(attachment); + return this; + } + + /** + * Creates a new {@link EmailAction} object with the properties stores in this builder. + * The new {@link EmailAction} object is independent of this builder and the builder can be used to build + * new instances. + * @return A new {@link EmailAction} object with the properties stored in this builder. + */ + @Override + public EmailAction build() { + final Node.ConstructionData constructionData = getConstructionData(); + + final EmailAction instance = new EmailAction( + constructionData, + to.get(), + cc.get(), + bcc.get(), + subject.get(), + body.get(), + contentType.get(), + attachment.get()); + + addAsChildToAllParents(instance); + + return instance; + } + + @Override + protected EmailActionBuilder getRuntimeSelfReference() { + return this; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ErrorHandler.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ErrorHandler.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ErrorHandler.java new file mode 100644 index 0000000..6129b9f --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/ErrorHandler.java @@ -0,0 +1,78 @@ +/** + * 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.oozie.fluentjob.api.action; + +import com.google.common.base.Preconditions; +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A class encapsulating an action so that it can be used as an error handler in a workflow. + * + * In an Oozie workflow definition (XML), every action has an "ok-transition" that is taken if the action completed + * successfully and an "error-transition" that is taken if the action failed. In this API, the dependency relations + * specified will be translated into "ok-transitions". + * + * If you would like to provide some error handling in case of action failure, you should add an {@link ErrorHandler} + * to the {@link Node} representing the action. The error handler action will be added as the "error-transition" of + * the original action in the generated Oozie workflow XML. Both the "ok-transition" and the "error-transition" of the + * error handler action itself will lead to an autogenerated kill node. + */ [email protected] [email protected] +public class ErrorHandler { + private final Node handlerNode; + + /** + * Creates a new {@link ErrorHandler}. The provided builder is used to build the underlying error handler action. + * The builder should be in a state where no parents are specified, otherwise an exception is thrown. + * @param builder The builder that is used to build the underlying error handler node. + * @return A new {@link ErrorHandler}. + * + * @throws IllegalStateException if the provided builder has parents registered. + */ + public static ErrorHandler buildAsErrorHandler(final Builder<? extends Node> builder) { + final Node handlerNode = builder.build(); + return new ErrorHandler(handlerNode); + } + + private ErrorHandler(final Node handlerNode) { + final boolean hasParents = !handlerNode.getAllParents().isEmpty(); + final boolean hasChildren = !handlerNode.getAllChildren().isEmpty(); + Preconditions.checkState(!hasParents && !hasChildren, "Error handler nodes cannot have parents or children."); + + this.handlerNode = handlerNode; + } + + /** + * Returns the name of the error handler action. + * @return The name of the error handler action. + */ + public String getName() { + return handlerNode.getName(); + } + + /** + * Returns the error handler action node. + * @return The error handler action node. + */ + public Node getHandlerNode() { + return handlerNode; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSAction.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSAction.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSAction.java new file mode 100644 index 0000000..5d10e80 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSAction.java @@ -0,0 +1,137 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +import java.util.List; +import java.util.Map; + +/** + * A class representing the Oozie file system action. + * Instances of this class should be built using the builder {@link FSActionBuilder}. + * + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. + * + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link FSActionBuilder#build} either. + */ [email protected] [email protected] +public class FSAction extends Node implements HasAttributes { + private final ActionAttributes attributes; + + FSAction(final Node.ConstructionData constructionData, + final ActionAttributes attributes) { + super(constructionData); + + this.attributes = attributes; + } + + /** + * Returns the name node used by this {@link FSAction}. + * @return The name node used by this {@link FSAction}. + */ + public String getNameNode() { + return attributes.getNameNode(); + } + + /** + * Returns the list of job XMLs used by this {@link FSAction}. + * @return The list of job XMLs used by this {@link FSAction}. + */ + public List<String> getJobXmls() { + return attributes.getJobXmls(); + } + + /** + * Returns the value associated with the provided configuration property name. + * @param property The name of the configuration property for which the value will be returned. + * @return The value associated with the provided configuration property name. + */ + public String getConfigProperty(final String property) { + return attributes.getConfiguration().get(property); + } + + /** + * Returns all configuration properties of this {@link FSAction} as a map. + * @return All configuration properties of this {@link FSAction} as a map. + */ + public Map<String, String> getConfiguration() { + return attributes.getConfiguration(); + } + + /** + * Returns the {@link Delete} objects that specify which directories or files will be deleted when running this action. + * @return The {@link Delete} objects that specify which directories or files will be deleted when running this action. + */ + public List<Delete> getDeletes() { + return attributes.getDeletes(); + } + + /** + * Returns the {@link Mkdir} objects that specify which directories will be created when running this action. + * @return The {@link Mkdir} objects that specify which directories will be created when running this action. + */ + public List<Mkdir> getMkdirs() { + return attributes.getMkdirs(); + } + + /** + * Returns the {@link Move} objects that specify which directories or files will be moved and where when running this action. + * @return The {@link Move} objects that specify which directories or files will be moved and where when running this action. + */ + public List<Move> getMoves() { + return attributes.getMoves(); + } + + /** + * Returns the {@link Chmod} objects that specify the directories or files the permission of which will be changed + * and to what when running this action. + * @return The {@link Chmod} objects that specify the directories or files the permission of which will be changed + * and to what when running this action. + */ + public List<Chmod> getChmods() { + return attributes.getChmods(); + } + + /** + * Returns the {@link Touchz} objects that specify which files will be touched when running this action. + * @return The {@link Touchz} objects that specify which files will be touched when running this action. + */ + public List<Touchz> getTouchzs() { + return attributes.getTouchzs(); + } + + /** + * Returns the {@link Chgrp} objects that specify the directories or files the owner / group of which will be changed + * and to what when running this action. + * @return The {@link Chgrp} objects that specify the directories or files the owner / group of which will be changed + * and to what when running this action. + */ + public List<Chgrp> getChgrps() { + return attributes.getChgrps(); + } + + public ActionAttributes getAttributes() { + return attributes; + } +} http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSActionBuilder.java ---------------------------------------------------------------------- diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSActionBuilder.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSActionBuilder.java new file mode 100644 index 0000000..e70b061 --- /dev/null +++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/action/FSActionBuilder.java @@ -0,0 +1,323 @@ +/** + * 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.oozie.fluentjob.api.action; + +import org.apache.hadoop.classification.InterfaceAudience; +import org.apache.hadoop.classification.InterfaceStability; + +/** + * A builder class for {@link FSAction}. + * <p> + * The properties of the builder can only be set once, an attempt to set them a second time will trigger + * an {@link IllegalStateException}. The properties that are lists are an exception to this rule, of course multiple + * elements can be added / removed. + * <p> + * Builder instances can be used to build several elements, although properties already set cannot be changed after + * a call to {@link FSActionBuilder#build} either. + */ [email protected] [email protected] +public class FSActionBuilder extends NodeBuilderBaseImpl<FSActionBuilder> implements Builder<FSAction> { + private final ActionAttributesBuilder attributesBuilder; + + /** + * Creates and returns an empty builder. + * @return An empty builder. + */ + public static FSActionBuilder create() { + final ActionAttributesBuilder builder = ActionAttributesBuilder.create(); + + return new FSActionBuilder( + null, + builder); + } + + /** + * Create and return a new {@link FSActionBuilder} that is based on an already built + * {@link FSAction} object. The properties of the builder will initially be the same as those of the + * provided {@link FSAction} object, but it is possible to modify them once. + * @param action The {@link FSAction} object on which this {@link FSActionBuilder} will be based. + * @return A new {@link FSActionBuilder} that is based on a previously built {@link FSAction} object. + */ + public static FSActionBuilder createFromExistingAction(final Node action) { + final ActionAttributesBuilder builder = ActionAttributesBuilder.createFromAction(action); + + return new FSActionBuilder( + action, + builder); + } + + FSActionBuilder(final Node action, + final ActionAttributesBuilder attributesBuilder) { + super(action); + + this.attributesBuilder = attributesBuilder; + } + + /** + * Registers a name node. + * @param nameNode The string representing the name node. + * @return this + * @throws IllegalStateException if a name node has already been set on this builder. + */ + public FSActionBuilder withNameNode(final String nameNode) { + attributesBuilder.withNameNode(nameNode); + return this; + } + + /** + * Registers a job XML with this builder. + * @param jobXml The job XML to register. + * @return this + */ + public FSActionBuilder withJobXml(final String jobXml) { + attributesBuilder.withJobXml(jobXml); + return this; + } + + /** + * Removes a job XML if it is registered with this builder, otherwise does nothing. + * @param jobXml The job XML to remove. + * @return this + */ + public FSActionBuilder withoutJobXml(final String jobXml) { + attributesBuilder.withoutJobXml(jobXml); + return this; + } + + /** + * Removes all job XMLs that are registered with this builder. + * @return this + */ + public FSActionBuilder clearJobXmls() { + attributesBuilder.clearJobXmls(); + return this; + } + + /** + * Registers a configuration property (a key-value pair) with this builder. If the provided key has already been + * set on this builder, an exception is thrown. Setting a key to null means deleting it. + * @param key The name of the property to set. + * @param value The value of the property to set. + * @return this + * @throws IllegalStateException if the provided key has already been set on this builder. + */ + public FSActionBuilder withConfigProperty(final String key, final String value) { + attributesBuilder.withConfigProperty(key, value); + return this; + } + + /** + * Registers a {@link Delete} object with this builder. + * @param delete The {@link Delete} object to register. + * @return this + */ + public FSActionBuilder withDelete(final Delete delete) { + attributesBuilder.withDelete(delete); + return this; + } + + /** + * Removes a {@link Delete} object if it is registered with this builder, otherwise does nothing. + * @param delete The {@link Delete} object to remove. + * @return this + */ + public FSActionBuilder withoutDelete(final Delete delete) { + attributesBuilder.withoutDelete(delete); + return this; + } + + /** + * Removes all {@link Delete} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearDeletes() { + attributesBuilder.clearDeletes(); + return this; + } + + /** + * Registers a {@link Mkdir} object with this builder. + * @param mkdir The {@link Mkdir} object to register. + * @return this + */ + public FSActionBuilder withMkdir(final Mkdir mkdir) { + attributesBuilder.withMkdir(mkdir); + return this; + } + + /** + * Removes a {@link Mkdir} object if it is registered with this builder, otherwise does nothing. + * @param mkdir The {@link Mkdir} object to remove. + * @return this + */ + public FSActionBuilder withoutMkdir(final Mkdir mkdir) { + attributesBuilder.withoutMkdir(mkdir); + return this; + } + + /** + * Removes all {@link Mkdir} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearMkdirs() { + attributesBuilder.clearMkdirs(); + return this; + } + + /** + * Registers a {@link Move} object with this builder. + * @param move The {@link Move} object to register. + * @return this + */ + public FSActionBuilder withMove(final Move move) { + attributesBuilder.withMove(move); + return this; + } + + /** + * Removes a {@link Move} object if it is registered with this builder, otherwise does nothing. + * @param move The {@link Move} object to remove. + * @return this + */ + public FSActionBuilder withoutMove(final Move move) { + attributesBuilder.withoutMove(move); + return this; + } + + /** + * Removes all {@link Move} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearMoves() { + attributesBuilder.clearMoves(); + return this; + } + + /** + * Registers a {@link Chmod} object with this builder. + * @param chmod The {@link Chmod} object to register. + * @return this + */ + public FSActionBuilder withChmod(final Chmod chmod) { + attributesBuilder.withChmod(chmod); + return this; + } + + /** + * Removes a {@link Chmod} object if it is registered with this builder, otherwise does nothing. + * @param chmod The {@link Chmod} object to remove. + * @return this + */ + public FSActionBuilder withoutChmod(final Chmod chmod) { + attributesBuilder.withoutChmod(chmod); + return this; + } + + /** + * Removes all {@link Chmod} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearChmods() { + attributesBuilder.clearChmods(); + return this; + } + + /** + * Registers a {@link Touchz} object with this builder. + * @param touchz The {@link Touchz} object to register. + * @return this + */ + public FSActionBuilder withTouchz(final Touchz touchz) { + attributesBuilder.withTouchz(touchz); + return this; + } + + /** + * Removes a {@link Touchz} object if it is registered with this builder, otherwise does nothing. + * @param touchz The {@link Touchz} object to remove. + * @return this + */ + public FSActionBuilder withoutTouchz(final Touchz touchz) { + attributesBuilder.withoutTouchz(touchz); + return this; + } + + /** + * Removes all {@link Touchz} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearTouchzs() { + attributesBuilder.clearTouchzs(); + return this; + } + + /** + * Registers a {@link Chgrp} object with this builder. + * @param chgrp The {@link Chgrp} object to register. + * @return this + */ + public FSActionBuilder withChgrp(final Chgrp chgrp) { + attributesBuilder.withChgrp(chgrp); + return this; + } + + /** + * Removes a {@link Chgrp} object if it is registered with this builder, otherwise does nothing. + * @param chgrp The {@link Chgrp} object to remove. + * @return this + */ + public FSActionBuilder withoutChgrp(final Chgrp chgrp) { + attributesBuilder.withoutChgrp(chgrp); + return this; + } + + /** + * Removes all {@link Chgrp} objects that are registered with this builder. + * @return this + */ + public FSActionBuilder clearChgrps() { + attributesBuilder.clearChgrps(); + return this; + } + + /** + * Creates a new {@link FSAction} object with the properties stores in this builder. + * The new {@link FSAction} object is independent of this builder and the builder can be used to build + * new instances. + * @return A new {@link FSAction} object with the properties stored in this builder. + */ + @Override + public FSAction build() { + final Node.ConstructionData constructionData = getConstructionData(); + + final FSAction instance = new FSAction( + constructionData, + attributesBuilder.build()); + + addAsChildToAllParents(instance); + + return instance; + } + + @Override + protected FSActionBuilder getRuntimeSelfReference() { + return this; + } +}
