HBASE-26921 Rewrite the counting cells part in TestMultiVersions (#4316)
[hbase.git] / hbase-client / src / main / java / org / apache / hadoop / hbase / protobuf / ProtobufMessageConverter.java
blobfd74719e722e943eb74af23b55b4a0a18901fe82
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 package org.apache.hadoop.hbase.protobuf;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.LinkedHashMap;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Map.Entry;
28 import org.apache.yetus.audience.InterfaceAudience;
29 import org.apache.hbase.thirdparty.com.google.gson.JsonArray;
30 import org.apache.hbase.thirdparty.com.google.gson.JsonElement;
31 import org.apache.hbase.thirdparty.com.google.gson.JsonObject;
32 import org.apache.hbase.thirdparty.com.google.gson.JsonParser;
33 import org.apache.hbase.thirdparty.com.google.gson.JsonPrimitive;
34 import org.apache.hbase.thirdparty.com.google.protobuf.BytesValue;
35 import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
36 import org.apache.hbase.thirdparty.com.google.protobuf.MessageOrBuilder;
37 import org.apache.hbase.thirdparty.com.google.protobuf.util.JsonFormat;
38 import org.apache.hbase.thirdparty.com.google.protobuf.util.JsonFormat.TypeRegistry;
39 import org.apache.hadoop.hbase.shaded.protobuf.generated.LockServiceProtos;
40 import org.apache.hadoop.hbase.shaded.protobuf.generated.MasterProcedureProtos;
41 import org.apache.hadoop.hbase.shaded.protobuf.generated.ProcedureProtos;
43 /**
44 * This class converts PB Messages to various representations, like:
45 * <ul>
46 * <li>JSON string: {@link #toJsonElement(MessageOrBuilder)}</li>
47 * <li>JSON object (gson): {@link #toJsonElement(MessageOrBuilder)}</li>
48 * <li>Java objects (Boolean, Number, String, List, Map):
49 * {@link #toJavaObject(JsonElement)}</li>
50 * </ul>
52 @InterfaceAudience.Private
53 public class ProtobufMessageConverter {
54 private static final String TYPE_KEY = "@type";
56 private static final JsonFormat.Printer jsonPrinter;
58 static {
59 TypeRegistry.Builder builder = TypeRegistry.newBuilder();
60 builder
61 .add(BytesValue.getDescriptor())
62 .add(LockServiceProtos.getDescriptor().getMessageTypes())
63 .add(MasterProcedureProtos.getDescriptor().getMessageTypes())
64 .add(ProcedureProtos.getDescriptor().getMessageTypes());
65 TypeRegistry typeRegistry = builder.build();
66 jsonPrinter = JsonFormat.printer()
67 .usingTypeRegistry(typeRegistry)
68 .omittingInsignificantWhitespace();
71 private ProtobufMessageConverter() {
74 public static String toJsonString(MessageOrBuilder messageOrBuilder)
75 throws InvalidProtocolBufferException {
76 return jsonPrinter.print(messageOrBuilder);
79 private static void removeTypeFromJson(JsonElement json) {
80 if (json.isJsonArray()) {
81 for (JsonElement child: json.getAsJsonArray()) {
82 removeTypeFromJson(child);
84 } else if (json.isJsonObject()) {
85 Iterator<Entry<String, JsonElement>> iterator =
86 json.getAsJsonObject().entrySet().iterator();
88 while (iterator.hasNext()) {
89 Entry<String, JsonElement> entry = iterator.next();
90 if (TYPE_KEY.equals(entry.getKey())) {
91 iterator.remove();
92 } else {
93 removeTypeFromJson(entry.getValue());
99 public static JsonElement toJsonElement(MessageOrBuilder messageOrBuilder)
100 throws InvalidProtocolBufferException {
101 return toJsonElement(messageOrBuilder, true);
104 public static JsonElement toJsonElement(MessageOrBuilder messageOrBuilder,
105 boolean removeType) throws InvalidProtocolBufferException {
106 String jsonString = toJsonString(messageOrBuilder);
107 JsonParser parser = new JsonParser();
108 JsonElement element = parser.parse(jsonString);
109 if (removeType) {
110 removeTypeFromJson(element);
112 return element;
115 private static Object toJavaObject(JsonElement element) {
116 if (element.isJsonNull()) {
117 return null;
118 } else if (element.isJsonPrimitive()) {
119 JsonPrimitive primitive = element.getAsJsonPrimitive();
120 if (primitive.isBoolean()) {
121 return primitive.getAsBoolean();
122 } else if (primitive.isNumber()) {
123 return primitive.getAsNumber();
124 } else if (primitive.isString()) {
125 return primitive.getAsString();
126 } else {
127 return null;
129 } else if (element.isJsonArray()) {
130 JsonArray array = element.getAsJsonArray();
131 List<Object> list = new ArrayList<>();
133 for (JsonElement arrayElement : array) {
134 Object javaObject = toJavaObject(arrayElement);
135 list.add(javaObject);
138 return list;
139 } else if (element.isJsonObject()) {
140 JsonObject object = element.getAsJsonObject();
141 Map<String, Object> map = new LinkedHashMap<>();
143 for (Entry<String, JsonElement> entry: object.entrySet()) {
144 Object javaObject = toJavaObject(entry.getValue());
145 map.put(entry.getKey(), javaObject);
148 return map;
149 } else {
150 return null;
154 public static Object toJavaObject(MessageOrBuilder messageOrBuilder)
155 throws InvalidProtocolBufferException {
156 JsonElement element = toJsonElement(messageOrBuilder);
157 return toJavaObject(element);