1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.rest.model;
20
21 import com.fasterxml.jackson.annotation.JsonAnyGetter;
22 import com.fasterxml.jackson.annotation.JsonAnySetter;
23 import com.fasterxml.jackson.annotation.JsonIgnore;
24
25 import java.io.IOException;
26 import java.io.Serializable;
27 import java.util.ArrayList;
28 import java.util.Iterator;
29 import java.util.LinkedHashMap;
30 import java.util.List;
31 import java.util.Map;
32
33 import javax.xml.bind.annotation.XmlAnyAttribute;
34 import javax.xml.bind.annotation.XmlAttribute;
35 import javax.xml.bind.annotation.XmlElement;
36 import javax.xml.bind.annotation.XmlRootElement;
37 import javax.xml.namespace.QName;
38
39 import org.apache.hadoop.hbase.HColumnDescriptor;
40 import org.apache.hadoop.hbase.HConstants;
41 import org.apache.hadoop.hbase.HTableDescriptor;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.classification.InterfaceAudience;
44 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
45 import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
46 import org.apache.hadoop.hbase.rest.ProtobufMessageHandler;
47 import org.apache.hadoop.hbase.rest.protobuf.generated.ColumnSchemaMessage.ColumnSchema;
48 import org.apache.hadoop.hbase.rest.protobuf.generated.TableSchemaMessage.TableSchema;
49 import org.apache.hadoop.hbase.util.Bytes;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 @XmlRootElement(name="TableSchema")
66 @InterfaceAudience.Private
67 public class TableSchemaModel implements Serializable, ProtobufMessageHandler {
68 private static final long serialVersionUID = 1L;
69 private static final QName IS_META = new QName(HTableDescriptor.IS_META);
70 private static final QName IS_ROOT = new QName(HTableDescriptor.IS_ROOT);
71 private static final QName READONLY = new QName(HTableDescriptor.READONLY);
72 private static final QName TTL = new QName(HColumnDescriptor.TTL);
73 private static final QName VERSIONS = new QName(HConstants.VERSIONS);
74 private static final QName COMPRESSION =
75 new QName(HColumnDescriptor.COMPRESSION);
76
77 private String name;
78 private Map<QName,Object> attrs = new LinkedHashMap<>();
79 private List<ColumnSchemaModel> columns = new ArrayList<>();
80
81
82
83
84 public TableSchemaModel() {}
85
86
87
88
89
90 public TableSchemaModel(HTableDescriptor htd) {
91 setName(htd.getTableName().getNameAsString());
92 for (Map.Entry<ImmutableBytesWritable, ImmutableBytesWritable> e : htd.getValues().entrySet()) {
93 addAttribute(Bytes.toString(e.getKey().get()),
94 Bytes.toString(e.getValue().get()));
95 }
96 for (HColumnDescriptor hcd : htd.getFamilies()) {
97 ColumnSchemaModel columnModel = new ColumnSchemaModel();
98 columnModel.setName(hcd.getNameAsString());
99 for (Map.Entry<ImmutableBytesWritable, ImmutableBytesWritable> e :
100 hcd.getValues().entrySet()) {
101 columnModel.addAttribute(Bytes.toString(e.getKey().get()),
102 Bytes.toString(e.getValue().get()));
103 }
104 addColumnFamily(columnModel);
105 }
106 }
107
108
109
110
111
112
113 @JsonAnySetter
114 public void addAttribute(String name, Object value) {
115 attrs.put(new QName(name), value);
116 }
117
118
119
120
121
122
123
124 public String getAttribute(String name) {
125 Object o = attrs.get(new QName(name));
126 return o != null ? o.toString() : null;
127 }
128
129
130
131
132
133 public void addColumnFamily(ColumnSchemaModel family) {
134 columns.add(family);
135 }
136
137
138
139
140
141
142 public ColumnSchemaModel getColumnFamily(int index) {
143 return columns.get(index);
144 }
145
146
147
148
149 @XmlAttribute
150 public String getName() {
151 return name;
152 }
153
154
155
156
157 @XmlAnyAttribute
158 @JsonAnyGetter
159 public Map<QName,Object> getAny() {
160 return attrs;
161 }
162
163
164
165
166 @XmlElement(name="ColumnSchema")
167 public List<ColumnSchemaModel> getColumns() {
168 return columns;
169 }
170
171
172
173
174 public void setName(String name) {
175 this.name = name;
176 }
177
178
179
180
181 public void setColumns(List<ColumnSchemaModel> columns) {
182 this.columns = columns;
183 }
184
185
186
187
188 @Override
189 public String toString() {
190 StringBuilder sb = new StringBuilder();
191 sb.append("{ NAME=> '");
192 sb.append(name);
193 sb.append('\'');
194 for (Map.Entry<QName,Object> e : attrs.entrySet()) {
195 sb.append(", ");
196 sb.append(e.getKey().getLocalPart());
197 sb.append(" => '");
198 sb.append(e.getValue().toString());
199 sb.append('\'');
200 }
201 sb.append(", COLUMNS => [ ");
202 Iterator<ColumnSchemaModel> i = columns.iterator();
203 while (i.hasNext()) {
204 ColumnSchemaModel family = i.next();
205 sb.append(family.toString());
206 if (i.hasNext()) {
207 sb.append(',');
208 }
209 sb.append(' ');
210 }
211 sb.append("] }");
212 return sb.toString();
213 }
214
215
216
217
218
219
220
221
222
223 public boolean __getIsMeta() {
224 Object o = attrs.get(IS_META);
225 return o != null && Boolean.parseBoolean(o.toString());
226 }
227
228
229
230
231 public boolean __getIsRoot() {
232 Object o = attrs.get(IS_ROOT);
233 return o != null && Boolean.parseBoolean(o.toString());
234 }
235
236
237
238
239 public boolean __getReadOnly() {
240 Object o = attrs.get(READONLY);
241 return o != null ? Boolean.parseBoolean(o.toString()) : HTableDescriptor.DEFAULT_READONLY;
242 }
243
244
245
246
247 public void __setIsMeta(boolean value) {
248 attrs.put(IS_META, Boolean.toString(value));
249 }
250
251
252
253
254 public void __setIsRoot(boolean value) {
255 attrs.put(IS_ROOT, Boolean.toString(value));
256 }
257
258
259
260
261 public void __setReadOnly(boolean value) {
262 attrs.put(READONLY, Boolean.toString(value));
263 }
264
265 @Override
266 public byte[] createProtobufOutput() {
267 TableSchema.Builder builder = TableSchema.newBuilder();
268 builder.setName(name);
269 for (Map.Entry<QName, Object> e : attrs.entrySet()) {
270 TableSchema.Attribute.Builder attrBuilder =
271 TableSchema.Attribute.newBuilder();
272 attrBuilder.setName(e.getKey().getLocalPart());
273 attrBuilder.setValue(e.getValue().toString());
274 builder.addAttrs(attrBuilder);
275 }
276 for (ColumnSchemaModel family : columns) {
277 Map<QName, Object> familyAttrs = family.getAny();
278 ColumnSchema.Builder familyBuilder = ColumnSchema.newBuilder();
279 familyBuilder.setName(family.getName());
280 for (Map.Entry<QName, Object> e : familyAttrs.entrySet()) {
281 ColumnSchema.Attribute.Builder attrBuilder =
282 ColumnSchema.Attribute.newBuilder();
283 attrBuilder.setName(e.getKey().getLocalPart());
284 attrBuilder.setValue(e.getValue().toString());
285 familyBuilder.addAttrs(attrBuilder);
286 }
287 if (familyAttrs.containsKey(TTL)) {
288 familyBuilder.setTtl(Integer.parseInt(familyAttrs.get(TTL).toString()));
289 }
290 if (familyAttrs.containsKey(VERSIONS)) {
291 familyBuilder.setMaxVersions(Integer.parseInt(familyAttrs.get(VERSIONS).toString()));
292 }
293 if (familyAttrs.containsKey(COMPRESSION)) {
294 familyBuilder.setCompression(familyAttrs.get(COMPRESSION).toString());
295 }
296 builder.addColumns(familyBuilder);
297 }
298 if (attrs.containsKey(READONLY)) {
299 builder.setReadOnly(Boolean.parseBoolean(attrs.get(READONLY).toString()));
300 }
301 return builder.build().toByteArray();
302 }
303
304 @Override
305 public ProtobufMessageHandler getObjectFromMessage(byte[] message)
306 throws IOException {
307 TableSchema.Builder builder = TableSchema.newBuilder();
308 ProtobufUtil.mergeFrom(builder, message);
309 this.setName(builder.getName());
310 for (TableSchema.Attribute attr : builder.getAttrsList()) {
311 this.addAttribute(attr.getName(), attr.getValue());
312 }
313 if (builder.hasReadOnly()) {
314 this.addAttribute(HTableDescriptor.READONLY, builder.getReadOnly());
315 }
316 for (ColumnSchema family : builder.getColumnsList()) {
317 ColumnSchemaModel familyModel = new ColumnSchemaModel();
318 familyModel.setName(family.getName());
319 for (ColumnSchema.Attribute attr : family.getAttrsList()) {
320 familyModel.addAttribute(attr.getName(), attr.getValue());
321 }
322 if (family.hasTtl()) {
323 familyModel.addAttribute(HColumnDescriptor.TTL, family.getTtl());
324 }
325 if (family.hasMaxVersions()) {
326 familyModel.addAttribute(HConstants.VERSIONS,
327 family.getMaxVersions());
328 }
329 if (family.hasCompression()) {
330 familyModel.addAttribute(HColumnDescriptor.COMPRESSION,
331 family.getCompression());
332 }
333 this.addColumnFamily(familyModel);
334 }
335 return this;
336 }
337
338
339
340
341 @JsonIgnore
342 public HTableDescriptor getTableDescriptor() {
343 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(getName()));
344 for (Map.Entry<QName, Object> e : getAny().entrySet()) {
345 htd.setValue(e.getKey().getLocalPart(), e.getValue().toString());
346 }
347 for (ColumnSchemaModel column : getColumns()) {
348 HColumnDescriptor hcd = new HColumnDescriptor(column.getName());
349 for (Map.Entry<QName, Object> e : column.getAny().entrySet()) {
350 hcd.setValue(e.getKey().getLocalPart(), e.getValue().toString());
351 }
352 htd.addFamily(hcd);
353 }
354 return htd;
355 }
356 }