|
@@ -37,6 +37,7 @@ import java.net.InetSocketAddress;
|
|
import java.util.ArrayList;
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.Collection;
|
|
import java.util.EnumSet;
|
|
import java.util.EnumSet;
|
|
|
|
+import java.util.HashSet;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.LinkedHashSet;
|
|
import java.util.List;
|
|
import java.util.List;
|
|
@@ -587,6 +588,7 @@ public class RouterRpcServer extends AbstractService implements ClientProtocol,
|
|
/**
|
|
/**
|
|
* Invokes the method at default namespace, if default namespace is not
|
|
* Invokes the method at default namespace, if default namespace is not
|
|
* available then at the first available namespace.
|
|
* available then at the first available namespace.
|
|
|
|
+ * If the namespace is unavailable, retry once with other namespace.
|
|
* @param <T> expected return type.
|
|
* @param <T> expected return type.
|
|
* @param method the remote method.
|
|
* @param method the remote method.
|
|
* @return the response received after invoking method.
|
|
* @return the response received after invoking method.
|
|
@@ -595,18 +597,61 @@ public class RouterRpcServer extends AbstractService implements ClientProtocol,
|
|
<T> T invokeAtAvailableNs(RemoteMethod method, Class<T> clazz)
|
|
<T> T invokeAtAvailableNs(RemoteMethod method, Class<T> clazz)
|
|
throws IOException {
|
|
throws IOException {
|
|
String nsId = subclusterResolver.getDefaultNamespace();
|
|
String nsId = subclusterResolver.getDefaultNamespace();
|
|
- if (!nsId.isEmpty()) {
|
|
|
|
- return rpcClient.invokeSingle(nsId, method, clazz);
|
|
|
|
- }
|
|
|
|
// If default Ns is not present return result from first namespace.
|
|
// If default Ns is not present return result from first namespace.
|
|
Set<FederationNamespaceInfo> nss = namenodeResolver.getNamespaces();
|
|
Set<FederationNamespaceInfo> nss = namenodeResolver.getNamespaces();
|
|
|
|
+ try {
|
|
|
|
+ if (!nsId.isEmpty()) {
|
|
|
|
+ return rpcClient.invokeSingle(nsId, method, clazz);
|
|
|
|
+ }
|
|
|
|
+ // If no namespace is available, throw IOException.
|
|
|
|
+ IOException io = new IOException("No namespace available.");
|
|
|
|
+ return invokeOnNs(method, clazz, io, nss);
|
|
|
|
+ } catch (IOException ioe) {
|
|
|
|
+ if (!clientProto.isUnavailableSubclusterException(ioe)) {
|
|
|
|
+ LOG.debug("{} exception cannot be retried",
|
|
|
|
+ ioe.getClass().getSimpleName());
|
|
|
|
+ throw ioe;
|
|
|
|
+ }
|
|
|
|
+ Set<FederationNamespaceInfo> nssWithoutFailed = getNameSpaceInfo(nsId);
|
|
|
|
+ return invokeOnNs(method, clazz, ioe, nssWithoutFailed);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Invoke the method on first available namespace,
|
|
|
|
+ * throw no namespace available exception, if no namespaces are available.
|
|
|
|
+ * @param method the remote method.
|
|
|
|
+ * @param clazz Class for the return type.
|
|
|
|
+ * @param ioe IOException .
|
|
|
|
+ * @param nss List of name spaces in the federation
|
|
|
|
+ * @return the response received after invoking method.
|
|
|
|
+ * @throws IOException
|
|
|
|
+ */
|
|
|
|
+ <T> T invokeOnNs(RemoteMethod method, Class<T> clazz, IOException ioe,
|
|
|
|
+ Set<FederationNamespaceInfo> nss) throws IOException {
|
|
if (nss.isEmpty()) {
|
|
if (nss.isEmpty()) {
|
|
- throw new IOException("No namespace available.");
|
|
|
|
|
|
+ throw ioe;
|
|
}
|
|
}
|
|
- nsId = nss.iterator().next().getNameserviceId();
|
|
|
|
|
|
+ String nsId = nss.iterator().next().getNameserviceId();
|
|
return rpcClient.invokeSingle(nsId, method, clazz);
|
|
return rpcClient.invokeSingle(nsId, method, clazz);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Get set of namespace info's removing the already invoked namespaceinfo.
|
|
|
|
+ * @param nsId already invoked namespace id
|
|
|
|
+ * @return List of name spaces in the federation on
|
|
|
|
+ * removing the already invoked namespaceinfo.
|
|
|
|
+ */
|
|
|
|
+ private Set<FederationNamespaceInfo> getNameSpaceInfo(String nsId) {
|
|
|
|
+ Set<FederationNamespaceInfo> namespaceInfos = new HashSet<>();
|
|
|
|
+ for (FederationNamespaceInfo ns : namespaceInfos) {
|
|
|
|
+ if (!nsId.equals(ns.getNameserviceId())) {
|
|
|
|
+ namespaceInfos.add(ns);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return namespaceInfos;
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override // ClientProtocol
|
|
@Override // ClientProtocol
|
|
public Token<DelegationTokenIdentifier> getDelegationToken(Text renewer)
|
|
public Token<DelegationTokenIdentifier> getDelegationToken(Text renewer)
|
|
throws IOException {
|
|
throws IOException {
|