1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase;
19
20 import com.google.protobuf.ServiceException;
21 import java.io.IOException;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.Set;
26 import org.apache.commons.lang.StringUtils;
27 import org.apache.hadoop.hbase.classification.InterfaceAudience;
28 import org.apache.hadoop.hbase.client.Admin;
29 import org.apache.hadoop.hbase.client.Connection;
30 import org.apache.hadoop.hbase.client.ConnectionFactory;
31 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ShellExecEndpoint.ShellExecRequest;
32 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ShellExecEndpoint.ShellExecResponse;
33 import org.apache.hadoop.hbase.coprocessor.protobuf.generated.ShellExecEndpoint.ShellExecService;
34 import org.apache.hadoop.hbase.ipc.HBaseRpcControllerImpl;
35 import org.apache.hadoop.hbase.util.Pair;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43 @InterfaceAudience.Private
44 @SuppressWarnings("unused")
45 public class CoprocClusterManager extends HBaseClusterManager {
46 private static final Logger LOG = LoggerFactory.getLogger(CoprocClusterManager.class);
47 private static final Set<ServiceType> supportedServices = buildSupportedServicesSet();
48
49 @Override
50 protected Pair<Integer, String> exec(String hostname, ServiceType service, String... cmd)
51 throws IOException {
52 if (!supportedServices.contains(service)) {
53 throw unsupportedServiceType(service);
54 }
55
56
57
58
59 final String command = StringUtils.join(cmd, " ");
60 LOG.info(String.format("Executing remote command: %s, hostname:%s", command, hostname));
61
62 try (final Connection conn = ConnectionFactory.createConnection(getConf())) {
63 final Admin admin = conn.getAdmin();
64 final ShellExecRequest req = ShellExecRequest.newBuilder()
65 .setCommand(command)
66 .setAwaitResponse(false)
67 .build();
68
69 final ShellExecResponse resp;
70 try {
71 switch (service) {
72 case HBASE_MASTER:
73
74
75 resp = masterExec(admin, req);
76 break;
77 case HBASE_REGIONSERVER:
78 final ServerName targetHost = resolveRegionServerName(admin, hostname);
79 resp = regionServerExec(admin, req, targetHost);
80 break;
81 default:
82 throw new RuntimeException("should not happen");
83 }
84 } catch (ServiceException se) {
85 LOG.error(String.format("Error running command: %s, error: %s", command, se.getMessage()));
86
87
88 throw new IOException(se);
89 }
90
91 if (LOG.isDebugEnabled()) {
92 LOG.debug(String.format("Executed remote command: %s, exit code:%s , output:%s", command,
93 resp.getExitCode(), resp.getStdout()));
94 } else {
95 LOG.info(String.format("Executed remote command: %s, exit code:%s", command,
96 resp.getExitCode()));
97 }
98 return new Pair<>(resp.getExitCode(), resp.getStdout());
99 }
100 }
101
102 private static Set<ServiceType> buildSupportedServicesSet() {
103 final Set<ServiceType> set = new HashSet<>();
104 set.add(ServiceType.HBASE_MASTER);
105 set.add(ServiceType.HBASE_REGIONSERVER);
106 return Collections.unmodifiableSet(set);
107 }
108
109 private static ShellExecResponse masterExec(final Admin admin,
110 final ShellExecRequest req) throws ServiceException {
111
112 return ShellExecService.newBlockingStub(
113 admin.coprocessorService()).shellExec(new HBaseRpcControllerImpl(), req);
114 }
115
116 private static ShellExecResponse regionServerExec(final Admin admin,
117 final ShellExecRequest req, final ServerName targetHost) throws ServiceException {
118 return ShellExecService.newBlockingStub(
119 admin.coprocessorService(targetHost)).shellExec(new HBaseRpcControllerImpl(), req);
120 }
121
122 private static ServerName resolveRegionServerName(final Admin admin,
123 final String hostname) throws IOException {
124 Collection<ServerName> liveServers = admin.getClusterStatus().getServers();
125 for (ServerName sname: liveServers) {
126 if (sname.getServerName().equals(hostname)) {
127 return sname;
128 }
129 }
130 throw serverNotFound(hostname);
131 }
132
133 private static RuntimeException serverNotFound(final String hostname) {
134 return new RuntimeException(
135 String.format("Did not find %s amongst the servers known to the client.", hostname));
136 }
137
138 private static RuntimeException unsupportedServiceType(final ServiceType serviceType) {
139 return new RuntimeException(
140 String.format("Unable to service request for service=%s", serviceType));
141 }
142 }