You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@oozie.apache.org by an...@apache.org on 2018/06/19 09:46:59 UTC

[09/16] oozie git commit: OOZIE-2339 [fluent-job] Minimum Viable Fluent Job API (daniel.becker, andras.piros via rkanter, gezapeti, pbacsko)

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2LauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2LauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2LauncherConverter.java
new file mode 100644
index 0000000..34b11f8
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2LauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.hive2.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.action.hive2.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class Hive2LauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public Hive2LauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2PrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2PrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2PrepareConverter.java
new file mode 100644
index 0000000..105f996
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/Hive2PrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.hive2.DELETE;
+import org.apache.oozie.fluentjob.api.generated.action.hive2.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.action.hive2.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.action.hive2.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class Hive2PrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public Hive2PrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveConfigurationConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveConfigurationConverter.java
new file mode 100644
index 0000000..5f9a2b1
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveConfigurationConverter.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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.hive.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.action.hive.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class HiveConfigurationConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public HiveConfigurationConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapEntries(source, destination);
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureDestination(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+
+        return destination;
+    }
+
+    private void mapEntries(final Map source, final CONFIGURATION destination) {
+        if (source != null) {
+            final List<CONFIGURATION.Property> targetProperties = new ArrayList<>();
+
+            for (final Object objectKey : source.keySet()) {
+                final String name = objectKey.toString();
+                final String value = source.get(name).toString();
+                final CONFIGURATION.Property targetProperty = OBJECT_FACTORY.createCONFIGURATIONProperty();
+                targetProperty.setName(name);
+                targetProperty.setValue(value);
+                targetProperties.add(targetProperty);
+            }
+
+            destination.setProperty(targetProperties);
+        }
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveLauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveLauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveLauncherConverter.java
new file mode 100644
index 0000000..ad231f5
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HiveLauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.hive.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.action.hive.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class HiveLauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public HiveLauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HivePrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HivePrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HivePrepareConverter.java
new file mode 100644
index 0000000..9b668d4
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/HivePrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.hive.DELETE;
+import org.apache.oozie.fluentjob.api.generated.action.hive.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.action.hive.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.action.hive.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class HivePrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public HivePrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowConfigurationConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowConfigurationConverter.java
new file mode 100644
index 0000000..b1e17c9
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowConfigurationConverter.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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class InlineWorkflowConfigurationConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public InlineWorkflowConfigurationConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapEntries(source, destination);
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureDestination(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+
+        return destination;
+    }
+
+    private void mapEntries(final Map source, final CONFIGURATION destination) {
+        if (source != null) {
+            final List<CONFIGURATION.Property> targetProperties = new ArrayList<>();
+
+            for (final Object objectKey : source.keySet()) {
+                final String name = objectKey.toString();
+                final String value = source.get(name).toString();
+                final CONFIGURATION.Property targetProperty = OBJECT_FACTORY.createCONFIGURATIONProperty();
+                targetProperty.setName(name);
+                targetProperty.setValue(value);
+                targetProperties.add(targetProperty);
+            }
+
+            destination.setProperty(targetProperties);
+        }
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowLauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowLauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowLauncherConverter.java
new file mode 100644
index 0000000..8d32160
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowLauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class InlineWorkflowLauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public InlineWorkflowLauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowPrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowPrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowPrepareConverter.java
new file mode 100644
index 0000000..5f2bf7b
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/InlineWorkflowPrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.DELETE;
+import org.apache.oozie.fluentjob.api.generated.workflow.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.workflow.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class InlineWorkflowPrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public InlineWorkflowPrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/JoinConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/JoinConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/JoinConverter.java
new file mode 100644
index 0000000..e9495b6
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/JoinConverter.java
@@ -0,0 +1,63 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.JOIN;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.dag.Join;
+import org.apache.oozie.fluentjob.api.dag.NodeBase;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Join} to JAXB {@link JOIN}.
+ */
+public class JoinConverter extends DozerConverter<Join, JOIN> {
+
+    private static final ObjectFactory WORKFLOW_OBJECT_FACTORY = new ObjectFactory();
+
+    public JoinConverter() {
+        super(Join.class, JOIN.class);
+    }
+
+    @Override
+    public JOIN convertTo(final Join source, JOIN destination) {
+        destination = ensureDestination(destination);
+
+        destination.setName(source.getName());
+
+        final NodeBase child  = source.getChild();
+        final NodeBase realChild = RealChildLocator.findRealChild(child);
+
+        destination.setTo(realChild.getName());
+
+        return destination;
+    }
+
+    private JOIN ensureDestination(JOIN destination) {
+        if (destination == null) {
+            destination = WORKFLOW_OBJECT_FACTORY.createJOIN();
+        }
+        return destination;
+    }
+
+    @Override
+    public Join convertFrom(JOIN source, Join destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/MapToConfigurationPropertyConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/MapToConfigurationPropertyConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/MapToConfigurationPropertyConverter.java
new file mode 100644
index 0000000..c86e066
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/MapToConfigurationPropertyConverter.java
@@ -0,0 +1,75 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class MapToConfigurationPropertyConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public MapToConfigurationPropertyConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        destination = ensureConfiguration(destination);
+
+        for (final Object entryObject : source.entrySet()) {
+            final Map.Entry<String, String> entry = (Map.Entry<String, String>) entryObject;
+            final String key = entry.getKey();
+            final String value = entry.getValue();
+
+            final CONFIGURATION.Property property = createProperty(key, value);
+
+            destination.getProperty().add(property);
+        }
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureConfiguration(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+        return destination;
+    }
+
+    private CONFIGURATION.Property createProperty(final String key, final String value) {
+        final CONFIGURATION.Property property = OBJECT_FACTORY.createCONFIGURATIONProperty();
+
+        property.setName(key);
+        property.setValue(value);
+
+        return property;
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ParametersConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ParametersConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ParametersConverter.java
new file mode 100644
index 0000000..f3677e5
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ParametersConverter.java
@@ -0,0 +1,73 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.workflow.PARAMETERS;
+import org.apache.oozie.fluentjob.api.workflow.Parameter;
+import org.apache.oozie.fluentjob.api.workflow.Parameters;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Parameters} to JAXB {@link PARAMETERS}.
+ */
+public class ParametersConverter extends DozerConverter<Parameters, PARAMETERS> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public ParametersConverter() {
+        super(Parameters.class, PARAMETERS.class);
+    }
+
+    @Override
+    public PARAMETERS convertTo(final Parameters source, PARAMETERS destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapParameters(source, destination);
+
+        return destination;
+    }
+
+    private PARAMETERS ensureDestination(final PARAMETERS destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPARAMETERS();
+        }
+
+        return destination;
+    }
+
+    private void mapParameters(final Parameters source, final PARAMETERS destination) {
+        for (final Parameter parameter : source.getParameters()) {
+            final PARAMETERS.Property property = OBJECT_FACTORY.createPARAMETERSProperty();
+            property.setName(parameter.getName());
+            property.setValue(parameter.getValue());
+            property.setDescription(parameter.getDescription());
+
+            destination.getProperty().add(property);
+        }
+    }
+
+    @Override
+    public Parameters convertFrom(final PARAMETERS source, final Parameters destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/RealChildLocator.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/RealChildLocator.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/RealChildLocator.java
new file mode 100644
index 0000000..a1073a0
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/RealChildLocator.java
@@ -0,0 +1,35 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.dag.DecisionJoin;
+import org.apache.oozie.fluentjob.api.dag.NodeBase;
+
+/**
+ * Finds the real child among list of {@link NodeBase} children, that is, one that isn't a {@link DecisionJoin}.
+ */
+class RealChildLocator {
+    static NodeBase findRealChild(final NodeBase originalChild) {
+        if (originalChild instanceof DecisionJoin) {
+            return findRealChild(((DecisionJoin) originalChild).getChild());
+        }
+
+        return originalChild;
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellConfigurationConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellConfigurationConverter.java
new file mode 100644
index 0000000..ab73dfd
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellConfigurationConverter.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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.shell.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.action.shell.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class ShellConfigurationConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public ShellConfigurationConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapEntries(source, destination);
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureDestination(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+
+        return destination;
+    }
+
+    private void mapEntries(final Map source, final CONFIGURATION destination) {
+        if (source != null) {
+            final List<CONFIGURATION.Property> targetProperties = new ArrayList<>();
+
+            for (final Object objectKey : source.keySet()) {
+                final String name = objectKey.toString();
+                final String value = source.get(name).toString();
+                final CONFIGURATION.Property targetProperty = OBJECT_FACTORY.createCONFIGURATIONProperty();
+                targetProperty.setName(name);
+                targetProperty.setValue(value);
+                targetProperties.add(targetProperty);
+            }
+
+            destination.setProperty(targetProperties);
+        }
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellLauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellLauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellLauncherConverter.java
new file mode 100644
index 0000000..d933499
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellLauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.shell.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.action.shell.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class ShellLauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public ShellLauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellPrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellPrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellPrepareConverter.java
new file mode 100644
index 0000000..30fcf7c
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/ShellPrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.shell.DELETE;
+import org.apache.oozie.fluentjob.api.generated.action.shell.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.action.shell.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.action.shell.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class ShellPrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public ShellPrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkConfigurationConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkConfigurationConverter.java
new file mode 100644
index 0000000..8827769
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkConfigurationConverter.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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.spark.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.action.spark.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class SparkConfigurationConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SparkConfigurationConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapEntries(source, destination);
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureDestination(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+
+        return destination;
+    }
+
+    private void mapEntries(final Map source, final CONFIGURATION destination) {
+        if (source != null) {
+            final List<CONFIGURATION.Property> targetProperties = new ArrayList<>();
+
+            for (final Object objectKey : source.keySet()) {
+                final String name = objectKey.toString();
+                final String value = source.get(name).toString();
+                final CONFIGURATION.Property targetProperty = OBJECT_FACTORY.createCONFIGURATIONProperty();
+                targetProperty.setName(name);
+                targetProperty.setValue(value);
+                targetProperties.add(targetProperty);
+            }
+
+            destination.setProperty(targetProperties);
+        }
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkLauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkLauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkLauncherConverter.java
new file mode 100644
index 0000000..be7436a
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkLauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.spark.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.action.spark.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class SparkLauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SparkLauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkPrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkPrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkPrepareConverter.java
new file mode 100644
index 0000000..812e53d
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SparkPrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.spark.DELETE;
+import org.apache.oozie.fluentjob.api.generated.action.spark.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.action.spark.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.action.spark.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class SparkPrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SparkPrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopConfigurationConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopConfigurationConverter.java
new file mode 100644
index 0000000..1d4f615
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopConfigurationConverter.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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.CONFIGURATION;
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.ObjectFactory;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A {@link DozerConverter} converting from {@link Map} to JAXB {@link CONFIGURATION}.
+ */
+public class SqoopConfigurationConverter extends DozerConverter<Map, CONFIGURATION> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SqoopConfigurationConverter() {
+        super(Map.class, CONFIGURATION.class);
+    }
+
+    @Override
+    public CONFIGURATION convertTo(final Map source, CONFIGURATION destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapEntries(source, destination);
+
+        return destination;
+    }
+
+    private CONFIGURATION ensureDestination(CONFIGURATION destination) {
+        if (destination == null) {
+            destination = OBJECT_FACTORY.createCONFIGURATION();
+        }
+
+        return destination;
+    }
+
+    private void mapEntries(final Map source, final CONFIGURATION destination) {
+        if (source != null) {
+            final List<CONFIGURATION.Property> targetProperties = new ArrayList<>();
+
+            for (final Object objectKey : source.keySet()) {
+                final String name = objectKey.toString();
+                final String value = source.get(name).toString();
+                final CONFIGURATION.Property targetProperty = OBJECT_FACTORY.createCONFIGURATIONProperty();
+                targetProperty.setName(name);
+                targetProperty.setValue(value);
+                targetProperties.add(targetProperty);
+            }
+
+            destination.setProperty(targetProperties);
+        }
+    }
+
+    @Override
+    public Map convertFrom(final CONFIGURATION source, final Map destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopLauncherConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopLauncherConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopLauncherConverter.java
new file mode 100644
index 0000000..556cb7b
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopLauncherConverter.java
@@ -0,0 +1,74 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.LAUNCHER;
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.ObjectFactory;
+import org.apache.oozie.fluentjob.api.action.Launcher;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Launcher} to JAXB {@link LAUNCHER}.
+ */
+public class SqoopLauncherConverter extends DozerConverter<Launcher, LAUNCHER> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SqoopLauncherConverter() {
+        super(Launcher.class, LAUNCHER.class);
+    }
+
+    @Override
+    public LAUNCHER convertTo(final Launcher source, LAUNCHER destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapAttributes(source, destination);
+
+        return destination;
+    }
+
+    private LAUNCHER ensureDestination(final LAUNCHER destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createLAUNCHER();
+        }
+
+        return destination;
+    }
+
+    private void mapAttributes(final Launcher source, final LAUNCHER destination) {
+        if (source == null) {
+            return;
+        }
+
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERMemoryMb(source.getMemoryMb()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERVcores(source.getVCores()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERQueue(source.getQueue()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERSharelib(source.getSharelib()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERViewAcl(source.getViewAcl()));
+        destination.getMemoryMbOrVcoresOrJavaOpts().add(OBJECT_FACTORY.createLAUNCHERModifyAcl(source.getModifyAcl()));
+    }
+
+    @Override
+    public Launcher convertFrom(final LAUNCHER source, final Launcher destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopPrepareConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopPrepareConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopPrepareConverter.java
new file mode 100644
index 0000000..5062c08
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/SqoopPrepareConverter.java
@@ -0,0 +1,97 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.DELETE;
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.MKDIR;
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.action.sqoop.PREPARE;
+import org.apache.oozie.fluentjob.api.action.Delete;
+import org.apache.oozie.fluentjob.api.action.Mkdir;
+import org.apache.oozie.fluentjob.api.action.Prepare;
+import org.dozer.DozerConverter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link DozerConverter} converting from {@link Prepare} to JAXB {@link PREPARE}.
+ */
+public class SqoopPrepareConverter extends DozerConverter<Prepare, PREPARE> {
+    private static final ObjectFactory OBJECT_FACTORY = new ObjectFactory();
+
+    public SqoopPrepareConverter() {
+        super(Prepare.class, PREPARE.class);
+    }
+
+    @Override
+    public PREPARE convertTo(final Prepare source, PREPARE destination) {
+        if (source == null) {
+            return null;
+        }
+
+        destination = ensureDestination(destination);
+
+        mapDeletes(source, destination);
+
+        mapMkdirs(source, destination);
+
+        return destination;
+    }
+
+    private PREPARE ensureDestination(final PREPARE destination) {
+        if (destination == null) {
+            return OBJECT_FACTORY.createPREPARE();
+        }
+        return destination;
+    }
+
+    private void mapDeletes(final Prepare source, final PREPARE destination) {
+        if (source.getDeletes() != null) {
+            final List<DELETE> targetDeletes = new ArrayList<>();
+
+            for (final Delete sourceDelete : source.getDeletes()) {
+                final DELETE targetDelete = OBJECT_FACTORY.createDELETE();
+                targetDelete.setPath(sourceDelete.getPath());
+                targetDeletes.add(targetDelete);
+            }
+
+            destination.setDelete(targetDeletes);
+        }
+    }
+
+    private void mapMkdirs(final Prepare source, final PREPARE destination) {
+        if (source.getMkdirs() != null) {
+            final List<MKDIR> targetMkdirs = new ArrayList<>();
+
+            for (final Mkdir sourceMkDir: source.getMkdirs()) {
+                final MKDIR targetMkDir = OBJECT_FACTORY.createMKDIR();
+                targetMkDir.setPath(sourceMkDir.getPath());
+                targetMkdirs.add(targetMkDir);
+            }
+
+            destination.setMkdir(targetMkdirs);
+        }
+    }
+
+    @Override
+    public Prepare convertFrom(final PREPARE source, final Prepare destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/StartConverter.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/StartConverter.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/StartConverter.java
new file mode 100644
index 0000000..fe4d55e
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/mapping/StartConverter.java
@@ -0,0 +1,50 @@
+/**
+ * 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.mapping;
+
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.workflow.START;
+import org.apache.oozie.fluentjob.api.dag.NodeBase;
+import org.apache.oozie.fluentjob.api.dag.Start;
+import org.dozer.DozerConverter;
+
+/**
+ * A {@link DozerConverter} converting from {@link Start} to JAXB {@link START}.
+ */
+public class StartConverter extends DozerConverter<Start, START> {
+    public StartConverter() {
+        super(Start.class, START.class);
+    }
+
+    @Override
+    public START convertTo(Start source, START destination) {
+        if (destination == null) {
+            destination = new ObjectFactory().createSTART();
+        }
+
+        final NodeBase realChild = RealChildLocator.findRealChild(source.getChild());
+        destination.setTo(realChild.getName());
+        return destination;
+    }
+
+    @Override
+    public Start convertFrom(START source, Start destination) {
+        throw new UnsupportedOperationException("This mapping is not bidirectional.");
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/serialization/WorkflowMarshaller.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/serialization/WorkflowMarshaller.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/serialization/WorkflowMarshaller.java
new file mode 100644
index 0000000..ec56554
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/serialization/WorkflowMarshaller.java
@@ -0,0 +1,105 @@
+/**
+ * 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.serialization;
+
+import org.apache.oozie.fluentjob.api.action.Node;
+import org.apache.oozie.fluentjob.api.generated.workflow.ObjectFactory;
+import org.apache.oozie.fluentjob.api.generated.workflow.WORKFLOWAPP;
+import org.apache.oozie.fluentjob.api.mapping.DozerBeanMapperSingleton;
+import org.apache.oozie.fluentjob.api.dag.Graph;
+import org.apache.oozie.fluentjob.api.workflow.Workflow;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBElement;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.Locale;
+
+/**
+ * Similar to JAXB {@link Marshaller} / {@link javax.xml.bind.Unmarshaller}, this class translates between Jobs API {@link Workflow}
+ * and JAXB {@link WORKFLOWAPP} by using the appropriate Dozer converters.
+ */
+public class WorkflowMarshaller {
+
+    public static String marshal(final Workflow workflow) throws JAXBException, UnsupportedEncodingException {
+        final Graph graph = new Graph(workflow);
+        final WORKFLOWAPP workflowapp = DozerBeanMapperSingleton.instance().map(graph, WORKFLOWAPP.class);
+        final String filteredPackages = filterPackages(workflow);
+
+        return marshal(workflowapp, filteredPackages);
+    }
+
+    private static String marshal(final WORKFLOWAPP workflowapp, final String filteredPackages)
+            throws JAXBException, UnsupportedEncodingException {
+        final JAXBElement<?> wfElement = new ObjectFactory().createWorkflowApp(workflowapp);
+
+        final JAXBContext jc = JAXBContext.newInstance(filteredPackages);
+        final Marshaller m =  jc.createMarshaller();
+        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
+        final ByteArrayOutputStream out = new ByteArrayOutputStream();
+        m.marshal(wfElement, out);
+
+        return out.toString(Charset.defaultCharset().name());
+    }
+
+    private static String filterPackages(final Workflow workflow) {
+        final StringBuilder filteredPackages = new StringBuilder();
+
+        filteredPackages.append("org.apache.oozie.fluentjob.api.generated.workflow");
+        appendIfPresent(workflow, filteredPackages, "distcp");
+        appendIfPresent(workflow, filteredPackages, "email");
+        appendIfPresent(workflow, filteredPackages, "hive2");
+        appendIfPresent(workflow, filteredPackages, "hive");
+        appendIfPresent(workflow, filteredPackages, "sla");
+        appendIfPresent(workflow, filteredPackages, "shell");
+        appendIfPresent(workflow, filteredPackages, "spark");
+        appendIfPresent(workflow, filteredPackages, "sqoop");
+        appendIfPresent(workflow, filteredPackages, "ssh");
+
+        return filteredPackages.toString();
+    }
+
+    private static void appendIfPresent(final Workflow workflow, final StringBuilder filteredPackages, final String nodeType) {
+        if (containsNodeType(workflow, nodeType)) {
+            filteredPackages.append(":org.apache.oozie.fluentjob.api.generated.action.").append(nodeType);
+        }
+    }
+
+    private static boolean containsNodeType(final Workflow workflow, final String nodeType) {
+        final String actionType = nodeType + "action";
+        for (final Node node : workflow.getAllNodes()) {
+            final String nodeSimpleName = node.getClass().getSimpleName();
+            if (nodeSimpleName.toLowerCase(Locale.getDefault()).startsWith(actionType.toLowerCase(Locale.getDefault()))) {
+                return true;
+            }
+            if (node.getErrorHandler() != null) {
+                final String errorHandlerSimpleName = node.getErrorHandler().getHandlerNode().getClass().getSimpleName();
+                if (errorHandlerSimpleName.toLowerCase(Locale.getDefault())
+                        .startsWith(actionType.toLowerCase(Locale.getDefault()))) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/oozie/blob/8a0a6487/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/workflow/ConfigurationEntry.java
----------------------------------------------------------------------
diff --git a/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/workflow/ConfigurationEntry.java b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/workflow/ConfigurationEntry.java
new file mode 100644
index 0000000..72b2d5a
--- /dev/null
+++ b/fluent-job/fluent-job-api/src/main/java/org/apache/oozie/fluentjob/api/workflow/ConfigurationEntry.java
@@ -0,0 +1,61 @@
+/**
+ * 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.workflow;
+
+import org.apache.hadoop.classification.InterfaceAudience;
+import org.apache.hadoop.classification.InterfaceStability;
+
+/**
+ * Represents the {@code <configuration>} element and its siblings inside workflow XML / XSD.
+ * <p>
+ * By assigning non-{@code null} field values, the resulting parent {@code <workflow>} will have its
+ * optional {@code <configuration>} element and its siblings filled.
+ * <p>
+ * This class is used only as part of a {@link org.apache.oozie.fluentjob.api.workflow.Workflow}, isn't
+ * to be used alone with Jobs API.
+ */
+@InterfaceAudience.Private
+@InterfaceStability.Unstable
+public class ConfigurationEntry {
+    private final String name;
+    private final String value;
+    private final String description;
+
+    public ConfigurationEntry(final String name, final String description) {
+        this(name, description, null);
+    }
+
+    public ConfigurationEntry(final String name, final String value, final String description) {
+        this.name = name;
+        this.value = value;
+        this.description = description;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+}