/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.blur.thrift;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import org.apache.blur.thirdparty.thrift_0_9_0.TException;
import org.apache.blur.thrift.generated.Blur.Iface;
import org.apache.blur.thrift.generated.Column;
import org.apache.blur.thrift.generated.FetchResult;
import org.apache.blur.thrift.generated.Record;
import org.apache.blur.thrift.generated.RecordMutation;
import org.apache.blur.thrift.generated.RecordMutationType;
import org.apache.blur.thrift.generated.Row;
import org.apache.blur.thrift.generated.RowMutation;
import org.apache.blur.thrift.generated.RowMutationType;
import org.apache.blur.thrift.generated.Selector;
public class BlurMutationBug {
private final Iface client;
private final String tableName;
private final String[] rowIds;
public static void main(String[] args) throws TException {
Iface client = BlurClient.getClient("localhost:40010");
BlurMutationBug blurMutationBug = new BlurMutationBug(client, "testtable", 20);
blurMutationBug.runTest(5, TimeUnit.MINUTES);
}
public BlurMutationBug(Iface client, String tableName, int totalIds) {
this.client = client;
this.tableName = tableName;
rowIds = new String[totalIds];
for (int i = 0; i < totalIds; i++) {
rowIds[i] = UUID.randomUUID().toString();
}
}
public void runTest(long totalTime, TimeUnit timeUnit) throws TException {
long testTime = timeUnit.toMillis(totalTime);
long startTime = System.currentTimeMillis();
while (testTime + startTime >= System.currentTimeMillis()) {
for (String rowId : rowIds) {
addMetaToBlur(rowId);
}
}
}
private void addMetaToBlur(String rowId) throws TException {
RowMutation rowMutation = buildMeta(rowId);
mutateIndex(rowMutation);
Row row = fetchRow(rowMutation.getRowId());
if ((row == null) || !row.getId().equals(rowMutation.getRowId())) {
throw new IllegalStateException("Fetch of rowId " + rowMutation.getRowId() + " returned wrong rowId "
+ ((row == null) ? "null" : row.getId()));
}
checkForCorruption();
}
private void checkForCorruption() throws TException {
for (String rowId : rowIds) {
Row row = fetchRow(rowId);
if (row != null) {
List<String> metaKeys = new ArrayList<String>(1);
for (Record record : row.getRecords()) {
for (Column column : record.getColumns()) {
if ("key".equals(column.getName())) {
metaKeys.add(column.getValue());
}
}
}
if ((metaKeys.size() != 1) || !metaKeys.get(0).equals(rowId)) {
throw new IllegalStateException("corrupt row with bad key(s) " + metaKeys);
}
}
}
}
private RowMutation buildMeta(String rowId) {
Column column = new Column();
column.setName("key");
column.setValue(rowId);
List<Column> columns = new ArrayList<Column>();
columns.add(column);
Record record = new Record();
record.setFamily("meta");
record.setColumns(columns);
record.setRecordId("0");
List<RecordMutation> recMutations = new ArrayList<RecordMutation>(1);
RecordMutation recMutation = new RecordMutation();
recMutation.setRecordMutationType(RecordMutationType.REPLACE_ENTIRE_RECORD);
recMutation.setRecord(record);
recMutations.add(recMutation);
RowMutation rowMutation = new RowMutation();
rowMutation.setTable(tableName);
rowMutation.setRowId(rowId);
rowMutation.setRowMutationType(RowMutationType.REPLACE_ROW);
rowMutation.setRecordMutations(recMutations);
return (rowMutation);
}
private void mutateIndex(RowMutation rowMutation) throws TException {
Iface blurClient = getClient();
blurClient.mutate(rowMutation);
}
private Row fetchRow(String rowId) throws TException {
Iface blurClient = getClient();
Selector selector = new Selector();
selector.setRowId(rowId);
FetchResult fetchResult = blurClient.fetchRow(tableName, selector);
Row row = null;
if (fetchResult != null && fetchResult.isExists() && fetchResult.isSetRowResult()) {
row = fetchResult.getRowResult().getRow();
}
return (row);
}
private Iface getClient() {
return client;
}
}