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.client;
21
22 import java.io.IOException;
23 import java.io.InterruptedIOException;
24 import java.io.UnsupportedEncodingException;
25 import java.net.URLEncoder;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.TreeMap;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.hadoop.conf.Configuration;
37 import org.apache.hadoop.hbase.Cell;
38 import org.apache.hadoop.hbase.CellUtil;
39 import org.apache.hadoop.hbase.HBaseConfiguration;
40 import org.apache.hadoop.hbase.HConstants;
41 import org.apache.hadoop.hbase.HTableDescriptor;
42 import org.apache.hadoop.hbase.KeyValue;
43 import org.apache.hadoop.hbase.TableName;
44 import org.apache.hadoop.hbase.classification.InterfaceAudience;
45 import org.apache.hadoop.hbase.classification.InterfaceStability;
46 import org.apache.hadoop.hbase.client.Append;
47 import org.apache.hadoop.hbase.client.Delete;
48 import org.apache.hadoop.hbase.client.Durability;
49 import org.apache.hadoop.hbase.client.Get;
50 import org.apache.hadoop.hbase.client.Increment;
51 import org.apache.hadoop.hbase.client.Put;
52 import org.apache.hadoop.hbase.client.Result;
53 import org.apache.hadoop.hbase.client.ResultScanner;
54 import org.apache.hadoop.hbase.client.Row;
55 import org.apache.hadoop.hbase.client.RowMutations;
56 import org.apache.hadoop.hbase.client.Scan;
57 import org.apache.hadoop.hbase.client.Table;
58 import org.apache.hadoop.hbase.client.coprocessor.Batch;
59 import org.apache.hadoop.hbase.client.coprocessor.Batch.Callback;
60 import org.apache.hadoop.hbase.client.metrics.ScanMetrics;
61 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
62 import org.apache.hadoop.hbase.io.TimeRange;
63 import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel;
64 import org.apache.hadoop.hbase.rest.Constants;
65 import org.apache.hadoop.hbase.rest.model.CellModel;
66 import org.apache.hadoop.hbase.rest.model.CellSetModel;
67 import org.apache.hadoop.hbase.rest.model.RowModel;
68 import org.apache.hadoop.hbase.rest.model.ScannerModel;
69 import org.apache.hadoop.hbase.rest.model.TableSchemaModel;
70 import org.apache.hadoop.hbase.util.Bytes;
71 import org.apache.hadoop.util.StringUtils;
72
73 import com.google.protobuf.Descriptors;
74 import com.google.protobuf.Message;
75 import com.google.protobuf.Service;
76 import com.google.protobuf.ServiceException;
77
78
79
80
81 @InterfaceAudience.Public
82 @InterfaceStability.Stable
83 public class RemoteHTable implements Table {
84
85 private static final Log LOG = LogFactory.getLog(RemoteHTable.class);
86
87 final Client client;
88 final Configuration conf;
89 final byte[] name;
90 final int maxRetries;
91 final long sleepTime;
92
93 @SuppressWarnings("rawtypes")
94 protected String buildRowSpec(final byte[] row, final Map familyMap,
95 final long startTime, final long endTime, final int maxVersions) {
96 StringBuffer sb = new StringBuffer();
97 sb.append('/');
98 sb.append(Bytes.toString(name));
99 sb.append('/');
100 sb.append(toURLEncodedBytes(row));
101 Set families = familyMap.entrySet();
102 if (families != null) {
103 Iterator i = familyMap.entrySet().iterator();
104 sb.append('/');
105 while (i.hasNext()) {
106 Map.Entry e = (Map.Entry)i.next();
107 Collection quals = (Collection)e.getValue();
108 if (quals == null || quals.isEmpty()) {
109
110 sb.append(toURLEncodedBytes((byte[])e.getKey()));
111 } else {
112 Iterator ii = quals.iterator();
113 while (ii.hasNext()) {
114 sb.append(toURLEncodedBytes((byte[])e.getKey()));
115 Object o = ii.next();
116
117 if (o instanceof byte[]) {
118 sb.append(':');
119 sb.append(toURLEncodedBytes((byte[])o));
120 } else if (o instanceof KeyValue) {
121 if (((KeyValue) o).getQualifierLength() != 0) {
122 sb.append(':');
123 sb.append(toURLEncodedBytes(((KeyValue) o).getQualifier()));
124 }
125 } else {
126 throw new RuntimeException("object type not handled");
127 }
128 if (ii.hasNext()) {
129 sb.append(',');
130 }
131 }
132 }
133 if (i.hasNext()) {
134 sb.append(',');
135 }
136 }
137 }
138 if (startTime >= 0 && endTime != Long.MAX_VALUE) {
139 sb.append('/');
140 sb.append(startTime);
141 if (startTime != endTime) {
142 sb.append(',');
143 sb.append(endTime);
144 }
145 } else if (endTime != Long.MAX_VALUE) {
146 sb.append('/');
147 sb.append(endTime);
148 }
149 if (maxVersions > 1) {
150 sb.append("?v=");
151 sb.append(maxVersions);
152 }
153 return sb.toString();
154 }
155
156 protected String buildMultiRowSpec(final byte[][] rows, int maxVersions) {
157 StringBuilder sb = new StringBuilder();
158 sb.append('/');
159 sb.append(Bytes.toString(name));
160 sb.append("/multiget/");
161 if (rows == null || rows.length == 0) {
162 return sb.toString();
163 }
164 sb.append("?");
165 for(int i=0; i<rows.length; i++) {
166 byte[] rk = rows[i];
167 if (i != 0) {
168 sb.append('&');
169 }
170 sb.append("row=");
171 sb.append(toURLEncodedBytes(rk));
172 }
173 sb.append("&v=");
174 sb.append(maxVersions);
175
176 return sb.toString();
177 }
178
179 protected Result[] buildResultFromModel(final CellSetModel model) {
180 List<Result> results = new ArrayList<Result>();
181 for (RowModel row: model.getRows()) {
182 List<Cell> kvs = new ArrayList<Cell>();
183 for (CellModel cell: row.getCells()) {
184 byte[][] split = KeyValue.parseColumn(cell.getColumn());
185 byte[] column = split[0];
186 byte[] qualifier = null;
187 if (split.length == 1) {
188 qualifier = HConstants.EMPTY_BYTE_ARRAY;
189 } else if (split.length == 2) {
190 qualifier = split[1];
191 } else {
192 throw new IllegalArgumentException("Invalid familyAndQualifier provided.");
193 }
194 kvs.add(new KeyValue(row.getKey(), column, qualifier,
195 cell.getTimestamp(), cell.getValue()));
196 }
197 results.add(Result.create(kvs));
198 }
199 return results.toArray(new Result[results.size()]);
200 }
201
202 protected CellSetModel buildModelFromPut(Put put) {
203 RowModel row = new RowModel(put.getRow());
204 long ts = put.getTimeStamp();
205 for (List<Cell> cells: put.getFamilyCellMap().values()) {
206 for (Cell cell: cells) {
207 row.addCell(new CellModel(CellUtil.cloneFamily(cell), CellUtil.cloneQualifier(cell),
208 ts != HConstants.LATEST_TIMESTAMP ? ts : cell.getTimestamp(),
209 CellUtil.cloneValue(cell)));
210 }
211 }
212 CellSetModel model = new CellSetModel();
213 model.addRow(row);
214 return model;
215 }
216
217
218
219
220 public RemoteHTable(Client client, String name) {
221 this(client, HBaseConfiguration.create(), Bytes.toBytes(name));
222 }
223
224
225
226
227 public RemoteHTable(Client client, Configuration conf, String name) {
228 this(client, conf, Bytes.toBytes(name));
229 }
230
231
232
233
234 public RemoteHTable(Client client, Configuration conf, byte[] name) {
235 this.client = client;
236 this.conf = conf;
237 this.name = name;
238 this.maxRetries = conf.getInt("hbase.rest.client.max.retries", 10);
239 this.sleepTime = conf.getLong("hbase.rest.client.sleep", 1000);
240 }
241
242 public byte[] getTableName() {
243 return name.clone();
244 }
245
246 @Override
247 public TableName getName() {
248 return TableName.valueOf(name);
249 }
250
251 @Override
252 public Configuration getConfiguration() {
253 return conf;
254 }
255
256 @Override
257 public HTableDescriptor getTableDescriptor() throws IOException {
258 StringBuilder sb = new StringBuilder();
259 sb.append('/');
260 sb.append(Bytes.toString(name));
261 sb.append('/');
262 sb.append("schema");
263 for (int i = 0; i < maxRetries; i++) {
264 Response response = client.get(sb.toString(), Constants.MIMETYPE_PROTOBUF);
265 int code = response.getCode();
266 switch (code) {
267 case 200:
268 TableSchemaModel schema = new TableSchemaModel();
269 schema.getObjectFromMessage(response.getBody());
270 return schema.getTableDescriptor();
271 case 509:
272 try {
273 Thread.sleep(sleepTime);
274 } catch (InterruptedException e) {
275 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
276 }
277 break;
278 default:
279 throw new IOException("schema request returned " + code);
280 }
281 }
282 throw new IOException("schema request timed out");
283 }
284
285 @Override
286 public void close() throws IOException {
287 client.shutdown();
288 }
289
290 @Override
291 public Result get(Get get) throws IOException {
292 TimeRange range = get.getTimeRange();
293 String spec = buildRowSpec(get.getRow(), get.getFamilyMap(),
294 range.getMin(), range.getMax(), get.getMaxVersions());
295 if (get.getFilter() != null) {
296 LOG.warn("filters not supported on gets");
297 }
298 Result[] results = getResults(spec);
299 if (results.length > 0) {
300 if (results.length > 1) {
301 LOG.warn("too many results for get (" + results.length + ")");
302 }
303 return results[0];
304 } else {
305 return new Result();
306 }
307 }
308
309 @Override
310 public Result[] get(List<Get> gets) throws IOException {
311 byte[][] rows = new byte[gets.size()][];
312 int maxVersions = 1;
313 int count = 0;
314
315 for(Get g:gets) {
316
317 if ( count == 0 ) {
318 maxVersions = g.getMaxVersions();
319 } else if (g.getMaxVersions() != maxVersions) {
320 LOG.warn("MaxVersions on Gets do not match, using the first in the list ("+maxVersions+")");
321 }
322
323 if (g.getFilter() != null) {
324 LOG.warn("filters not supported on gets");
325 }
326
327 rows[count] = g.getRow();
328 count ++;
329 }
330
331 String spec = buildMultiRowSpec(rows, maxVersions);
332
333 return getResults(spec);
334 }
335
336 private Result[] getResults(String spec) throws IOException {
337 for (int i = 0; i < maxRetries; i++) {
338 Response response = client.get(spec, Constants.MIMETYPE_PROTOBUF);
339 int code = response.getCode();
340 switch (code) {
341 case 200:
342 CellSetModel model = new CellSetModel();
343 model.getObjectFromMessage(response.getBody());
344 Result[] results = buildResultFromModel(model);
345 if ( results.length > 0) {
346 return results;
347 }
348
349 case 404:
350 return new Result[0];
351
352 case 509:
353 try {
354 Thread.sleep(sleepTime);
355 } catch (InterruptedException e) {
356 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
357 }
358 break;
359 default:
360 throw new IOException("get request returned " + code);
361 }
362 }
363 throw new IOException("get request timed out");
364 }
365
366 @Override
367 public boolean exists(Get get) throws IOException {
368 LOG.warn("exists() is really get(), just use get()");
369 Result result = get(get);
370 return (result != null && !(result.isEmpty()));
371 }
372
373
374
375
376
377 @Override
378 public boolean[] existsAll(List<Get> gets) throws IOException {
379 LOG.warn("exists(List<Get>) is really list of get() calls, just use get()");
380 boolean[] results = new boolean[gets.size()];
381 for (int i = 0; i < results.length; i++) {
382 results[i] = exists(gets.get(i));
383 }
384 return results;
385 }
386
387 @Deprecated
388 public Boolean[] exists(List<Get> gets) throws IOException {
389 boolean[] results = existsAll(gets);
390 Boolean[] objectResults = new Boolean[results.length];
391 for (int i = 0; i < results.length; ++i) {
392 objectResults[i] = results[i];
393 }
394 return objectResults;
395 }
396
397 @Override
398 public void put(Put put) throws IOException {
399 CellSetModel model = buildModelFromPut(put);
400 StringBuilder sb = new StringBuilder();
401 sb.append('/');
402 sb.append(Bytes.toString(name));
403 sb.append('/');
404 sb.append(toURLEncodedBytes(put.getRow()));
405 for (int i = 0; i < maxRetries; i++) {
406 Response response = client.put(sb.toString(), Constants.MIMETYPE_PROTOBUF,
407 model.createProtobufOutput());
408 int code = response.getCode();
409 switch (code) {
410 case 200:
411 return;
412 case 509:
413 try {
414 Thread.sleep(sleepTime);
415 } catch (InterruptedException e) {
416 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
417 }
418 break;
419 default:
420 throw new IOException("put request failed with " + code);
421 }
422 }
423 throw new IOException("put request timed out");
424 }
425
426 @Override
427 public void put(List<Put> puts) throws IOException {
428
429
430
431
432 TreeMap<byte[],List<Cell>> map =
433 new TreeMap<byte[],List<Cell>>(Bytes.BYTES_COMPARATOR);
434 for (Put put: puts) {
435 byte[] row = put.getRow();
436 List<Cell> cells = map.get(row);
437 if (cells == null) {
438 cells = new ArrayList<Cell>();
439 map.put(row, cells);
440 }
441 for (List<Cell> l: put.getFamilyCellMap().values()) {
442 cells.addAll(l);
443 }
444 }
445
446
447 CellSetModel model = new CellSetModel();
448 for (Map.Entry<byte[], List<Cell>> e: map.entrySet()) {
449 RowModel row = new RowModel(e.getKey());
450 for (Cell cell: e.getValue()) {
451 row.addCell(new CellModel(cell));
452 }
453 model.addRow(row);
454 }
455
456
457 StringBuilder sb = new StringBuilder();
458 sb.append('/');
459 sb.append(Bytes.toString(name));
460 sb.append("/$multiput");
461 for (int i = 0; i < maxRetries; i++) {
462 Response response = client.put(sb.toString(), Constants.MIMETYPE_PROTOBUF,
463 model.createProtobufOutput());
464 int code = response.getCode();
465 switch (code) {
466 case 200:
467 return;
468 case 509:
469 try {
470 Thread.sleep(sleepTime);
471 } catch (InterruptedException e) {
472 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
473 }
474 break;
475 default:
476 throw new IOException("multiput request failed with " + code);
477 }
478 }
479 throw new IOException("multiput request timed out");
480 }
481
482 @Override
483 public void delete(Delete delete) throws IOException {
484 String spec = buildRowSpec(delete.getRow(), delete.getFamilyCellMap(),
485 delete.getTimeStamp(), delete.getTimeStamp(), 1);
486 for (int i = 0; i < maxRetries; i++) {
487 Response response = client.delete(spec);
488 int code = response.getCode();
489 switch (code) {
490 case 200:
491 return;
492 case 509:
493 try {
494 Thread.sleep(sleepTime);
495 } catch (InterruptedException e) {
496 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
497 }
498 break;
499 default:
500 throw new IOException("delete request failed with " + code);
501 }
502 }
503 throw new IOException("delete request timed out");
504 }
505
506 @Override
507 public void delete(List<Delete> deletes) throws IOException {
508 for (Delete delete: deletes) {
509 delete(delete);
510 }
511 }
512
513 public void flushCommits() throws IOException {
514
515 }
516
517 class Scanner implements ResultScanner {
518
519 String uri;
520
521 public Scanner(Scan scan) throws IOException {
522 ScannerModel model;
523 try {
524 model = ScannerModel.fromScan(scan);
525 } catch (Exception e) {
526 throw new IOException(e);
527 }
528 StringBuffer sb = new StringBuffer();
529 sb.append('/');
530 sb.append(Bytes.toString(name));
531 sb.append('/');
532 sb.append("scanner");
533 for (int i = 0; i < maxRetries; i++) {
534 Response response = client.post(sb.toString(),
535 Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
536 int code = response.getCode();
537 switch (code) {
538 case 201:
539 uri = response.getLocation();
540 return;
541 case 509:
542 try {
543 Thread.sleep(sleepTime);
544 } catch (InterruptedException e) {
545 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
546 }
547 break;
548 default:
549 throw new IOException("scan request failed with " + code);
550 }
551 }
552 throw new IOException("scan request timed out");
553 }
554
555 @Override
556 public Result[] next(int nbRows) throws IOException {
557 StringBuilder sb = new StringBuilder(uri);
558 sb.append("?n=");
559 sb.append(nbRows);
560 for (int i = 0; i < maxRetries; i++) {
561 Response response = client.get(sb.toString(),
562 Constants.MIMETYPE_PROTOBUF);
563 int code = response.getCode();
564 switch (code) {
565 case 200:
566 CellSetModel model = new CellSetModel();
567 model.getObjectFromMessage(response.getBody());
568 return buildResultFromModel(model);
569 case 204:
570 case 206:
571 return null;
572 case 509:
573 try {
574 Thread.sleep(sleepTime);
575 } catch (InterruptedException e) {
576 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
577 }
578 break;
579 default:
580 throw new IOException("scanner.next request failed with " + code);
581 }
582 }
583 throw new IOException("scanner.next request timed out");
584 }
585
586 @Override
587 public Result next() throws IOException {
588 Result[] results = next(1);
589 if (results == null || results.length < 1) {
590 return null;
591 }
592 return results[0];
593 }
594
595 class Iter implements Iterator<Result> {
596
597 Result cache;
598
599 public Iter() {
600 try {
601 cache = Scanner.this.next();
602 } catch (IOException e) {
603 LOG.warn(StringUtils.stringifyException(e));
604 }
605 }
606
607 @Override
608 public boolean hasNext() {
609 return cache != null;
610 }
611
612 @Override
613 public Result next() {
614 Result result = cache;
615 try {
616 cache = Scanner.this.next();
617 } catch (IOException e) {
618 LOG.warn(StringUtils.stringifyException(e));
619 cache = null;
620 }
621 return result;
622 }
623
624 @Override
625 public void remove() {
626 throw new RuntimeException("remove() not supported");
627 }
628
629 }
630
631 @Override
632 public Iterator<Result> iterator() {
633 return new Iter();
634 }
635
636 @Override
637 public void close() {
638 try {
639 client.delete(uri);
640 } catch (IOException e) {
641 LOG.warn(StringUtils.stringifyException(e));
642 }
643 }
644
645 @Override
646 public boolean renewLease() {
647 throw new RuntimeException("renewLease() not supported");
648 }
649
650 @Override
651 public ScanMetrics getScanMetrics() {
652 throw new RuntimeException("getScanMetrics() not supported");
653 }
654 }
655
656 @Override
657 public ResultScanner getScanner(Scan scan) throws IOException {
658 return new Scanner(scan);
659 }
660
661 @Override
662 public ResultScanner getScanner(byte[] family) throws IOException {
663 Scan scan = new Scan();
664 scan.addFamily(family);
665 return new Scanner(scan);
666 }
667
668 @Override
669 public ResultScanner getScanner(byte[] family, byte[] qualifier)
670 throws IOException {
671 Scan scan = new Scan();
672 scan.addColumn(family, qualifier);
673 return new Scanner(scan);
674 }
675
676 public boolean isAutoFlush() {
677 return true;
678 }
679
680 public Result getRowOrBefore(byte[] row, byte[] family) throws IOException {
681 throw new IOException("getRowOrBefore not supported");
682 }
683
684 @Override
685 public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
686 byte[] value, Put put) throws IOException {
687
688 put.add(new KeyValue(row, family, qualifier, value));
689
690 CellSetModel model = buildModelFromPut(put);
691 StringBuilder sb = new StringBuilder();
692 sb.append('/');
693 sb.append(Bytes.toString(name));
694 sb.append('/');
695 sb.append(toURLEncodedBytes(put.getRow()));
696 sb.append("?check=put");
697
698 for (int i = 0; i < maxRetries; i++) {
699 Response response = client.put(sb.toString(),
700 Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
701 int code = response.getCode();
702 switch (code) {
703 case 200:
704 return true;
705 case 304:
706 return false;
707 case 509:
708 try {
709 Thread.sleep(sleepTime);
710 } catch (final InterruptedException e) {
711 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
712 }
713 break;
714 default:
715 throw new IOException("checkAndPut request failed with " + code);
716 }
717 }
718 throw new IOException("checkAndPut request timed out");
719 }
720
721 @Override
722 public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier,
723 CompareOp compareOp, byte[] value, Put put) throws IOException {
724 throw new IOException("checkAndPut for non-equal comparison not implemented");
725 }
726
727 @Override
728 public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
729 byte[] value, Delete delete) throws IOException {
730 Put put = new Put(row);
731 put.setFamilyCellMap(delete.getFamilyCellMap());
732
733 put.add(new KeyValue(row, family, qualifier, value));
734 CellSetModel model = buildModelFromPut(put);
735 StringBuilder sb = new StringBuilder();
736 sb.append('/');
737 sb.append(Bytes.toString(name));
738 sb.append('/');
739 sb.append(toURLEncodedBytes(row));
740 sb.append("?check=delete");
741
742 for (int i = 0; i < maxRetries; i++) {
743 Response response = client.put(sb.toString(),
744 Constants.MIMETYPE_PROTOBUF, model.createProtobufOutput());
745 int code = response.getCode();
746 switch (code) {
747 case 200:
748 return true;
749 case 304:
750 return false;
751 case 509:
752 try {
753 Thread.sleep(sleepTime);
754 } catch (final InterruptedException e) {
755 throw (InterruptedIOException)new InterruptedIOException().initCause(e);
756 }
757 break;
758 default:
759 throw new IOException("checkAndDelete request failed with " + code);
760 }
761 }
762 throw new IOException("checkAndDelete request timed out");
763 }
764
765 @Override
766 public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier,
767 CompareOp compareOp, byte[] value, Delete delete) throws IOException {
768 throw new IOException("checkAndDelete for non-equal comparison not implemented");
769 }
770
771 @Override
772 public Result increment(Increment increment) throws IOException {
773 throw new IOException("Increment not supported");
774 }
775
776 @Override
777 public Result append(Append append) throws IOException {
778 throw new IOException("Append not supported");
779 }
780
781 @Override
782 public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier,
783 long amount) throws IOException {
784 throw new IOException("incrementColumnValue not supported");
785 }
786
787 @Override
788 public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier,
789 long amount, Durability durability) throws IOException {
790 throw new IOException("incrementColumnValue not supported");
791 }
792
793 @Override
794 public void batch(List<? extends Row> actions, Object[] results) throws IOException {
795 throw new IOException("batch not supported");
796 }
797
798 @Override
799 public Object[] batch(List<? extends Row> actions) throws IOException {
800 throw new IOException("batch not supported");
801 }
802
803 @Override
804 public <R> void batchCallback(List<? extends Row> actions, Object[] results,
805 Batch.Callback<R> callback) throws IOException, InterruptedException {
806 throw new IOException("batchCallback not supported");
807 }
808
809 @Override
810 public <R> Object[] batchCallback(List<? extends Row> actions, Batch.Callback<R> callback)
811 throws IOException, InterruptedException {
812 throw new IOException("batchCallback not supported");
813 }
814
815 @Override
816 public CoprocessorRpcChannel coprocessorService(byte[] row) {
817 throw new UnsupportedOperationException("coprocessorService not implemented");
818 }
819
820 @Override
821 public <T extends Service, R> Map<byte[], R> coprocessorService(Class<T> service,
822 byte[] startKey, byte[] endKey, Batch.Call<T, R> callable)
823 throws ServiceException, Throwable {
824 throw new UnsupportedOperationException("coprocessorService not implemented");
825 }
826
827 @Override
828 public <T extends Service, R> void coprocessorService(Class<T> service,
829 byte[] startKey, byte[] endKey, Batch.Call<T, R> callable, Batch.Callback<R> callback)
830 throws ServiceException, Throwable {
831 throw new UnsupportedOperationException("coprocessorService not implemented");
832 }
833
834 @Override
835 public void mutateRow(RowMutations rm) throws IOException {
836 throw new IOException("atomicMutation not supported");
837 }
838
839 @Override
840 public long getWriteBufferSize() {
841 throw new UnsupportedOperationException("getWriteBufferSize not implemented");
842 }
843
844 @Override
845 public void setWriteBufferSize(long writeBufferSize) throws IOException {
846 throw new IOException("setWriteBufferSize not supported");
847 }
848
849 @Override
850 public <R extends Message> Map<byte[], R> batchCoprocessorService(
851 Descriptors.MethodDescriptor method, Message request,
852 byte[] startKey, byte[] endKey, R responsePrototype) throws ServiceException, Throwable {
853 throw new UnsupportedOperationException("batchCoprocessorService not implemented");
854 }
855
856 @Override
857 public <R extends Message> void batchCoprocessorService(
858 Descriptors.MethodDescriptor method, Message request,
859 byte[] startKey, byte[] endKey, R responsePrototype, Callback<R> callback)
860 throws ServiceException, Throwable {
861 throw new UnsupportedOperationException("batchCoprocessorService not implemented");
862 }
863
864 @Override public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier,
865 CompareOp compareOp, byte[] value, RowMutations rm) throws IOException {
866 throw new UnsupportedOperationException("checkAndMutate not implemented");
867 }
868
869 @Override public void setOperationTimeout(int operationTimeout) {
870 throw new UnsupportedOperationException();
871 }
872
873 @Override public int getOperationTimeout() {
874 throw new UnsupportedOperationException();
875 }
876
877 @Override
878 @Deprecated
879 public void setRpcTimeout(int rpcTimeout) {
880 throw new UnsupportedOperationException();
881 }
882
883 @Override
884 @Deprecated
885 public int getRpcTimeout() {
886 throw new UnsupportedOperationException();
887 }
888
889 @Override
890 public int getReadRpcTimeout() {
891 throw new UnsupportedOperationException();
892 }
893
894 @Override
895 public void setReadRpcTimeout(int readRpcTimeout) {
896 throw new UnsupportedOperationException();
897 }
898
899 @Override
900 public int getWriteRpcTimeout() {
901 throw new UnsupportedOperationException();
902 }
903
904 @Override
905 public void setWriteRpcTimeout(int writeRpcTimeout) {
906 throw new UnsupportedOperationException();
907 }
908
909
910
911
912
913
914
915
916 private static String toURLEncodedBytes(byte[] row) {
917 try {
918 return URLEncoder.encode(new String(row, "UTF-8"), "UTF-8");
919 } catch (UnsupportedEncodingException e) {
920 throw new IllegalStateException("URLEncoder doesn't support UTF-8", e);
921 }
922 }
923 }