/* * Copyright 2012 NGDATA nv * * Licensed 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.lilyproject.tools.tester; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang.ArrayUtils; import org.codehaus.jackson.JsonNode; import org.lilyproject.repository.api.Blob; import org.lilyproject.repository.api.FieldType; import org.lilyproject.repository.api.HierarchyPath; import org.lilyproject.repository.api.QName; import org.lilyproject.repository.api.Record; import org.lilyproject.repository.api.RecordId; import org.lilyproject.repository.api.RepositoryException; import org.lilyproject.repository.api.ValueType; import org.lilyproject.repository.impl.valuetype.BlobValueType; import org.lilyproject.util.json.JsonUtil; public class ReadAction extends AbstractTestAction implements TestAction { private boolean readBlobs = false; public ReadAction(JsonNode jsonNode, TestActionContext testActionContext) { super(jsonNode, testActionContext); readBlobs = JsonUtil.getBoolean(actionNode, "readBlobs", false); } @Override protected void runAction() { TestRecord testRecord = testActionContext.records.getRecord(source); if (testRecord == null) { return; } long before = System.nanoTime(); try { Record readRecord = testActionContext.table.read(testRecord.getRecordId()); long after = System.nanoTime(); report(true, (int) (after - before), "R", null); // Read blobs if (readBlobs) { readBlobs(readRecord); } // if (!readRecord.equals(testRecord.record)) { // System.out.println("Read record does not match written record!"); // } } catch (Throwable t) { long after = System.nanoTime(); report(false, (int) (after - before)); reportError("Error reading record.", t); } } private void readBlobs(Record readRecord) throws IOException, RepositoryException, InterruptedException { Map<QName, Object> readFields = readRecord.getFields(); for (Entry<QName, Object> entry : readFields.entrySet()) { QName fieldName = entry.getKey(); FieldType fieldType = testActionContext.fieldTypes.get(fieldName).getFieldType(); ValueType valueType = fieldType.getValueType(); if (valueType.getDeepestValueType() instanceof BlobValueType) { readBlobs(readRecord, fieldName, entry.getValue(), valueType); } } } private void readBlobs(Record readRecord, QName fieldName, Object value, ValueType valueType, int... indexes) throws RepositoryException, InterruptedException, IOException { if (valueType.getBaseName().equals("LIST")) { List<Object> multivalues = (List<Object>) (value); int multivalueIndex = randomIndex(multivalues.size()); Object subValue = (multivalues.get(multivalueIndex)); indexes = ArrayUtils.add(indexes, multivalueIndex); readBlobs(readRecord, fieldName, subValue, valueType.getNestedValueType(), indexes); } else if (valueType.getBaseName().equals("PATH")) { Object[] hierarchyValues = ((HierarchyPath) (value)).getElements(); int hierarchyIndex = randomIndex(hierarchyValues.length); Object subValue = hierarchyValues[hierarchyIndex]; indexes = ArrayUtils.add(indexes, hierarchyIndex); readBlobs(readRecord, fieldName, subValue, valueType.getNestedValueType(), indexes); } else { Blob blob = (Blob) value; InputStream inputStream = testActionContext.table.getInputStream(readRecord, fieldName, indexes); readBlobBytes(blob, inputStream); } } private int randomIndex(int arrayLength) { return (int)(Math.random() * arrayLength); } private void readBlobBytes(Blob blob, InputStream inputStream) throws IOException { byte[] readBytes = new byte[blob.getSize().intValue()]; int offset = 0; int len = blob.getSize().intValue(); while (true) { int amountRead = inputStream.read(readBytes, offset, len); if (amountRead == -1) { break; } offset = offset + amountRead; len = len - amountRead; } // System.out.println("Blob read len="+offset+", expected="+blob.getSize()); } @Override public ActionResult linkFieldAction(TestFieldType testFieldType, RecordId recordId) { throw new UnsupportedOperationException(); } }