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