diff --git a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/pom.xml b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/pom.xml
index 9dd6abdc34..52f4fa6e8a 100644
--- a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/pom.xml
+++ b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/pom.xml
@@ -63,6 +63,11 @@
com.squareup.okhttp3
okhttp
+
+ org.apache.nifi
+ nifi-conflict-resolution
+ 1.20.0-SNAPSHOT
+
org.apache.nifi
nifi-mock
diff --git a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/main/java/org/apache/nifi/processors/dropbox/PutDropbox.java b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/main/java/org/apache/nifi/processors/dropbox/PutDropbox.java
index 54197ee102..1bd0398bcc 100644
--- a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/main/java/org/apache/nifi/processors/dropbox/PutDropbox.java
+++ b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/main/java/org/apache/nifi/processors/dropbox/PutDropbox.java
@@ -18,6 +18,9 @@
package org.apache.nifi.processors.dropbox;
import static java.lang.String.format;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.FAIL;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.IGNORE;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.REPLACE;
import static org.apache.nifi.processors.dropbox.DropboxAttributes.ERROR_MESSAGE;
import static org.apache.nifi.processors.dropbox.DropboxAttributes.ERROR_MESSAGE_DESC;
import static org.apache.nifi.processors.dropbox.DropboxAttributes.FILENAME;
@@ -58,6 +61,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
+import org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy;
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
import org.apache.nifi.annotation.behavior.ReadsAttribute;
@@ -100,10 +104,6 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
public static final int SINGLE_UPLOAD_LIMIT_IN_BYTES = 150 * 1024 * 1024;
- public static final String IGNORE_RESOLUTION = "ignore";
- public static final String REPLACE_RESOLUTION = "replace";
- public static final String FAIL_RESOLUTION = "fail";
-
public static final Relationship REL_SUCCESS = new Relationship.Builder()
.name("success")
.description("Files that have been successfully written to Dropbox are transferred to this relationship.")
@@ -140,8 +140,8 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
.displayName("Conflict Resolution Strategy")
.description("Indicates what should happen when a file with the same name already exists in the specified Dropbox folder.")
.required(true)
- .defaultValue(FAIL_RESOLUTION)
- .allowableValues(FAIL_RESOLUTION, IGNORE_RESOLUTION, REPLACE_RESOLUTION)
+ .defaultValue(FAIL.getValue())
+ .allowableValues(ConflictResolutionStrategy.class)
.build();
public static final PropertyDescriptor CHUNKED_UPLOAD_SIZE = new PropertyDescriptor.Builder()
@@ -219,8 +219,7 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
.asDataSize(DataUnit.B)
.longValue();
- final String conflictResolution = context.getProperty(CONFLICT_RESOLUTION).getValue();
-
+ final ConflictResolutionStrategy conflictResolution = ConflictResolutionStrategy.forValue(context.getProperty(CONFLICT_RESOLUTION).getValue());
final long size = flowFile.getSize();
final String uploadPath = convertFolderName(folder) + "/" + filename;
final long startNanos = System.nanoTime();
@@ -261,7 +260,7 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
}
}
- private void handleUploadError(final String conflictResolution, final String uploadPath, final UploadErrorException e) {
+ private void handleUploadError(final ConflictResolutionStrategy conflictResolution, final String uploadPath, final UploadErrorException e) {
if (e.errorValue.isPath() && e.errorValue.getPathValue().getReason().isConflict()) {
handleConflict(conflictResolution, uploadPath, e);
} else {
@@ -269,7 +268,7 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
}
}
- private void handleUploadError(final String conflictResolution, final String uploadPath, final UploadSessionFinishErrorException e) {
+ private void handleUploadError(final ConflictResolutionStrategy conflictResolution, final String uploadPath, final UploadSessionFinishErrorException e) {
if (e.errorValue.isPath() && e.errorValue.getPathValue().isConflict()) {
handleConflict(conflictResolution, uploadPath, e);
} else {
@@ -277,16 +276,17 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
}
}
- private void handleConflict(final String conflictResolution, final String uploadPath, final DbxApiException e) {
- if (IGNORE_RESOLUTION.equals(conflictResolution)) {
+ private void handleConflict(final ConflictResolutionStrategy conflictResolution, final String uploadPath, final DbxApiException e) {
+ if (conflictResolution == IGNORE) {
getLogger().info("File with the same name [{}] already exists. Remote file is not modified due to {} being set to '{}'.",
uploadPath, CONFLICT_RESOLUTION.getDisplayName(), conflictResolution);
- } else if (conflictResolution.equals(FAIL_RESOLUTION)) {
+ } else if (conflictResolution == FAIL) {
throw new ProcessException(format("File with the same name [%s] already exists.", uploadPath), e);
}
}
- private FileMetadata uploadLargeFileInChunks(String path, InputStream rawIn, long size, long uploadChunkSize, String conflictResolution) throws DbxException, IOException {
+ private FileMetadata uploadLargeFileInChunks(String path, InputStream rawIn, long size, long uploadChunkSize,
+ ConflictResolutionStrategy conflictResolution) throws DbxException, IOException {
final String sessionId;
try (UploadSessionStartUploader uploader = createUploadSessionStartUploader()) {
sessionId = uploader.uploadAndFinish(rawIn, uploadChunkSize).getSessionId();
@@ -317,15 +317,15 @@ public class PutDropbox extends AbstractProcessor implements DropboxTrait {
}
}
- private WriteMode getWriteMode(String conflictResolution) {
- if (REPLACE_RESOLUTION.equals(conflictResolution)) {
+ private WriteMode getWriteMode(ConflictResolutionStrategy conflictResolution) {
+ if (conflictResolution == REPLACE) {
return WriteMode.OVERWRITE;
} else {
return WriteMode.ADD;
}
}
- private UploadUploader createUploadUploader(String path, String conflictResolution) throws DbxException {
+ private UploadUploader createUploadUploader(String path, ConflictResolutionStrategy conflictResolution) throws DbxException {
return dropboxApiClient
.files()
.uploadBuilder(path)
diff --git a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxIT.java b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxIT.java
index 7900a7fae3..e329fd408c 100644
--- a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxIT.java
+++ b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxIT.java
@@ -17,6 +17,10 @@
package org.apache.nifi.processors.dropbox;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.FAIL;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.IGNORE;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.REPLACE;
+
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -80,7 +84,7 @@ public class PutDropboxIT extends AbstractDropboxIT {
@Test
void testUploadExistingFileFailStrategy() {
testRunner.setProperty(PutDropbox.FOLDER, MAIN_FOLDER);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.FAIL_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, FAIL.getValue());
testRunner.enqueue(CONTENT);
testRunner.run();
@@ -98,7 +102,7 @@ public class PutDropboxIT extends AbstractDropboxIT {
@Test
void testUploadExistingFileWithSameContentFailStrategy() {
testRunner.setProperty(PutDropbox.FOLDER, MAIN_FOLDER);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.FAIL_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, FAIL.getValue());
testRunner.enqueue(CONTENT);
testRunner.run();
@@ -117,7 +121,7 @@ public class PutDropboxIT extends AbstractDropboxIT {
@Test
void testUploadExistingFileReplaceStrategy() {
testRunner.setProperty(PutDropbox.FOLDER, MAIN_FOLDER);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.REPLACE_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, REPLACE.getValue());
testRunner.enqueue(CONTENT);
testRunner.run();
@@ -135,7 +139,7 @@ public class PutDropboxIT extends AbstractDropboxIT {
@Test
void testUploadExistingFileIgnoreStrategy() {
testRunner.setProperty(PutDropbox.FOLDER, MAIN_FOLDER);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.IGNORE_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, IGNORE.getValue());
testRunner.enqueue(CONTENT);
testRunner.run();
diff --git a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxTest.java b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxTest.java
index 6f0405b456..f981664233 100644
--- a/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxTest.java
+++ b/nifi-nar-bundles/nifi-dropbox-bundle/nifi-dropbox-processors/src/test/java/org/apache/nifi/processors/dropbox/PutDropboxTest.java
@@ -20,6 +20,8 @@ package org.apache.nifi.processors.dropbox;
import static com.dropbox.core.v2.files.UploadError.path;
import static com.dropbox.core.v2.files.WriteConflictError.FILE;
import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.IGNORE;
+import static org.apache.nifi.processors.conflict.resolution.ConflictResolutionStrategy.REPLACE;
import static org.apache.nifi.processors.dropbox.DropboxAttributes.ERROR_MESSAGE;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.ArgumentMatchers.any;
@@ -166,7 +168,7 @@ public class PutDropboxTest extends AbstractDropboxTest {
@Test
void testFileUploadWithReplaceConflictResolutionStrategy() throws Exception {
testRunner.setProperty(PutDropbox.FILE_NAME, FILENAME_1);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.REPLACE_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, REPLACE.getValue());
mockFileUpload(TEST_FOLDER, FILENAME_1, WriteMode.OVERWRITE);
@@ -193,7 +195,7 @@ public class PutDropboxTest extends AbstractDropboxTest {
@Test
void testFileUploadOtherExceptionIsNotIgnored() throws Exception {
testRunner.setProperty(PutDropbox.FILE_NAME, FILENAME_1);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.IGNORE_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, IGNORE.getValue());
mockFileUploadError(getException(WriteError.INSUFFICIENT_SPACE));
@@ -205,7 +207,7 @@ public class PutDropboxTest extends AbstractDropboxTest {
@Test
void testFileUploadConflictIgnoredWithIgnoreResolutionStrategy() throws Exception {
testRunner.setProperty(PutDropbox.FILE_NAME, FILENAME_1);
- testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, PutDropbox.IGNORE_RESOLUTION);
+ testRunner.setProperty(PutDropbox.CONFLICT_RESOLUTION, IGNORE.getValue());
mockFileUploadError(getException(WriteError.conflict(FILE)));
diff --git a/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/pom.xml b/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/pom.xml
new file mode 100644
index 0000000000..8531d16ef3
--- /dev/null
+++ b/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ 4.0.0
+
+ org.apache.nifi
+ nifi-extension-utils
+ 1.20.0-SNAPSHOT
+
+
+ nifi-conflict-resolution
+
+
+
+ org.apache.nifi
+ nifi-api
+
+
+
\ No newline at end of file
diff --git a/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/src/main/java/org/apache/nifi/processors/conflict/resolution/ConflictResolutionStrategy.java b/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/src/main/java/org/apache/nifi/processors/conflict/resolution/ConflictResolutionStrategy.java
new file mode 100644
index 0000000000..ae9a992e5b
--- /dev/null
+++ b/nifi-nar-bundles/nifi-extension-utils/nifi-conflict-resolution/src/main/java/org/apache/nifi/processors/conflict/resolution/ConflictResolutionStrategy.java
@@ -0,0 +1,62 @@
+/*
+ * 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.nifi.processors.conflict.resolution;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.nifi.components.DescribedValue;
+
+public enum ConflictResolutionStrategy implements DescribedValue {
+ FAIL( "fail", "Handle file conflict as failure."),
+ IGNORE("ignore", "Ignore conflict, do not change the original file."),
+ REPLACE( "replace", "Replace existing file in case of conflict.");
+
+ private static final Map ENUM_MAP = new HashMap<>();
+
+ static {
+ for (ConflictResolutionStrategy strategy : ConflictResolutionStrategy.values()) {
+ ENUM_MAP.put(strategy.getValue(), strategy);
+ }
+ }
+
+ private final String value;
+ private final String description;
+
+ ConflictResolutionStrategy(final String value, String description) {
+ this.value = value;
+ this.description = description;
+ }
+
+ public static ConflictResolutionStrategy forValue(String value) {
+ return ENUM_MAP.get(value);
+ }
+
+ @Override
+ public String getValue() {
+ return this.value;
+ }
+
+ @Override
+ public String getDisplayName() {
+ return this.value;
+ }
+
+ @Override
+ public String getDescription() {
+ return this.description;
+ }
+}
diff --git a/nifi-nar-bundles/nifi-extension-utils/pom.xml b/nifi-nar-bundles/nifi-extension-utils/pom.xml
index 723fd01b5f..65b396eed9 100644
--- a/nifi-nar-bundles/nifi-extension-utils/pom.xml
+++ b/nifi-nar-bundles/nifi-extension-utils/pom.xml
@@ -43,5 +43,6 @@
nifi-reporting-utils
nifi-service-utils
nifi-syslog-utils
+ nifi-conflict-resolution