/* * Copyright (c) 2016 EMC Corporation * All Rights Reserved */ package com.emc.storageos.db.server; import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.emc.storageos.db.client.URIUtil; import com.emc.storageos.db.client.impl.CompositeColumnName; import com.emc.storageos.db.client.impl.CompositeColumnNameSerializer; import com.emc.storageos.db.client.impl.DataObjectType; import com.emc.storageos.db.client.impl.DbClientImpl; import com.emc.storageos.db.client.impl.IndexColumnName; import com.emc.storageos.db.client.impl.IndexColumnNameSerializer; import com.emc.storageos.db.client.impl.RowMutator; import com.emc.storageos.db.client.impl.TypeMap; import com.emc.storageos.db.client.model.StoragePool; import com.emc.storageos.db.client.model.StringSet; import com.emc.storageos.db.client.model.Volume; import com.google.common.collect.Sets; import com.netflix.astyanax.ColumnListMutation; import com.netflix.astyanax.connectionpool.OperationResult; import com.netflix.astyanax.connectionpool.exceptions.ConnectionException; import com.netflix.astyanax.cql.CqlStatement; import com.netflix.astyanax.cql.CqlStatementResult; import com.netflix.astyanax.model.Column; import com.netflix.astyanax.model.ColumnFamily; import com.netflix.astyanax.model.ColumnList; import com.netflix.astyanax.model.Rows; import com.netflix.astyanax.serializers.StringSerializer; import com.netflix.astyanax.util.TimeUUIDUtils; public class RowMutationTest extends DbsvcTestBase { private RowMutator rowMutator; private ColumnFamily<String, CompositeColumnName> volumeCF; private ColumnFamily<String, CompositeColumnName> noExistCF; private ColumnFamily<String, IndexColumnName> indexCF; @Before public void setupTest() { volumeCF = new ColumnFamily<String, CompositeColumnName>("Volume", StringSerializer.get(), CompositeColumnNameSerializer.get()); indexCF = new ColumnFamily<String, IndexColumnName>("LabelPrefixIndex", StringSerializer.get(), IndexColumnNameSerializer.get()); noExistCF = new ColumnFamily<String, CompositeColumnName>("no_exits_CF", StringSerializer.get(), CompositeColumnNameSerializer.get()); rowMutator = new RowMutator(((DbClientImpl)this.getDbClient()).getLocalContext().getKeyspace(), false); } @Test public void insertRecordAndIndexColumn() throws ConnectionException { String rowKey = URIUtil.createId(Volume.class).toString(); String volumeLabel = "volume label"; //insert data object ColumnListMutation<CompositeColumnName> columnList = rowMutator.getRecordColumnList(volumeCF, rowKey); columnList.putColumn(new CompositeColumnName("allocatedCapacity"), 20); columnList.putColumn(new CompositeColumnName("label"), volumeLabel); //insert related index rowMutator.getIndexColumnList(indexCF, "vo"). putColumn(new IndexColumnName("Volume", volumeLabel, volumeLabel, rowKey, rowMutator.getTimeUUID()), ""); rowMutator.execute(); //verify data object information Volume volume = (Volume)this.getDbClient().queryObject(URI.create(rowKey)); Assert.assertNotNull(volume); Assert.assertEquals(volume.getAllocatedCapacity().longValue(), 20L); Assert.assertEquals(volume.getLabel(), volumeLabel); //verify index information CqlStatement statement = ((DbClientImpl)this.getDbClient()).getLocalContext().getKeyspace().prepareCqlStatement(); String cql = String.format("select * from \"LabelPrefixIndex\" where key='%s' and column1='Volume' and column2='%s' and column3='%s' and column4='%s'", "vo", volumeLabel, volumeLabel, rowKey); CqlStatementResult result = statement.withCql(cql).execute().getResult(); Rows<String, IndexColumnName> rows = result.getRows(indexCF); Assert.assertEquals(rows.size(), 1); } @Test public void insertRecordAndIndexColumnWithError() throws ConnectionException { String rowKey = URIUtil.createId(Volume.class).toString(); String volumeLabel = "volume label"; //insert data object ColumnListMutation<CompositeColumnName> columnList = rowMutator.getRecordColumnList(volumeCF, rowKey); columnList.putColumn(new CompositeColumnName("allocatedCapacity"), 20); columnList.putColumn(new CompositeColumnName("label"), volumeLabel); //insert related index rowMutator.getIndexColumnList(indexCF, "vo"). putColumn(new IndexColumnName("Volume", volumeLabel, volumeLabel, rowKey, rowMutator.getTimeUUID()), ""); //insert error column ColumnListMutation<CompositeColumnName> no_columnList = rowMutator.getRecordColumnList(noExistCF, rowKey); no_columnList.putColumn(new CompositeColumnName("test"), 20); try { rowMutator.execute(); Assert.fail(); } catch (Exception e) { //expected exception } //no volume should be created Volume volume = (Volume)this.getDbClient().queryObject(URI.create(rowKey)); Assert.assertNull(volume); //no index should be created CqlStatement statement = ((DbClientImpl)this.getDbClient()).getLocalContext().getKeyspace().prepareCqlStatement(); String cql = String.format("select * from \"LabelPrefixIndex\" where key='%s' and column1='Volume' and column2='%s' and column3='%s' and column4='%s'", "vo", volumeLabel, volumeLabel, rowKey); CqlStatementResult result = statement.withCql(cql).execute().getResult(); Rows<String, IndexColumnName> rows = result.getRows(indexCF); Assert.assertEquals(rows.size(), 0); } @Test public void insertDataObject() throws ConnectionException { String prefix = "AA"; Volume volume = new Volume(); URI id = URIUtil.createId(Volume.class); URI pool = URIUtil.createId(StoragePool.class); volume.setId(id); volume.setLabel(prefix + "volume"); volume.setPool(pool); volume.setNativeGuid(prefix + "native_guid-2"); volume.setNativeId(prefix + "native_id-2"); volume.setCompositionType(prefix + "compositionType"); volume.setInactive(false); volume.setAllocatedCapacity(1000L); volume.setProvisionedCapacity(2000L); this.getDbClient().updateObject(volume); Volume target = (Volume)this.getDbClient().queryObject(id); Assert.assertNotNull(target); Assert.assertEquals(target.getLabel(), volume.getLabel()); Assert.assertEquals(target.getPool(), volume.getPool()); Assert.assertEquals(target.getNativeGuid(), volume.getNativeGuid()); Assert.assertEquals(target.getNativeId(), volume.getNativeId()); Assert.assertEquals(target.getCompositionType(), volume.getCompositionType()); Assert.assertEquals(target.getAllocatedCapacity(), volume.getAllocatedCapacity()); Assert.assertEquals(target.getProvisionedCapacity(), volume.getProvisionedCapacity()); CqlStatement statement = ((DbClientImpl)this.getDbClient()).getLocalContext().getKeyspace().prepareCqlStatement(); String cql = String.format("select * from \"LabelPrefixIndex\" where key='%s' and column1='Volume' and column2='%s' and column3='%s' and column4='%s'", prefix.toLowerCase(), volume.getLabel().toLowerCase(), volume.getLabel(), volume.getId().toString()); CqlStatementResult result = statement.withCql(cql).execute().getResult(); Rows<String, IndexColumnName> rows = result.getRows(indexCF); Assert.assertEquals(rows.size(), 1); } @Test public void testTimeUUID() throws Exception { Volume volume = new Volume(); URI id1 = URIUtil.createId(Volume.class); URI pool1 = URIUtil.createId(StoragePool.class); volume.setId(id1); volume.setLabel("volume1"); volume.setPool(pool1); volume.setInactive(false); volume.setAllocatedCapacity(1000L); volume.setProvisionedCapacity(2000L); volume.setAssociatedSourceVolume(URI.create("test")); volume.setVolumeGroupIds(new StringSet(Sets.newHashSet("v1", "v2"))); getDbClient().updateObject(volume); DataObjectType doType = TypeMap.getDoType(Volume.class); OperationResult<ColumnList<CompositeColumnName>> result = ((DbClientImpl)getDbClient()).getLocalContext().getKeyspace().prepareQuery(doType.getCF()) .getKey(volume.getId().toString()) .execute(); List<Long> columnTimeUUIDStamps = new ArrayList<Long>(); for (Column<CompositeColumnName> column : result.getResult()) { if (column.getName().getTimeUUID() != null) { columnTimeUUIDStamps.add(TimeUUIDUtils.getMicrosTimeFromUUID(column.getName().getTimeUUID())); } } Collections.sort(columnTimeUUIDStamps); for (int i = 1; i < columnTimeUUIDStamps.size(); i++) { Assert.assertEquals(1, columnTimeUUIDStamps.get(i) - columnTimeUUIDStamps.get(i - 1)); } } }