View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  package org.apache.hadoop.hbase.master.procedure;
20  
21  import java.io.IOException;
22  import java.io.InterruptedIOException;
23  import java.util.Map;
24  import java.util.Map.Entry;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.hbase.classification.InterfaceAudience;
29  import org.apache.hadoop.hbase.classification.InterfaceStability;
30  import org.apache.hadoop.hbase.client.HBaseAdmin;
31  import org.apache.hadoop.hbase.procedure.MasterProcedureManager;
32  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.NameStringPair;
33  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ProcedureDescription;
34  import org.apache.hadoop.hbase.protobuf.generated.RPCProtos.UserInformation;
35  import org.apache.hadoop.hbase.snapshot.SnapshotDescriptionUtils;
36  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
37  import org.apache.hadoop.security.UserGroupInformation;
38  
39  @InterfaceAudience.Private
40  @InterfaceStability.Evolving
41  public final class MasterProcedureUtil {
42    private static final Log LOG = LogFactory.getLog(MasterProcedureUtil.class);
43  
44    private MasterProcedureUtil() {}
45  
46    public static UserInformation toProtoUserInfo(UserGroupInformation ugi) {
47      UserInformation.Builder userInfoPB = UserInformation.newBuilder();
48      userInfoPB.setEffectiveUser(ugi.getUserName());
49      if (ugi.getRealUser() != null) {
50        userInfoPB.setRealUser(ugi.getRealUser().getUserName());
51      }
52      return userInfoPB.build();
53    }
54  
55    public static UserGroupInformation toUserInfo(UserInformation userInfoProto) {
56      if (userInfoProto.hasEffectiveUser()) {
57        String effectiveUser = userInfoProto.getEffectiveUser();
58        if (userInfoProto.hasRealUser()) {
59          String realUser = userInfoProto.getRealUser();
60          UserGroupInformation realUserUgi = UserGroupInformation.createRemoteUser(realUser);
61          return UserGroupInformation.createProxyUser(effectiveUser, realUserUgi);
62        }
63        return UserGroupInformation.createRemoteUser(effectiveUser);
64      }
65      return null;
66    }
67  
68    public static ProcedureDescription buildProcedure(String signature, String instance,
69        Map<String, String> props) {
70      ProcedureDescription.Builder builder = ProcedureDescription.newBuilder();
71      builder.setSignature(signature).setInstance(instance);
72      for (Entry<String, String> entry : props.entrySet()) {
73        NameStringPair pair = NameStringPair.newBuilder().setName(entry.getKey())
74            .setValue(entry.getValue()).build();
75        builder.addConfiguration(pair);
76      }
77      ProcedureDescription desc = builder.build();
78      return desc;
79    }
80  
81    public static long execProcedure(MasterProcedureManager mpm, String signature, String instance,
82        Map<String, String> props) throws IOException {
83      if (mpm == null) {
84        throw new IOException("The procedure is not registered: " + signature);
85      }
86      ProcedureDescription desc = buildProcedure(signature, instance, props);
87      mpm.execProcedure(desc);
88  
89      // send back the max amount of time the client should wait for the procedure
90      // to complete
91      long waitTime = SnapshotDescriptionUtils.DEFAULT_MAX_WAIT_TIME;
92      return waitTime;
93    }
94    
95    public static void waitForProcedure(MasterProcedureManager mpm, String signature, String instance,
96        Map<String, String> props, long max, int numRetries, long pause) throws IOException {
97      ProcedureDescription desc = buildProcedure(signature, instance, props);
98      long start = EnvironmentEdgeManager.currentTime();
99      long maxPauseTime = max / numRetries;
100     int tries = 0;
101     LOG.debug("Waiting a max of " + max + " ms for procedure '" +
102         signature + " : " + instance + "'' to complete. (max " + maxPauseTime + " ms per retry)");
103     boolean done = false;
104     while (tries == 0
105         || ((EnvironmentEdgeManager.currentTime() - start) < max && !done)) {
106       try {
107         // sleep a backoff <= pauseTime amount
108         long sleep = HBaseAdmin.getPauseTime(tries++, pause);
109         sleep = sleep > maxPauseTime ? maxPauseTime : sleep;
110         LOG.debug("(#" + tries + ") Sleeping: " + sleep +
111           "ms while waiting for procedure completion.");
112         Thread.sleep(sleep);
113       } catch (InterruptedException e) {
114         throw (InterruptedIOException) new InterruptedIOException("Interrupted").initCause(e);
115       }
116       LOG.debug("Getting current status of procedure from master...");
117       done = mpm.isProcedureDone(desc);
118     }
119     if (!done) {
120       throw new IOException("Procedure '" + signature + " : " + instance
121           + "' wasn't completed in expectedTime:" + max + " ms");
122     }
123 
124   }
125 }