View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.protobuf;
21  
22  
23  import com.google.protobuf.ByteString;
24  import com.google.protobuf.ServiceException;
25  import org.apache.hadoop.hbase.HConstants;
26  import org.apache.hadoop.hbase.KeyValue;
27  import org.apache.hadoop.hbase.client.AdminProtocol;
28  import org.apache.hadoop.hbase.protobuf.generated.AdminProtos;
29  import org.apache.hadoop.hbase.regionserver.wal.HLog;
30  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
31  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
32  import org.apache.hadoop.hbase.util.Bytes;
33  
34  import java.io.IOException;
35  import java.util.ArrayList;
36  import java.util.List;
37  import java.util.Map;
38  import java.util.NavigableMap;
39  import java.util.TreeMap;
40  import java.util.UUID;
41  
42  public class ReplicationProtbufUtil {
43    /**
44     * Get the HLog entries from a list of protocol buffer WALEntry
45     *
46     * @param protoList the list of protocol buffer WALEntry
47     * @return an array of HLog entries
48     */
49    public static HLog.Entry[]
50        toHLogEntries(final List<AdminProtos.WALEntry> protoList) {
51      List<HLog.Entry> entries = new ArrayList<HLog.Entry>();
52      for (AdminProtos.WALEntry entry: protoList) {
53        AdminProtos.WALEntry.WALKey walKey = entry.getKey();
54        java.util.UUID clusterId = HConstants.DEFAULT_CLUSTER_ID;
55        if (walKey.hasClusterId()) {
56          AdminProtos.UUID protoUuid = walKey.getClusterId();
57          clusterId = new java.util.UUID(
58            protoUuid.getMostSigBits(), protoUuid.getLeastSigBits());
59        }
60        HLogKey key = new HLogKey(walKey.getEncodedRegionName().toByteArray(),
61          walKey.getTableName().toByteArray(), walKey.getLogSequenceNumber(),
62          walKey.getWriteTime(), clusterId);
63        AdminProtos.WALEntry.WALEdit walEdit = entry.getEdit();
64        WALEdit edit = new WALEdit();
65        for (ByteString keyValue: walEdit.getKeyValueBytesList()) {
66          edit.add(new KeyValue(keyValue.toByteArray()));
67        }
68        if (walEdit.getFamilyScopeCount() > 0) {
69          TreeMap<byte[], Integer> scopes =
70            new TreeMap<byte[], Integer>(Bytes.BYTES_COMPARATOR);
71          for (AdminProtos.WALEntry.WALEdit.FamilyScope scope: walEdit.getFamilyScopeList()) {
72            scopes.put(scope.getFamily().toByteArray(),
73              Integer.valueOf(scope.getScopeType().ordinal()));
74          }
75          edit.setScopes(scopes);
76        }
77        entries.add(new HLog.Entry(key, edit));
78      }
79      return entries.toArray(new HLog.Entry[entries.size()]);
80    }
81  
82    /**
83     * A helper to replicate a list of HLog entries using admin protocol.
84     *
85     * @param admin
86     * @param entries
87     * @throws java.io.IOException
88     */
89    public static void replicateWALEntry(final AdminProtocol admin,
90        final HLog.Entry[] entries) throws IOException {
91      AdminProtos.ReplicateWALEntryRequest request =
92        buildReplicateWALEntryRequest(entries);
93      try {
94        admin.replicateWALEntry(null, request);
95      } catch (ServiceException se) {
96        throw ProtobufUtil.getRemoteException(se);
97      }
98    }
99  
100   /**
101    * Create a new ReplicateWALEntryRequest from a list of HLog entries
102    *
103    * @param entries the HLog entries to be replicated
104    * @return a ReplicateWALEntryRequest
105    */
106   public static AdminProtos.ReplicateWALEntryRequest
107       buildReplicateWALEntryRequest(final HLog.Entry[] entries) {
108     AdminProtos.WALEntry.WALEdit.FamilyScope.Builder scopeBuilder = AdminProtos.WALEntry
109         .WALEdit
110         .FamilyScope
111         .newBuilder();
112     AdminProtos.WALEntry.Builder entryBuilder = AdminProtos.WALEntry.newBuilder();
113     AdminProtos.ReplicateWALEntryRequest.Builder builder =
114       AdminProtos.ReplicateWALEntryRequest.newBuilder();
115     for (HLog.Entry entry: entries) {
116       entryBuilder.clear();
117       AdminProtos.WALEntry.WALKey.Builder keyBuilder = entryBuilder.getKeyBuilder();
118       HLogKey key = entry.getKey();
119       keyBuilder.setEncodedRegionName(
120         ByteString.copyFrom(key.getEncodedRegionName()));
121       keyBuilder.setTableName(ByteString.copyFrom(key.getTablename()));
122       keyBuilder.setLogSequenceNumber(key.getLogSeqNum());
123       keyBuilder.setWriteTime(key.getWriteTime());
124       UUID clusterId = key.getClusterId();
125       if (clusterId != null) {
126         AdminProtos.UUID.Builder uuidBuilder = keyBuilder.getClusterIdBuilder();
127         uuidBuilder.setLeastSigBits(clusterId.getLeastSignificantBits());
128         uuidBuilder.setMostSigBits(clusterId.getMostSignificantBits());
129       }
130       WALEdit edit = entry.getEdit();
131       AdminProtos.WALEntry.WALEdit.Builder editBuilder = entryBuilder.getEditBuilder();
132       NavigableMap<byte[], Integer> scopes = edit.getScopes();
133       if (scopes != null && !scopes.isEmpty()) {
134         for (Map.Entry<byte[], Integer> scope: scopes.entrySet()) {
135           scopeBuilder.setFamily(ByteString.copyFrom(scope.getKey()));
136           AdminProtos.WALEntry.WALEdit.ScopeType
137               scopeType = AdminProtos.WALEntry
138               .WALEdit
139               .ScopeType
140               .valueOf(scope.getValue().intValue());
141           scopeBuilder.setScopeType(scopeType);
142           editBuilder.addFamilyScope(scopeBuilder.build());
143         }
144       }
145       List<KeyValue> keyValues = edit.getKeyValues();
146       for (KeyValue value: keyValues) {
147         editBuilder.addKeyValueBytes(ByteString.copyFrom(
148           value.getBuffer(), value.getOffset(), value.getLength()));
149       }
150       builder.addEntry(entryBuilder.build());
151     }
152     return builder.build();
153   }
154 }