OOZIE-3542 amend Handle better old Hdfs implementations in ECPolicyDisabler (zsombor via kmarton)
diff --git a/release-log.txt b/release-log.txt
index 96f91d9..0f406ae 100644
--- a/release-log.txt
+++ b/release-log.txt
@@ -1,5 +1,6 @@
-- Oozie 5.2.0 release (trunk - unreleased)
+OOZIE-3542 amend Handle better old Hdfs implementations in ECPolicyDisabler (zsombor via kmarton)
OOZIE-3529 Oozie not supported for s3 as filesystem (dionusos via asalamon74)
OOZIE-3465 Migrate from commons-codec (matijhs via asalamon74)
OOZIE-3533 Flaky test TestXLogService.testLog4jReload (asalamon74 via kmarton)
diff --git a/tools/src/main/java/org/apache/oozie/tools/ECPolicyDisabler.java b/tools/src/main/java/org/apache/oozie/tools/ECPolicyDisabler.java
index 6d51342..e24ac7a 100644
--- a/tools/src/main/java/org/apache/oozie/tools/ECPolicyDisabler.java
+++ b/tools/src/main/java/org/apache/oozie/tools/ECPolicyDisabler.java
@@ -27,6 +27,8 @@
import org.apache.hadoop.ipc.RemoteException;
import org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto.RpcErrorCodeProto;
+import org.apache.commons.lang3.tuple.Pair;
+
/**
* Utility class which can disable Erasure Coding for a given path.
*
@@ -68,22 +70,23 @@
DistributedFileSystem dfs = (DistributedFileSystem) fs;
final Object replicationPolicy = getReplicationPolicy();
Method getErasureCodingPolicyMethod = getMethod(dfs, GETERASURECODINGPOLICY_METHOD);
- final Object currentECPolicy = invokeMethod(getErasureCodingPolicyMethod, dfs, path);
+ final Pair<Object,Result> currentECPolicy = safeInvokeMethod(getErasureCodingPolicyMethod, dfs, path);
+ if (currentECPolicy.getRight() != null) {
+ return currentECPolicy.getRight();
+ }
- if (currentECPolicy != replicationPolicy) {
+ if (currentECPolicy.getLeft() != replicationPolicy) {
Method setECPolicyMethod = getMethod(dfs, SETERASURECODINGPOLICY_METHOD);
Method policyGetNameMethod = getMethod(replicationPolicy, GETNAME_METHOD);
- String name = (String) invokeMethod(policyGetNameMethod, replicationPolicy);
+ Pair<String,Result> pairName = safeInvokeMethod(policyGetNameMethod, replicationPolicy);
+ if (pairName.getRight() != null) {
+ return pairName.getRight();
+ }
- try {
- invokeMethod(setECPolicyMethod, dfs, path, name);
- } catch (RuntimeException e) {
- RpcErrorCodeProto errorCode = unwrapRemote(e);
- if (errorCode == RpcErrorCodeProto.ERROR_NO_SUCH_METHOD) {
- return Result.NO_SUCH_METHOD;
- }
- throw e;
+ Pair<String,Result> result = safeInvokeMethod(setECPolicyMethod, dfs, path, pairName.getLeft());
+ if (result.getRight() != null) {
+ return result.getRight();
}
return Result.DONE;
} else {
@@ -94,6 +97,18 @@
}
}
+ private static <X> Pair<X, Result> safeInvokeMethod(Method method, Object instance, Object... args) {
+ try {
+ return Pair.of((X) invokeMethod(method, instance, args), null);
+ } catch (RuntimeException e) {
+ RpcErrorCodeProto errorCode = unwrapRemote(e);
+ if (errorCode == RpcErrorCodeProto.ERROR_NO_SUCH_METHOD) {
+ return Pair.of(null, Result.NO_SUCH_METHOD);
+ }
+ throw e;
+ }
+ }
+
private static RpcErrorCodeProto unwrapRemote(Throwable e) {
if (e instanceof InvocationTargetException) {
return unwrapRemote(e.getCause());
diff --git a/tools/src/test/java/org/apache/hadoop/hdfs/protocol/SystemErasureCodingPolicies.java b/tools/src/test/java/org/apache/hadoop/hdfs/protocol/SystemErasureCodingPolicies.java
index ca6b65a..d5c5f9e 100644
--- a/tools/src/test/java/org/apache/hadoop/hdfs/protocol/SystemErasureCodingPolicies.java
+++ b/tools/src/test/java/org/apache/hadoop/hdfs/protocol/SystemErasureCodingPolicies.java
@@ -24,16 +24,26 @@
*
*/
public class SystemErasureCodingPolicies {
- public enum ReplicationPolicy {
- DEFAULT, OTHER;
+ private static ReplicationPolicy systemPolicy = ReplicationPolicy.DEFAULT;
+
+ public static class ReplicationPolicy {
+ public final static ReplicationPolicy DEFAULT = new ReplicationPolicy("DEFAULT");
+ public final static ReplicationPolicy OTHER = new ReplicationPolicy("OTHER");
+ private String name;
+ public ReplicationPolicy(String name) {
+ this.name = name;
+ }
public String getName() {
- return name();
+ return name;
}
}
public static ReplicationPolicy getReplicationPolicy() {
- return ReplicationPolicy.DEFAULT;
+ return systemPolicy;
}
+ public static void setSystemPolicy(ReplicationPolicy systemPolicy) {
+ SystemErasureCodingPolicies.systemPolicy = systemPolicy;
+ }
}
diff --git a/tools/src/test/java/org/apache/oozie/tools/TestECPolicyDisabler.java b/tools/src/test/java/org/apache/oozie/tools/TestECPolicyDisabler.java
index b085eb2..c2ba314 100644
--- a/tools/src/test/java/org/apache/oozie/tools/TestECPolicyDisabler.java
+++ b/tools/src/test/java/org/apache/oozie/tools/TestECPolicyDisabler.java
@@ -36,6 +36,7 @@
import org.apache.hadoop.ipc.protobuf.RpcHeaderProtos.RpcResponseHeaderProto.RpcErrorCodeProto;
import org.apache.oozie.tools.ECPolicyDisabler.Result;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
@@ -50,6 +51,11 @@
public abstract void setErasureCodingPolicy(Path path, String policy);
}
+ @Before
+ public void setup() {
+ SystemErasureCodingPolicies.setSystemPolicy(ReplicationPolicy.DEFAULT);
+ }
+
@Test
public void testNotSupported() {
FileSystem fs = mock(FileSystem.class);
@@ -91,6 +97,42 @@
}
@Test
+ public void testServerNotSupportsGetErasureCodingPolicyMethod() {
+ MockDistributedFileSystem fs = mock(MockDistributedFileSystem.class);
+ when(fs.getErasureCodingPolicy(any(Path.class))).thenThrow(createNoSuchMethodException());
+ ECPolicyDisabler.Result result = ECPolicyDisabler.check(fs, mock(Path.class));
+ assertEquals("result is expected", Result.NO_SUCH_METHOD, result);
+ verify(fs).getErasureCodingPolicy(any(Path.class));
+ verifyNoMoreInteractions(fs);
+ }
+
+ @Test
+ public void testServerNotSupportsGetName() {
+ MockDistributedFileSystem fs = mock(MockDistributedFileSystem.class);
+ when(fs.getErasureCodingPolicy(any())).thenReturn(ReplicationPolicy.OTHER);
+
+ ReplicationPolicy mockPolicy = mock(ReplicationPolicy.class);
+ SystemErasureCodingPolicies.setSystemPolicy(mockPolicy);
+ when(mockPolicy.getName()).thenThrow(createNoSuchMethodException());
+ ECPolicyDisabler.Result result = ECPolicyDisabler.check(fs, null);
+ assertEquals("result is expected", Result.NO_SUCH_METHOD, result);
+ verify(fs).getErasureCodingPolicy(any());
+ verifyNoMoreInteractions(fs);
+ }
+
+ @Test
+ public void testServerNotSupportsSetErasureCodingPolicyMethod() {
+ MockDistributedFileSystem fs = mock(MockDistributedFileSystem.class);
+ when(fs.getErasureCodingPolicy(any())).thenReturn(ReplicationPolicy.OTHER);
+ Mockito.doThrow(createNoSuchMethodException()).when(fs).setErasureCodingPolicy(any(), any());
+ ECPolicyDisabler.Result result = ECPolicyDisabler.check(fs, null);
+ assertEquals("result is expected", Result.NO_SUCH_METHOD, result);
+ verify(fs).getErasureCodingPolicy(any());
+ verify(fs).setErasureCodingPolicy(any(), eq("DEFAULT"));
+ verifyNoMoreInteractions(fs);
+ }
+
+ @Test
public void testOtherRuntimeExceptionThrown() {
MockDistributedFileSystem fs = mock(MockDistributedFileSystem.class);
when(fs.getErasureCodingPolicy(any())).thenReturn(ReplicationPolicy.OTHER);