All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.kstore.KafkaStoreTable Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/*
 * This file is licensed to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 * 

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ package io.kstore; import com.google.protobuf.Descriptors; import com.google.protobuf.Message; import com.google.protobuf.Service; import com.google.protobuf.ServiceException; import io.kcache.Cache; import io.kcache.KeyValueIterator; import io.kstore.schema.KafkaSchemaValue; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.Cell; import org.apache.hadoop.hbase.CellUtil; import org.apache.hadoop.hbase.CompareOperator; import org.apache.hadoop.hbase.HConstants; import org.apache.hadoop.hbase.HRegionLocation; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.KeyValue; import org.apache.hadoop.hbase.ServerName; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Append; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Durability; import org.apache.hadoop.hbase.client.Get; import org.apache.hadoop.hbase.client.Increment; import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.client.RegionLocator; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Row; import org.apache.hadoop.hbase.client.RowMutations; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.client.TableDescriptor; import org.apache.hadoop.hbase.client.coprocessor.Batch; import org.apache.hadoop.hbase.client.metrics.ScanMetrics; import org.apache.hadoop.hbase.filter.CompareFilter; import org.apache.hadoop.hbase.filter.Filter; import org.apache.hadoop.hbase.io.TimeRange; import org.apache.hadoop.hbase.ipc.CoprocessorRpcChannel; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.Pair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.NavigableMap; import java.util.NavigableSet; import java.util.NoSuchElementException; import java.util.TreeMap; public abstract class KafkaStoreTable implements Table { private static final Logger LOG = LoggerFactory.getLogger(KafkaStoreTable.class); private final KafkaStoreConnection conn; private final TableName tableName; private final KafkaTableCache cache; private final Cache>>> data; public KafkaStoreTable(Configuration config, KafkaStoreConnection conn, KafkaSchemaValue schemaValue) { this.conn = conn; this.tableName = TableName.valueOf(schemaValue.getTableName()); this.cache = new KafkaTableCache(config, schemaValue); this.data = cache.getRows(); } public KafkaTableCache getCache() { return cache; } /** * {@inheritDoc} */ @Override public TableName getName() { return tableName; } /** * {@inheritDoc} */ @Override public Configuration getConfiguration() { return conn.getConfiguration(); } /** * {@inheritDoc} */ @Override public HTableDescriptor getTableDescriptor() throws IOException { TableDescriptor descriptor = this.getDescriptor(); return descriptor instanceof HTableDescriptor ? (HTableDescriptor)descriptor : new HTableDescriptor(descriptor); } /** * {@inheritDoc} */ @Override public TableDescriptor getDescriptor() throws IOException { return conn.getLatestSchemaValue(tableName).getSchema().toDesc(); } /** * {@inheritDoc} */ @Override public void mutateRow(RowMutations rm) throws IOException { for (Mutation mutation : rm.getMutations()) { if (mutation instanceof Put) { put((Put) mutation); } else if (mutation instanceof Delete) { delete((Delete) mutation); } else if (mutation instanceof Increment) { increment((Increment) mutation); } else if (mutation instanceof Append) { append((Append) mutation); } } } /** * {@inheritDoc} */ @Override public Result append(Append append) throws IOException { throw new UnsupportedOperationException("append"); } private static List toKeyValue(byte[] row, NavigableMap>> rowdata, TimeRange timeRange, Map familyTimeRanges, int maxVersions) { List ret = new ArrayList<>(); for (Map.Entry>> entry : rowdata.entrySet()) { byte[] family = entry.getKey(); TimeRange familyTimeRange = familyTimeRanges.get(family); if (familyTimeRange == null) familyTimeRange = timeRange; for (Map.Entry> innerEntry : entry.getValue().entrySet()) { byte[] qualifier = innerEntry.getKey(); int versionsAdded = 0; for (Map.Entry tsToVal : innerEntry.getValue().descendingMap().entrySet()) { if (versionsAdded == maxVersions) break; Long timestamp = tsToVal.getKey(); if (!familyTimeRange.withinTimeRange(timestamp)) continue; byte[] value = tsToVal.getValue(); ret.add(new KeyValue(row, family, qualifier, timestamp, value)); versionsAdded++; } } } return ret; } /** * {@inheritDoc} */ @Override public boolean exists(Get get) throws IOException { Result result = get(get); return result != null && !result.isEmpty(); } /** * {@inheritDoc} */ @Override public boolean[] exists(List gets) throws IOException { boolean[] result = new boolean[gets.size()]; for (int i = 0; i < gets.size(); i++) { result[i] = exists(gets.get(i)); } return result; } /** * {@inheritDoc} */ @Override public void batch(List actions, Object[] results) throws IOException, InterruptedException { Object[] rows = batch(actions); if (results != null) { System.arraycopy(rows, 0, results, 0, rows.length); } } /** * {@inheritDoc} */ public Object[] batch(List actions) throws IOException, InterruptedException { Object[] results = new Object[actions.size()]; // same size. for (int i = 0; i < actions.size(); i++) { Row r = actions.get(i); if (r instanceof Delete) { delete((Delete) r); results[i] = new Result(); } if (r instanceof Put) { put((Put) r); results[i] = new Result(); } if (r instanceof Get) { Result result = get((Get) r); results[i] = result; } if (r instanceof Increment) { Result result = increment((Increment) r); results[i] = result; } if (r instanceof Append) { Result result = append((Append) r); results[i] = result; } } return results; } /** * {@inheritDoc} */ @Override public void batchCallback( final List actions, final Object[] results, final Batch.Callback callback) throws IOException, InterruptedException { throw new UnsupportedOperationException("batchCallback"); } /** * {@inheritDoc} */ @Override public Result get(Get get) throws IOException { byte[] row = get.getRow(); NavigableMap>> rowData = data.get(row); if (rowData == null) { return new Result(); } List kvs = new ArrayList<>(); Filter filter = get.getFilter(); int maxResults = get.getMaxResultsPerColumnFamily(); if (!get.hasFamilies()) { kvs = toKeyValue(row, rowData, get.getTimeRange(), get.getColumnFamilyTimeRange(), get.getMaxVersions()); if (filter != null) { kvs = filter(filter, kvs); } if (maxResults >= 0 && kvs.size() > maxResults) { kvs = kvs.subList(0, maxResults); } } else { for (Map.Entry> entry : get.getFamilyMap().entrySet()) { byte[] family = entry.getKey(); NavigableMap> familyData = rowData.get(family); if (familyData == null) continue; NavigableSet qualifiers = entry.getValue(); if (qualifiers == null || qualifiers.isEmpty()) qualifiers = familyData.navigableKeySet(); List familyKvs = new ArrayList<>(); TimeRange familyTimeRange = get.getColumnFamilyTimeRange().get(family); if (familyTimeRange == null) familyTimeRange = get.getTimeRange(); for (byte[] qualifier : qualifiers) { if (familyData.get(qualifier) == null) continue; List tsKvs = new ArrayList<>(); for (Map.Entry innerMostEntry : familyData.get(qualifier).descendingMap().entrySet()) { Long timestamp = innerMostEntry.getKey(); if (!familyTimeRange.withinTimeRange(timestamp)) continue; byte[] value = innerMostEntry.getValue(); tsKvs.add(new KeyValue(row, family, qualifier, timestamp, value)); if (tsKvs.size() == get.getMaxVersions()) { break; } } familyKvs.addAll(tsKvs); } if (filter != null) { familyKvs = filter(filter, familyKvs); } if (maxResults >= 0 && familyKvs.size() > maxResults) { familyKvs = familyKvs.subList(0, maxResults); } kvs.addAll(familyKvs); } } return Result.create(kvs); } /** * {@inheritDoc} */ @Override public Result[] get(List gets) throws IOException { List results = new ArrayList<>(); for (Get g : gets) { results.add(get(g)); } return results.toArray(new Result[0]); } /** * {@inheritDoc} */ @Override public ResultScanner getScanner(Scan scan) throws IOException { final List ret = new ArrayList<>(); byte[] st = scan.getStartRow(); if (st.length == 0) st = null; byte[] sp = scan.getStopRow(); if (sp.length == 0) sp = null; Filter filter = scan.getFilter(); int maxResults = scan.getMaxResultsPerColumnFamily(); Cache>>> subData = scan.isReversed() ? data.descendingCache() : data; if (st != null || sp != null) { boolean includeStopRow = scan.includeStopRow(); if (st != null && sp != null && Arrays.equals(st, sp)) { includeStopRow = true; } subData = subData.subCache(st, scan.includeStartRow(), sp, includeStopRow); } KeyValueIterator>>> iter = subData.all(); while (iter.hasNext()) { io.kcache.KeyValue>>> entry = iter.next(); byte[] row = entry.key; NavigableMap>> rowData = entry.value; List kvs; if (!scan.hasFamilies()) { kvs = toKeyValue(row, rowData, scan.getTimeRange(), scan.getColumnFamilyTimeRange(), scan.getMaxVersions()); if (filter != null) { kvs = filter(filter, kvs); } if (maxResults >= 0 && kvs.size() > maxResults) { kvs = kvs.subList(0, maxResults); } } else { kvs = new ArrayList<>(); for (Map.Entry> innerEntry : scan.getFamilyMap().entrySet()) { byte[] family = innerEntry.getKey(); NavigableMap> familyData = rowData.get(family); if (familyData == null) continue; NavigableSet qualifiers = innerEntry.getValue(); if (qualifiers == null || qualifiers.isEmpty()) qualifiers = familyData.navigableKeySet(); List familyKvs = new ArrayList<>(); TimeRange familyTimeRange = scan.getColumnFamilyTimeRange().get(family); if (familyTimeRange == null) familyTimeRange = scan.getTimeRange(); for (byte[] qualifier : qualifiers) { if (familyData.get(qualifier) == null) continue; List tsKvs = new ArrayList<>(); for (Map.Entry innerMostEntry : familyData.get(qualifier).descendingMap().entrySet()) { Long timestamp = innerMostEntry.getKey(); if (!familyTimeRange.withinTimeRange(timestamp)) continue; byte[] value = innerMostEntry.getValue(); tsKvs.add(new KeyValue(row, family, qualifier, timestamp, value)); if (tsKvs.size() == scan.getMaxVersions()) { break; } } familyKvs.addAll(tsKvs); } if (filter != null) { familyKvs = filter(filter, familyKvs); } if (maxResults >= 0 && familyKvs.size() > maxResults) { familyKvs = familyKvs.subList(0, maxResults); } kvs.addAll(familyKvs); } } if (!kvs.isEmpty()) { ret.add(Result.create(kvs)); } // Check for early out optimization if (filter != null && filter.filterAllRemaining()) { break; } } iter.close(); return new ResultScanner() { private final Iterator iterator = ret.iterator(); public Iterator iterator() { return iterator; } public Result[] next(int nbRows) throws IOException { ArrayList resultSets = new ArrayList<>(nbRows); for (int i = 0; i < nbRows; i++) { Result next = next(); if (next != null) { resultSets.add(next); } else { break; } } return resultSets.toArray(new Result[0]); } public Result next() throws IOException { try { return iterator().next(); } catch (NoSuchElementException e) { return null; } } public void close() { } public ScanMetrics getScanMetrics() { return null; } public boolean renewLease() { return false; } }; } /** * Follows the logical flow through the filter methods for a single row. * * @param filter HBase filter. * @param kvs List of a row's KeyValues * @return List of KeyValues that were not filtered. */ private List filter(Filter filter, List kvs) throws IOException { filter.reset(); List tmp = new ArrayList<>(kvs.size()); tmp.addAll(kvs); /* * Note. Filter flow for a single row. Adapted from * "HBase: The Definitive Guide" (p. 163) by Lars George, 2011. * See Figure 4-2 on p. 163. */ boolean filteredOnRowKey = false; List nkvs = new ArrayList<>(tmp.size()); for (Cell kv : tmp) { if (filter.filterRowKey(kv)) { filteredOnRowKey = true; break; } Filter.ReturnCode filterResult = filter.filterCell(kv); if (filterResult == Filter.ReturnCode.INCLUDE || filterResult == Filter.ReturnCode.INCLUDE_AND_NEXT_COL) { nkvs.add(filter.transformCell(kv)); } else if (filterResult == Filter.ReturnCode.NEXT_ROW) { break; } else if (filterResult == Filter.ReturnCode.NEXT_COL || filterResult == Filter.ReturnCode.SKIP) { //noinspection UnnecessaryContinue continue; } /* * Ignoring next key hint which is a optimization to reduce file * system IO */ } if (filter.hasFilterRow() && !filteredOnRowKey) { filter.filterRowCells(nkvs); } if (filter.filterRow() || filteredOnRowKey) { nkvs.clear(); } tmp = nkvs; return tmp; } /** * {@inheritDoc} */ @Override public ResultScanner getScanner(byte[] family) throws IOException { Scan scan = new Scan(); scan.addFamily(family); return getScanner(scan); } /** * {@inheritDoc} */ @Override public ResultScanner getScanner(byte[] family, byte[] qualifier) throws IOException { Scan scan = new Scan(); scan.addColumn(family, qualifier); return getScanner(scan); } /** * {@inheritDoc} */ @Override public void put(Put put) throws IOException { byte[] row = put.getRow(); NavigableMap>> rowData = data.computeIfAbsent(row, k -> new TreeMap<>(Bytes.BYTES_COMPARATOR)); for (Map.Entry> entry : put.getFamilyCellMap().entrySet()) { byte[] family = entry.getKey(); NavigableMap> familyData = rowData.computeIfAbsent(family, k -> new TreeMap<>(Bytes.BYTES_COMPARATOR)); for (Cell kv : entry.getValue()) { long ts = kv.getTimestamp(); if (ts == HConstants.LATEST_TIMESTAMP) { ts = put.getTimestamp(); } if (ts == HConstants.LATEST_TIMESTAMP) { ts = System.currentTimeMillis(); } byte[] qualifier = CellUtil.cloneQualifier(kv); NavigableMap qualifierData = familyData.computeIfAbsent(qualifier, k -> new TreeMap<>()); qualifierData.put(ts, CellUtil.cloneValue(kv)); } } data.put(row, rowData); data.flush(); } /** * {@inheritDoc} */ @Override public void put(List puts) throws IOException { for (Put put : puts) { put(put); } } private boolean check(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, byte[] value) { return check(row, family, qualifier, compareOp, value, TimeRange.allTime()); } private boolean check(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, byte[] value, TimeRange timeRange) { NavigableMap>> rowData = data.get(row); if (value == null) return rowData == null || !rowData.containsKey(family) || !rowData.get(family).containsKey(qualifier) || rowData.get(family).get(qualifier).subMap(timeRange.getMin(), true, timeRange.getMax(), false).isEmpty(); else if (rowData != null && rowData.containsKey(family) && rowData.get(family).containsKey(qualifier) && !rowData.get(family).get(qualifier).subMap(timeRange.getMin(), true, timeRange.getMax(), false).isEmpty()) { byte[] oldValue = rowData.get(family).get(qualifier).subMap(timeRange.getMin(), true, timeRange.getMax(), false).lastEntry().getValue(); int compareResult = Bytes.compareTo(value, oldValue); switch (compareOp) { case LESS: return compareResult < 0; case LESS_OR_EQUAL: return compareResult <= 0; case EQUAL: return compareResult == 0; case NOT_EQUAL: return compareResult != 0; case GREATER_OR_EQUAL: return compareResult >= 0; case GREATER: return compareResult > 0; default: throw new IllegalArgumentException("Unknown Compare op " + compareOp.name()); } } else { return false; } } /** * {@inheritDoc} */ @Override public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put) throws IOException { return checkAndPut(row, family, qualifier, CompareFilter.CompareOp.EQUAL, value, put); } /** * {@inheritDoc} */ @Override public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value, Put put) throws IOException { return checkAndPut(row, family, qualifier, CompareOperator.valueOf(compareOp.name()), value, put); } /** * {@inheritDoc} */ @Override public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, byte[] value, Put put) throws IOException { if (check(row, family, qualifier, compareOp, value)) { put(put); return true; } return false; } @Override public void delete(Delete delete) throws IOException { byte[] row = delete.getRow(); NavigableMap>> rowData = data.get(row); if (rowData == null) return; if (delete.getFamilyCellMap().isEmpty()) { data.remove(row); data.flush(); return; } for (Map.Entry> entry : delete.getFamilyCellMap().entrySet()) { byte[] family = entry.getKey(); NavigableMap> familyData = rowData.get(family); if (familyData == null) continue; if (entry.getValue().isEmpty()) { rowData.remove(family); continue; } for (Cell kv : entry.getValue()) { byte[] qualifier = CellUtil.cloneQualifier(kv); long ts = kv.getTimestamp(); NavigableMap qualifierData = familyData.get(qualifier); Iterator>> iter; switch (kv.getType()) { case DeleteFamily: iter = familyData.entrySet().iterator(); while (iter.hasNext()) { Map.Entry> innerEntry = iter.next(); NavigableMap qualData = innerEntry.getValue(); if (qualData != null) { if (ts == HConstants.LATEST_TIMESTAMP) { iter.remove(); } else { qualData.subMap(0L, true, ts, true).clear(); } if (qualData.isEmpty()) { iter.remove(); } } } break; case DeleteFamilyVersion: iter = familyData.entrySet().iterator(); while (iter.hasNext()) { Map.Entry> innerEntry = iter.next(); NavigableMap qualData = innerEntry.getValue(); if (qualData != null) { if (ts == HConstants.LATEST_TIMESTAMP) { qualData.pollLastEntry(); } else { qualData.remove(ts); } if (qualData.isEmpty()) { iter.remove(); } } } break; case DeleteColumn: if (qualifierData != null) { if (ts == HConstants.LATEST_TIMESTAMP) { familyData.remove(qualifier); } else { qualifierData.subMap(0L, true, ts, true).clear(); } if (qualifierData.isEmpty()) { familyData.remove(qualifier); } } break; case Delete: if (qualifierData != null) { if (ts == HConstants.LATEST_TIMESTAMP) { qualifierData.pollLastEntry(); } else { qualifierData.remove(ts); } if (qualifierData.isEmpty()) { familyData.remove(qualifier); } } break; default: throw new IllegalArgumentException("Incorrect type " + kv.getType() + " during delete"); } } if (familyData.isEmpty()) { rowData.remove(family); } } if (rowData.isEmpty()) { data.remove(row); } else { data.put(row, rowData); } data.flush(); } /** * {@inheritDoc} */ @Override public void delete(List deletes) throws IOException { for (Delete delete : deletes) { delete(delete); } } /** * {@inheritDoc} */ @Override public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, byte[] value, Delete delete) throws IOException { return checkAndDelete(row, family, qualifier, CompareFilter.CompareOp.EQUAL, value, delete); } /** * {@inheritDoc} */ @Override public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value, Delete delete) throws IOException { return checkAndDelete(row, family, qualifier, CompareOperator.valueOf(compareOp.name()), value, delete); } /** * {@inheritDoc} */ @Override public boolean checkAndDelete(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, byte[] value, Delete delete) throws IOException { if (check(row, family, qualifier, compareOp, value)) { delete(delete); return true; } return false; } /** * {@inheritDoc} */ @Override public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareFilter.CompareOp compareOp, byte[] value, RowMutations rm) throws IOException { return checkAndMutate(row, family, qualifier, CompareOperator.valueOf(compareOp.name()), value, rm); } /** * {@inheritDoc} */ @Override public boolean checkAndMutate(byte[] row, byte[] family, byte[] qualifier, CompareOperator compareOp, byte[] value, RowMutations rm) throws IOException { if (check(row, family, qualifier, compareOp, value)) { mutateRow(rm); return true; } return false; } /** * {@inheritDoc} */ @Override public Result increment(Increment increment) throws IOException { List kvs = new ArrayList<>(); Map> famToVal = increment.getFamilyMapOfLongs(); for (Map.Entry> ef : famToVal.entrySet()) { byte[] family = ef.getKey(); NavigableMap qToVal = ef.getValue(); for (Map.Entry eq : qToVal.entrySet()) { long newValue = incrementColumnValue(increment.getRow(), family, eq.getKey(), eq.getValue(), increment.getTimeRange()); Map.Entry timestampAndValue = data.get(increment.getRow()).get(family).get(eq.getKey()).lastEntry(); kvs.add(new KeyValue(increment.getRow(), family, eq.getKey(), timestampAndValue.getKey(), timestampAndValue.getValue())); } } return Result.create(kvs); } /** * {@inheritDoc} */ @Override public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount) throws IOException { return incrementColumnValue(row, family, qualifier, amount, TimeRange.allTime()); } private long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount, TimeRange timeRange) throws IOException { if (check(row, family, qualifier, CompareOperator.EQUAL, null, timeRange)) { Put put = new Put(row); put.addColumn(family, qualifier, Bytes.toBytes(amount)); put(put); return amount; } NavigableMap>> rowData = data.get(row); long newValue = Bytes.toLong(rowData.get(family).get(qualifier) .subMap(timeRange.getMin(), true, timeRange.getMax(), false).lastEntry().getValue()) + amount; rowData.get(family).get(qualifier).put(System.currentTimeMillis(), Bytes.toBytes(newValue)); data.put(row, rowData); data.flush(); return newValue; } /** * {@inheritDoc} */ @Override public long incrementColumnValue(byte[] row, byte[] family, byte[] qualifier, long amount, Durability durability) throws IOException { return incrementColumnValue(row, family, qualifier, amount); } /** * {@inheritDoc} */ @Override public void close() throws IOException { // no-op } /** * {@inheritDoc} */ @Override public CoprocessorRpcChannel coprocessorService(byte[] row) { throw new UnsupportedOperationException("coprocessorService"); } /** * {@inheritDoc} */ @Override public Map coprocessorService(final Class service, byte[] startKey, byte[] endKey, final Batch.Call callable) throws ServiceException { throw new UnsupportedOperationException("coprocessorService"); } /** * {@inheritDoc} */ @Override public void coprocessorService(final Class service, byte[] startKey, byte[] endKey, final Batch.Call callable, final Batch.Callback callback) throws ServiceException { throw new UnsupportedOperationException("coprocessorService"); } /** * {@inheritDoc} */ @Override public Map batchCoprocessorService( Descriptors.MethodDescriptor methodDescriptor, Message request, byte[] startKey, byte[] endKey, R responsePrototype) throws ServiceException { throw new UnsupportedOperationException("batchCoprocessorService"); } /** * {@inheritDoc} */ @Override public void batchCoprocessorService(Descriptors.MethodDescriptor methodDescriptor, Message request, byte[] startKey, byte[] endKey, R responsePrototype, Batch.Callback callback) throws ServiceException { throw new UnsupportedOperationException("batchCoprocessorService"); } public RegionLocator getRegionLocator() { return new RegionLocator() { @Override public HRegionLocation getRegionLocation(byte[] bytes) throws IOException { return new HRegionLocation(null, ServerName.valueOf("localhost:0", 0)); } @Override public HRegionLocation getRegionLocation(byte[] bytes, boolean b) throws IOException { return new HRegionLocation(null, ServerName.valueOf("localhost:0", 0)); } @Override public HRegionLocation getRegionLocation(byte[] bytes, int regionId, boolean b) throws IOException { return new HRegionLocation(null, ServerName.valueOf("localhost:0", 0)); } @Override public List getRegionLocations(byte[] bytes, boolean b) throws IOException { return Collections.singletonList(getRegionLocation(bytes, b)); } @Override public void clearRegionLocationCache() { } @Override public List getAllRegionLocations() throws IOException { return null; } @Override public byte[][] getStartKeys() throws IOException { return getStartEndKeys().getFirst(); } @Override public byte[][] getEndKeys() throws IOException { return getStartEndKeys().getSecond(); } @Override public Pair getStartEndKeys() throws IOException { final byte[][] startKeyList = new byte[1][]; final byte[][] endKeyList = new byte[1][]; startKeyList[0] = new byte[0]; endKeyList[0] = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff}; return new Pair<>(startKeyList, endKeyList); } @Override public TableName getName() { return KafkaStoreTable.this.getName(); } @Override public void close() throws IOException { } }; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy