private static boolean areGsisSameConfiguration(final List<GlobalSecondaryIndexDescription> g1, final List<GlobalSecondaryIndexDescription> g2) { if (g1 == null) { return g2 == null; } if (g1.size() != g2.size()) { return false; } // make copy of the lists because we don't want to mutate the lists final ArrayList<GlobalSecondaryIndexDescription> g1clone = new ArrayList<>(g1.size()); g1clone.addAll(g1); final ArrayList<GlobalSecondaryIndexDescription> g2clone = new ArrayList<>(g2.size()); g1clone.addAll(g2); for (final GlobalSecondaryIndexDescription gi1 : g1) { for (final GlobalSecondaryIndexDescription gi2 : g2) { if (areGsisSameConfiguration(gi1, gi2)) { g1clone.remove(gi1); g2clone.remove(gi2); break; } } } return g1clone.isEmpty() || g2clone.isEmpty(); }
private static boolean areGsisSameConfiguration(final GlobalSecondaryIndexDescription g1, final GlobalSecondaryIndexDescription g2) { if (g1 == null ^ g2 == null) { return false; } if (g1 == g2) { return true; } final EqualsBuilder builder = new EqualsBuilder(); builder.append(g1.getIndexName(), g2.getIndexName()); builder.append(g1.getKeySchema(), g2.getKeySchema()); builder.append(g1.getProjection().getProjectionType(), g2.getProjection().getProjectionType()); builder.append(g1.getProvisionedThroughput().getReadCapacityUnits(), g2.getProvisionedThroughput().getReadCapacityUnits()); builder.append(g1.getProvisionedThroughput().getWriteCapacityUnits(), g2.getProvisionedThroughput().getWriteCapacityUnits()); final Set<String> projectionNonKeyAttributesG1 = new HashSet<>(Optional.ofNullable(g1.getProjection().getNonKeyAttributes()).orElse(Collections.emptyList())); final Set<String> projectionNonKeyAttributesG2 = new HashSet<>(Optional.ofNullable(g2.getProjection().getNonKeyAttributes()).orElse(Collections.emptyList())); builder.append(projectionNonKeyAttributesG1, projectionNonKeyAttributesG2); return builder.build(); }
private static Collection<IndexDescription> toIndexDescriptions(com.amazonaws.services.dynamodbv2.model.TableDescription table) { List<IndexDescription> indexes = new ArrayList<>(); // Main indexes.add( toIndex( null, IndexType.MAIN_INDEX, table.getKeySchema(), table.getAttributeDefinitions(), table.getProvisionedThroughput())); if ( null != table.getLocalSecondaryIndexes() ) { for ( LocalSecondaryIndexDescription lsi : table.getLocalSecondaryIndexes() ) { indexes.add( toIndex( lsi.getIndexName(), IndexType.LOCAL_SECONDARY_INDEX, lsi.getKeySchema(), table.getAttributeDefinitions(), null)); } } if ( null != table.getGlobalSecondaryIndexes() ) { for ( GlobalSecondaryIndexDescription gsi : table.getGlobalSecondaryIndexes() ) { indexes.add( toIndex( gsi.getIndexName(), IndexType.GLOBAL_SECONDARY_INDEX, gsi.getKeySchema(), table.getAttributeDefinitions(), gsi.getProvisionedThroughput())); } } return indexes; }
public boolean isGsiExists(String gsiName) { List<GlobalSecondaryIndexDescription> descriptionList = null; descriptionList = tableDescription.getGlobalSecondaryIndexes(); if (null == descriptionList) { return false; } for (GlobalSecondaryIndexDescription desc : descriptionList) { if (desc.getIndexName().equals(gsiName)) { return true; } } return false; }
@Before public void setupBeforeTest() { /** Setup key schema */ List<KeySchemaElement> keySchema = new ArrayList<KeySchemaElement>(); KeySchemaElement hashKey = new KeySchemaElement().withAttributeName(hashKeyName).withKeyType(KeyType.HASH); KeySchemaElement rangeKey = new KeySchemaElement().withAttributeName(rangeKeyName).withKeyType(KeyType.RANGE); keySchema.add(hashKey); keySchema.add(rangeKey); Mockito.when(mockTableDescription.getKeySchema()).thenReturn(keySchema); /** Setup attribute definition */ List<AttributeDefinition> attribtueDefinitions = new ArrayList<AttributeDefinition>(); AttributeDefinition hashKeyDefinition = new AttributeDefinition().withAttributeName(hashKeyName).withAttributeType(hashKeyType); AttributeDefinition rangeKeyDefinition = new AttributeDefinition().withAttributeName(rangeKeyName).withAttributeType(rangeKeyType); attribtueDefinitions.add(hashKeyDefinition); attribtueDefinitions.add(rangeKeyDefinition); Mockito.when(mockTableDescription.getAttributeDefinitions()).thenReturn(attribtueDefinitions); /** Setup GSI */ List<GlobalSecondaryIndexDescription> globalSecondaryIndexes = new ArrayList<GlobalSecondaryIndexDescription>(); GlobalSecondaryIndexDescription gsiTest = new GlobalSecondaryIndexDescription().withIndexName(gsiName); globalSecondaryIndexes.add(gsiTest); Mockito.when(mockTableDescription.getGlobalSecondaryIndexes()).thenReturn(globalSecondaryIndexes); /** Setup provisioned throughput */ ProvisionedThroughputDescription provisionedThroughPut = new ProvisionedThroughputDescription().withReadCapacityUnits(readCapacity) .withWriteCapacityUnits(writeCapacity); Mockito.when(mockTableDescription.getProvisionedThroughput()).thenReturn(provisionedThroughPut); }
public void waitForTableCreation(final String tableName, final boolean verifyIndexesList, final List<LocalSecondaryIndexDescription> expectedLsiList, final List<GlobalSecondaryIndexDescription> expectedGsiList) throws BackendException { boolean successFlag = false; int retryCount = 0; while (!successFlag && retryCount < maxRetries) { try { boolean areAllGsisActive = true; final TableDescription td = describeTable(tableName); if (verifyIndexesList) { final Set<LocalSecondaryIndexDescription> expectedLSIs = new HashSet<LocalSecondaryIndexDescription>(); if (expectedLsiList != null) { expectedLSIs.addAll(expectedLsiList); } final Set<LocalSecondaryIndexDescription> actualLSIs = new HashSet<LocalSecondaryIndexDescription>(); if (td.getLocalSecondaryIndexes() != null) { actualLSIs.addAll(td.getLocalSecondaryIndexes()); } // the lsi list should be there even if the table is in creating state if (!(expectedLsiList == null && td.getLocalSecondaryIndexes() == null || expectedLSIs.equals(actualLSIs))) { throw new PermanentBackendException("LSI list is not as expected during table creation. expectedLsiList=" + expectedLsiList.toString() + "; table description=" + td.toString()); } // ignore the status of all GSIs since they will mess up .equals() if (td.getGlobalSecondaryIndexes() != null) { for (final GlobalSecondaryIndexDescription gDesc : td.getGlobalSecondaryIndexes()) { if (!isTableAcceptingWrites(gDesc.getIndexStatus())) { areAllGsisActive = false; break; } } } // the gsi list should be there even if the table is in creating state if (!areGsisSameConfiguration(expectedGsiList, td.getGlobalSecondaryIndexes())) { throw new PermanentBackendException("GSI list is not as expected during table creation. expectedGsiList=" + expectedGsiList.toString() + "; table description=" + td.toString()); } } successFlag = isTableAcceptingWrites(td.getTableStatus()) && areAllGsisActive; } catch (BackendNotFoundException ignore) { successFlag = false; } if (!successFlag) { interruptibleSleep(CONTROL_PLANE_RETRY_DELAY_MS); } retryCount++; } if (!successFlag) { throw new PermanentBackendException("Table creation not completed for table " + tableName + " after retrying " + this.maxRetries + " times for a duration of " + CONTROL_PLANE_RETRY_DELAY_MS * this.maxRetries + " ms"); } }