You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ozone.apache.org by jh...@apache.org on 2026/05/01 02:23:12 UTC
(ozone) 02/02: Add ContainerStateManagerInvoker
This is an automated email from the ASF dual-hosted git repository.
Russole pushed a commit to branch HDDS-15053
in repository https://gitbox.apache.org/repos/asf/ozone.git
commit ff56ce6a01ece61b4faac178218ff34aa779a97c
Author: Russole <85...@gmail.com>
AuthorDate: Fri May 1 10:17:40 2026 +0800
Add ContainerStateManagerInvoker
---
.../hdds/scm/container/ContainerStateManager.java | 5 +
.../scm/container/ContainerStateManagerImpl.java | 3 +-
.../ha/invoker/ContainerStateManagerInvoker.java | 328 +++++++++++++++++++++
.../scm/ha/invoker/ScmInvokerCodeGenerator.java | 218 ++++++++++++--
4 files changed, 522 insertions(+), 32 deletions(-)
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManager.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManager.java
index 9e31e21822b..fa282396a3e 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManager.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManager.java
@@ -28,6 +28,7 @@
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
import org.apache.hadoop.hdds.protocol.proto.SCMRatisProtocol.RequestType;
import org.apache.hadoop.hdds.scm.ha.SCMHandler;
+import org.apache.hadoop.hdds.scm.ha.invoker.ScmInvokerCodeGenerator;
import org.apache.hadoop.hdds.scm.metadata.Replicate;
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
import org.apache.hadoop.hdds.utils.db.Table;
@@ -236,4 +237,8 @@ default RequestType getType() {
@Replicate
void updateContainerInfo(HddsProtos.ContainerInfoProto containerInfo)
throws IOException;
+
+ static void main(String[] args) {
+ ScmInvokerCodeGenerator.generate(ContainerStateManager.class, true);
+ }
}
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
index 7b50dfceb7b..80a9725fac9 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/container/ContainerStateManagerImpl.java
@@ -58,6 +58,7 @@
import org.apache.hadoop.hdds.scm.container.states.ContainerStateMap;
import org.apache.hadoop.hdds.scm.ha.ExecutionUtil;
import org.apache.hadoop.hdds.scm.ha.SCMRatisServer;
+import org.apache.hadoop.hdds.scm.ha.invoker.ContainerStateManagerInvoker;
import org.apache.hadoop.hdds.scm.metadata.DBTransactionBuffer;
import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
import org.apache.hadoop.hdds.scm.pipeline.PipelineManager;
@@ -653,7 +654,7 @@ public ContainerStateManager build() throws IOException {
conf, pipelineMgr, table, transactionBuffer,
containerReplicaPendingOps);
- return scmRatisServer.getProxyHandler(ContainerStateManager.class, csm);
+ return scmRatisServer.getProxyHandler(new ContainerStateManagerInvoker(csm, scmRatisServer));
}
}
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ContainerStateManagerInvoker.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ContainerStateManagerInvoker.java
new file mode 100644
index 00000000000..12cc3785d28
--- /dev/null
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ContainerStateManagerInvoker.java
@@ -0,0 +1,328 @@
+/*
+ * 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.hadoop.hdds.scm.ha.invoker;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableSet;
+import java.util.Set;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ContainerInfoProto;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleEvent;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.LifeCycleState;
+import org.apache.hadoop.hdds.protocol.proto.HddsProtos.ReplicationType;
+import org.apache.hadoop.hdds.scm.container.ContainerID;
+import org.apache.hadoop.hdds.scm.container.ContainerInfo;
+import org.apache.hadoop.hdds.scm.container.ContainerReplica;
+import org.apache.hadoop.hdds.scm.container.ContainerStateManager;
+import org.apache.hadoop.hdds.scm.ha.SCMRatisResponse;
+import org.apache.hadoop.hdds.scm.ha.SCMRatisServer;
+import org.apache.hadoop.hdds.scm.pipeline.PipelineID;
+import org.apache.hadoop.hdds.utils.db.Table;
+import org.apache.hadoop.ozone.common.statemachine.InvalidStateTransitionException;
+import org.apache.ratis.protocol.Message;
+
+/** Code generated for {@link ContainerStateManager}. Do not modify. */
+public class ContainerStateManagerInvoker extends ScmInvoker<ContainerStateManager> {
+ enum ReplicateMethod implements NameAndParameterTypes {
+ addContainer(new Class<?>[][] {
+ null,
+ new Class<?>[] {ContainerInfoProto.class}
+ }),
+ removeContainer(new Class<?>[][] {
+ null,
+ new Class<?>[] {HddsProtos.ContainerID.class}
+ }),
+ transitionDeletingOrDeletedToTargetState(new Class<?>[][] {
+ null,
+ null,
+ new Class<?>[] {HddsProtos.ContainerID.class, LifeCycleState.class}
+ }),
+ updateContainerInfo(new Class<?>[][] {
+ null,
+ new Class<?>[] {ContainerInfoProto.class}
+ }),
+ updateContainerStateWithSequenceId(new Class<?>[][] {
+ null,
+ null,
+ null,
+ new Class<?>[] {HddsProtos.ContainerID.class, LifeCycleEvent.class, Long.class}
+ });
+
+ private final Class<?>[][] parameterTypes;
+
+ ReplicateMethod(Class<?>[][] parameterTypes) {
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public Class<?>[] getParameterTypes(int numArgs) {
+ return parameterTypes[numArgs];
+ }
+ }
+
+ public ContainerStateManagerInvoker(ContainerStateManager impl, SCMRatisServer ratis) {
+ super(impl, ContainerStateManagerInvoker::newProxy, ratis);
+ }
+
+ @Override
+ public Class<ContainerStateManager> getApi() {
+ return ContainerStateManager.class;
+ }
+
+ static ContainerStateManager newProxy(ScmInvoker<ContainerStateManager> invoker) {
+ return new ContainerStateManager() {
+
+ @Override
+ public void addContainer(ContainerInfoProto arg0) throws IOException {
+ final Object[] args = {arg0};
+ invoker.invokeReplicateDirect(ReplicateMethod.addContainer, args);
+ }
+
+ @Override
+ public boolean contains(ContainerID arg0) {
+ return invoker.getImpl().contains(arg0);
+ }
+
+ @Override
+ public ContainerInfo getContainer(ContainerID arg0) {
+ return invoker.getImpl().getContainer(arg0);
+ }
+
+ @Override
+ public int getContainerCount(LifeCycleState arg0) {
+ return invoker.getImpl().getContainerCount(arg0);
+ }
+
+ @Override
+ public List<ContainerID> getContainerIDs(LifeCycleState arg0, ContainerID arg1, int arg2) {
+ return invoker.getImpl().getContainerIDs(arg0, arg1, arg2);
+ }
+
+ @Override
+ public List<ContainerInfo> getContainerInfos(ReplicationType arg0) {
+ return invoker.getImpl().getContainerInfos(arg0);
+ }
+
+ @Override
+ public List<ContainerInfo> getContainerInfos(LifeCycleState arg0) {
+ return invoker.getImpl().getContainerInfos(arg0);
+ }
+
+ @Override
+ public List<ContainerInfo> getContainerInfos(ContainerID arg0, int arg1) {
+ return invoker.getImpl().getContainerInfos(arg0, arg1);
+ }
+
+ @Override
+ public List<ContainerInfo> getContainerInfos(LifeCycleState arg0, ContainerID arg1, int arg2) {
+ return invoker.getImpl().getContainerInfos(arg0, arg1, arg2);
+ }
+
+ @Override
+ public Set<ContainerReplica> getContainerReplicas(ContainerID arg0) {
+ return invoker.getImpl().getContainerReplicas(arg0);
+ }
+
+ @Override
+ public ContainerInfo getMatchingContainer(long arg0, String arg1, PipelineID arg2, NavigableSet arg3) {
+ return invoker.getImpl().getMatchingContainer(arg0, arg1, arg2, arg3);
+ }
+
+ @Override
+ public void reinitialize(Table arg0) throws IOException {
+ invoker.getImpl().reinitialize(arg0);
+ }
+
+ @Override
+ public void removeContainer(HddsProtos.ContainerID arg0) throws IOException {
+ final Object[] args = {arg0};
+ invoker.invokeReplicateDirect(ReplicateMethod.removeContainer, args);
+ }
+
+ @Override
+ public void removeContainerReplica(ContainerReplica arg0) {
+ invoker.getImpl().removeContainerReplica(arg0);
+ }
+
+ @Override
+ public void transitionDeletingOrDeletedToTargetState(HddsProtos.ContainerID arg0, LifeCycleState arg1) throws
+ IOException {
+ final Object[] args = {arg0, arg1};
+ invoker.invokeReplicateDirect(ReplicateMethod.transitionDeletingOrDeletedToTargetState, args);
+ }
+
+ @Override
+ public void updateContainerInfo(ContainerInfoProto arg0) throws IOException {
+ final Object[] args = {arg0};
+ invoker.invokeReplicateDirect(ReplicateMethod.updateContainerInfo, args);
+ }
+
+ @Override
+ public void updateContainerReplica(ContainerReplica arg0) {
+ invoker.getImpl().updateContainerReplica(arg0);
+ }
+
+ @Override
+ public void updateContainerStateWithSequenceId(HddsProtos.ContainerID arg0, LifeCycleEvent arg1, Long arg2) throws
+ IOException, InvalidStateTransitionException {
+ final Object[] args = {arg0, arg1, arg2};
+ invoker.invokeReplicateDirect(ReplicateMethod.updateContainerStateWithSequenceId, args);
+ }
+
+ @Override
+ public void updateDeleteTransactionId(Map arg0) throws IOException {
+ invoker.getImpl().updateDeleteTransactionId(arg0);
+ }
+ };
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Message invokeLocal(String methodName, Object[] p) throws Exception {
+ final Class<?> returnType;
+ final Object returnValue;
+ switch (methodName) {
+ case "addContainer":
+ final ContainerInfoProto arg0 = p.length > 0 ? (ContainerInfoProto) p[0] : null;
+ getImpl().addContainer(arg0);
+ return Message.EMPTY;
+
+ case "contains":
+ final ContainerID arg1 = p.length > 0 ? (ContainerID) p[0] : null;
+ returnType = boolean.class;
+ returnValue = getImpl().contains(arg1);
+ break;
+
+ case "getContainer":
+ final ContainerID arg2 = p.length > 0 ? (ContainerID) p[0] : null;
+ returnType = ContainerInfo.class;
+ returnValue = getImpl().getContainer(arg2);
+ break;
+
+ case "getContainerCount":
+ final LifeCycleState arg3 = p.length > 0 ? (LifeCycleState) p[0] : null;
+ returnType = int.class;
+ returnValue = getImpl().getContainerCount(arg3);
+ break;
+
+ case "getContainerIDs":
+ final LifeCycleState arg4 = p.length > 0 ? (LifeCycleState) p[0] : null;
+ final ContainerID arg5 = p.length > 1 ? (ContainerID) p[1] : null;
+ final int arg6 = p.length > 2 ? (int) p[2] : 0;
+ returnType = List.class;
+ returnValue = getImpl().getContainerIDs(arg4, arg5, arg6);
+ break;
+
+ case "getContainerInfos":
+ if (p.length == 1 && (p[0] == null || ReplicationType.class.isInstance(p[0]))) {
+ final ReplicationType arg7 = (ReplicationType) p[0];
+ returnType = List.class;
+ returnValue = getImpl().getContainerInfos(arg7);
+ break;
+ }
+ if (p.length == 1 && (p[0] == null || LifeCycleState.class.isInstance(p[0]))) {
+ final LifeCycleState arg8 = (LifeCycleState) p[0];
+ returnType = List.class;
+ returnValue = getImpl().getContainerInfos(arg8);
+ break;
+ }
+ if (p.length == 2 && (p[0] == null || ContainerID.class.isInstance(p[0])) && p[1] instanceof Integer) {
+ final ContainerID arg9 = (ContainerID) p[0];
+ final int arg10 = (int) p[1];
+ returnType = List.class;
+ returnValue = getImpl().getContainerInfos(arg9, arg10);
+ break;
+ }
+ if (p.length == 3 && (p[0] == null || LifeCycleState.class.isInstance(p[0])) && (p[1] == null ||
+ ContainerID.class.isInstance(p[1])) && p[2] instanceof Integer) {
+ final LifeCycleState arg11 = (LifeCycleState) p[0];
+ final ContainerID arg12 = (ContainerID) p[1];
+ final int arg13 = (int) p[2];
+ returnType = List.class;
+ returnValue = getImpl().getContainerInfos(arg11, arg12, arg13);
+ break;
+ }
+ throw new IllegalArgumentException("Method not found: " + methodName + " in ContainerStateManager");
+
+ case "getContainerReplicas":
+ final ContainerID arg14 = p.length > 0 ? (ContainerID) p[0] : null;
+ returnType = Set.class;
+ returnValue = getImpl().getContainerReplicas(arg14);
+ break;
+
+ case "getMatchingContainer":
+ final long arg15 = p.length > 0 ? (long) p[0] : 0L;
+ final String arg16 = p.length > 1 ? (String) p[1] : null;
+ final PipelineID arg17 = p.length > 2 ? (PipelineID) p[2] : null;
+ final NavigableSet arg18 = p.length > 3 ? (NavigableSet) p[3] : null;
+ returnType = ContainerInfo.class;
+ returnValue = getImpl().getMatchingContainer(arg15, arg16, arg17, arg18);
+ break;
+
+ case "reinitialize":
+ final Table arg19 = p.length > 0 ? (Table) p[0] : null;
+ getImpl().reinitialize(arg19);
+ return Message.EMPTY;
+
+ case "removeContainer":
+ final HddsProtos.ContainerID arg20 = p.length > 0 ? (HddsProtos.ContainerID) p[0] : null;
+ getImpl().removeContainer(arg20);
+ return Message.EMPTY;
+
+ case "removeContainerReplica":
+ final ContainerReplica arg21 = p.length > 0 ? (ContainerReplica) p[0] : null;
+ getImpl().removeContainerReplica(arg21);
+ return Message.EMPTY;
+
+ case "transitionDeletingOrDeletedToTargetState":
+ final HddsProtos.ContainerID arg22 = p.length > 0 ? (HddsProtos.ContainerID) p[0] : null;
+ final LifeCycleState arg23 = p.length > 1 ? (LifeCycleState) p[1] : null;
+ getImpl().transitionDeletingOrDeletedToTargetState(arg22, arg23);
+ return Message.EMPTY;
+
+ case "updateContainerInfo":
+ final ContainerInfoProto arg24 = p.length > 0 ? (ContainerInfoProto) p[0] : null;
+ getImpl().updateContainerInfo(arg24);
+ return Message.EMPTY;
+
+ case "updateContainerReplica":
+ final ContainerReplica arg25 = p.length > 0 ? (ContainerReplica) p[0] : null;
+ getImpl().updateContainerReplica(arg25);
+ return Message.EMPTY;
+
+ case "updateContainerStateWithSequenceId":
+ final HddsProtos.ContainerID arg26 = p.length > 0 ? (HddsProtos.ContainerID) p[0] : null;
+ final LifeCycleEvent arg27 = p.length > 1 ? (LifeCycleEvent) p[1] : null;
+ final Long arg28 = p.length > 2 ? (Long) p[2] : null;
+ getImpl().updateContainerStateWithSequenceId(arg26, arg27, arg28);
+ return Message.EMPTY;
+
+ case "updateDeleteTransactionId":
+ final Map arg29 = p.length > 0 ? (Map) p[0] : null;
+ getImpl().updateDeleteTransactionId(arg29);
+ return Message.EMPTY;
+
+ default:
+ throw new IllegalArgumentException("Method not found: " + methodName + " in ContainerStateManager");
+ }
+
+ return SCMRatisResponse.encode(returnValue, returnType);
+ }
+}
diff --git a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ScmInvokerCodeGenerator.java b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ScmInvokerCodeGenerator.java
index a99364bc99b..a15bd3fa140 100644
--- a/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ScmInvokerCodeGenerator.java
+++ b/hadoop-hdds/server-scm/src/main/java/org/apache/hadoop/hdds/scm/ha/invoker/ScmInvokerCodeGenerator.java
@@ -22,7 +22,6 @@
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -38,7 +37,9 @@
import java.nio.file.StandardOpenOption;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.LinkedHashMap;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -156,6 +157,39 @@ static String getClassname(Class<?> clazz) {
return getClassnameBuilder(clazz).toString();
}
+ String getClassnameForApi(Class<?> clazz) {
+ if (clazz.getEnclosingClass() != null
+ && clazz.getEnclosingClass().getSimpleName().endsWith("Protos")
+ && hasSimpleNameConflict(clazz)) {
+ return clazz.getEnclosingClass().getSimpleName() + "." + clazz.getSimpleName();
+ }
+ return getClassname(clazz);
+ }
+
+ boolean hasSimpleNameConflict(Class<?> clazz) {
+ final String simpleName = clazz.getSimpleName();
+ return Arrays.stream(api.getMethods())
+ .flatMap(method -> Arrays.stream(method.getParameterTypes()))
+ .anyMatch(type -> type != clazz && type.getSimpleName().equals(simpleName));
+ }
+
+ String getParameterStringForApi(Class<?>[] types, String[] names) {
+ final StringBuilder b = new StringBuilder();
+ final int n = names != null ? names.length : types.length;
+ for (int i = 0; i < n; i++) {
+ b.append(getClassnameForApi(types[i])).append(' ')
+ .append(names != null ? names[i] : "arg" + i).append(", ");
+ }
+ if (b.length() > 0) {
+ b.setLength(b.length() - 2);
+ }
+ return b.toString();
+ }
+
+ String classesToStringForApi(Class<?>[] classes, String suffix) {
+ return arrayToString(classes, c -> getClassnameForApi(c) + suffix);
+ }
+
static StringBuilder getClassnameBuilder(Class<?> clazz) {
final StringBuilder b = new StringBuilder(clazz.getSimpleName());
for (Class<?> c = clazz.getEnclosingClass(); c != null; c = c.getEnclosingClass()) {
@@ -305,7 +339,7 @@ private void printEnumConstant(List<Method> overrides) {
if (classes == null) {
printf("null");
} else {
- printf("new Class<?>[] {%s}", classesToString(classes, ".class"));
+ printf("new Class<?>[] {%s}", classesToStringForApi(classes, ".class"));
}
}
}
@@ -342,32 +376,123 @@ void printHeaderMethods() {
}
}
- void printCase(Method apiMethod, String actualParameter, AtomicInteger argCount) {
- printf("case \"%s\":", apiMethod.getName());
+ void printCase(List<Method> apiMethods, String actualParameter, String switchName, AtomicInteger argCount) {
+ printf("case \"%s\":", apiMethods.get(0).getName());
try (UncheckedAutoCloseable ignore = printScope(false, 1)) {
- final Parameter[] apiParameters = apiMethod.getParameters();
- final StringBuilder b = new StringBuilder();
- for (int i = 0; i < apiParameters.length; i++) {
- final Parameter p = apiParameters[i];
- final String classname = getClassname(p.getType());
- final String arg = "arg" + argCount.getAndIncrement();
- b.append(arg).append(", ");
- println("final %s %s = %s.length > %d ? (%s) %s[%d] : null;", classname, arg,
- actualParameter, i, classname, actualParameter, i);
+ if (apiMethods.size() == 1) {
+ printMethodCall(apiMethods.get(0), actualParameter, argCount, false);
+ } else {
+ for (Method apiMethod : apiMethods) {
+ printf("if (%s)", getParameterMatchCondition(apiMethod, actualParameter));
+ try (UncheckedAutoCloseable ignored = printScope()) {
+ printMethodCall(apiMethod, actualParameter, argCount, true);
+ }
+ }
+ printMethodNotFound(null, switchName);
}
- if (b.length() > 0) {
- b.setLength(b.length() - 2);
+ }
+ println();
+ }
+
+ void printMethodCall(Method apiMethod, String actualParameter, AtomicInteger argCount, boolean exactArgs) {
+ final Parameter[] apiParameters = apiMethod.getParameters();
+ final StringBuilder b = new StringBuilder();
+ for (int i = 0; i < apiParameters.length; i++) {
+ final Parameter p = apiParameters[i];
+ final String classname = getClassnameForApi(p.getType());
+ final String arg = "arg" + argCount.getAndIncrement();
+ b.append(arg).append(", ");
+ if (exactArgs) {
+ println("final %s %s = (%s) %s[%d];", classname, arg, classname, actualParameter, i);
+ } else {
+ println("final %s %s = %s.length > %d ? (%s) %s[%d] : %s;", classname, arg,
+ actualParameter, i, classname, actualParameter, i, getDefaultValue(p.getType()));
}
- if (apiMethod.getReturnType() == void.class) {
- println("getImpl().%s(%s);", apiMethod.getName(), b);
- println("return Message.EMPTY;");
+ }
+ if (b.length() > 0) {
+ b.setLength(b.length() - 2);
+ }
+ if (apiMethod.getReturnType() == void.class) {
+ println("getImpl().%s(%s);", apiMethod.getName(), b);
+ println("return Message.EMPTY;");
+ } else {
+ println("returnType = %s.class;", getClassname(apiMethod.getReturnType()));
+ println("returnValue = getImpl().%s(%s);", apiMethod.getName(), b);
+ println("break;");
+ }
+ }
+
+ String getParameterMatchCondition(Method method, String actualParameter) {
+ final StringBuilder b = new StringBuilder()
+ .append(actualParameter)
+ .append(".length == ")
+ .append(method.getParameterCount());
+
+ final Class<?>[] parameterTypes = method.getParameterTypes();
+ for (int i = 0; i < parameterTypes.length; i++) {
+ final Class<?> type = parameterTypes[i];
+ final String checkType = getClassnameForApi(type.isPrimitive() ? getBoxedType(type) : type);
+ if (type.isPrimitive()) {
+ b.append(" && ").append(actualParameter).append("[").append(i).append("] instanceof ")
+ .append(checkType);
} else {
- println("returnType = %s.class;", getClassname(apiMethod.getReturnType()));
- println("returnValue = getImpl().%s(%s);", apiMethod.getName(), b);
- println("break;");
+ b.append(" && (").append(actualParameter).append("[").append(i).append("] == null || ")
+ .append(checkType).append(".class.isInstance(").append(actualParameter).append("[")
+ .append(i).append("]))");
}
}
- println();
+ return b.toString();
+ }
+
+ static Class<?> getBoxedType(Class<?> type) {
+ if (type == boolean.class) {
+ return Boolean.class;
+ } else if (type == byte.class) {
+ return Byte.class;
+ } else if (type == char.class) {
+ return Character.class;
+ } else if (type == short.class) {
+ return Short.class;
+ } else if (type == int.class) {
+ return Integer.class;
+ } else if (type == long.class) {
+ return Long.class;
+ } else if (type == float.class) {
+ return Float.class;
+ } else if (type == double.class) {
+ return Double.class;
+ }
+ return type;
+ }
+
+ static String getDefaultValue(Class<?> type) {
+ if (!type.isPrimitive()) {
+ return "null";
+ } else if (type == boolean.class) {
+ return "false";
+ } else if (type == char.class) {
+ return "'\\0'";
+ } else if (type == long.class) {
+ return "0L";
+ } else if (type == float.class) {
+ return "0F";
+ } else if (type == double.class) {
+ return "0D";
+ }
+ return "0";
+ }
+
+ void printMethodNotFound(String label, String switchName) {
+ if (label != null) {
+ printf("%s:", label);
+ try (UncheckedAutoCloseable ignore = printScope(false, 1)) {
+ println("throw new IllegalArgumentException(\"Method not found: \" + %s + \" in %s\");",
+ switchName, apiName);
+ }
+ } else {
+ println("throw new IllegalArgumentException(\"Method not found: \" + %s + \" in %s\");",
+ switchName, apiName);
+ }
}
void printSwitch(DeclaredMethod method) {
@@ -375,15 +500,15 @@ void printSwitch(DeclaredMethod method) {
printf("switch (%s)", switchName);
try (UncheckedAutoCloseable ignored = printScope(true, 0)) {
final AtomicInteger argCount = new AtomicInteger(0);
- for (Method apiMethod : getMethods(false, null)) {
- printCase(apiMethod, method.getParameterName(1), argCount);
- }
+ final Map<String, List<Method>> methodsByName = getMethods(false, null).stream()
+ .collect(Collectors.groupingBy(
+ Method::getName, LinkedHashMap::new, Collectors.toList()));
- printf("default:");
- try (UncheckedAutoCloseable ignore = printScope(false, 1)) {
- println("throw new IllegalArgumentException(\"Method not found: \" + %s + \" in %s\");",
- switchName, apiName);
+ for (List<Method> apiMethods : methodsByName.values()) {
+ printCase(apiMethods, method.getParameterName(1), switchName, argCount);
}
+
+ printMethodNotFound("default", switchName);
}
}
@@ -413,7 +538,7 @@ void printProxyClassMethod(Method method) {
printf("public %s %s(%s)%s",
getReturnTypeString(method),
method.getName(),
- getParameterString(method.getParameterTypes(), null),
+ getParameterStringForApi(method.getParameterTypes(), null),
getThrowsString(method.getExceptionTypes()));
try (UncheckedAutoCloseable ignored = printScope()) {
@@ -464,7 +589,7 @@ public String generateClass() {
File updateFile(String classString) throws IOException {
final File java = new File(DIR, invokerClassName + ".java");
if (!java.isFile()) {
- throw new FileNotFoundException("Not found: " + java.getAbsolutePath());
+ return createFile(java, classString);
}
final File tmp = new File(DIR, invokerClassName + "_tmp.java");
if (tmp.exists()) {
@@ -537,4 +662,35 @@ String getSignature() {
getThrowsString(exceptionTypes));
}
}
+
+ File createFile(File java, String classString) throws IOException {
+ try (OutputStream outStream = Files.newOutputStream(java.toPath(), StandardOpenOption.CREATE_NEW);
+ PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, UTF_8), true)) {
+ out.println("/*");
+ out.println(" * Licensed to the Apache Software Foundation (ASF) under one or more");
+ out.println(" * contributor license agreements. See the NOTICE file distributed with");
+ out.println(" * this work for additional information regarding copyright ownership.");
+ out.println(" * The ASF licenses this file to You under the Apache License, Version 2.0");
+ out.println(" * (the \"License\"); you may not use this file except in compliance with");
+ out.println(" * the License. You may obtain a copy of the License at");
+ out.println(" *");
+ out.println(" * http://www.apache.org/licenses/LICENSE-2.0");
+ out.println(" *");
+ out.println(" * Unless required by applicable law or agreed to in writing, software");
+ out.println(" * distributed under the License is distributed on an \"AS IS\" BASIS,");
+ out.println(" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.");
+ out.println(" * See the License for the specific language governing permissions and");
+ out.println(" * limitations under the License.");
+ out.println(" */");
+ out.println();
+ out.println("package org.apache.hadoop.hdds.scm.ha.invoker;");
+ out.println();
+ out.println("import org.apache.hadoop.hdds.scm.ha.SCMRatisResponse;");
+ out.println("import org.apache.hadoop.hdds.scm.ha.SCMRatisServer;");
+ out.println("import org.apache.ratis.protocol.Message;");
+ out.println();
+ out.print(classString);
+ }
+ return java;
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@ozone.apache.org
For additional commands, e-mail: commits-help@ozone.apache.org