private PluginKeyPrefix(String parentArtifactNamespace, String parentArtifactName, String type, String name) { this.keys = Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAMESPACE_FIELD, parentArtifactNamespace), Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAME_FIELD, parentArtifactName), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD, type), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_NAME_FIELD, name) ); }
private UniversalPluginKeyPrefix(String namespace, String type, String name) { this.keys = Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD, type), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_NAME_FIELD, name) ); } }
AppClassKey(NamespaceId namespace, String className) { this.keys = Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()), Fields.stringField(StoreDefinition.ArtifactStore.CLASS_NAME_FIELD, className) ); } }
private Range createUniversalPluginScanRange(String namespace, @Nullable String type) { List<Field<?>> keys = new ArrayList<>(); keys.add(Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace)); if (type != null) { keys.add(Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD, type)); } return Range.singleton(keys); }
private static Collection<Field<?>> fromRow(StructuredRow row) { return Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAMESPACE_FIELD, row.getString(StoreDefinition.ArtifactStore.ARTIFACT_NAMESPACE_FIELD)), Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAME_FIELD, row.getString(StoreDefinition.ArtifactStore.ARTIFACT_NAME_FIELD)), Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_VER_FIELD, row.getString(StoreDefinition.ArtifactStore.ARTIFACT_VER_FIELD)) ); } }
private static Collection<Field<?>> fromRow(StructuredRow row) { return Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAMESPACE_FIELD, row.getString(StoreDefinition.ArtifactStore.PARENT_NAMESPACE_FIELD)), Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAME_FIELD, row.getString(StoreDefinition.ArtifactStore.PARENT_NAME_FIELD)), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD, row.getString(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD)), Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_NAME_FIELD, row.getString(StoreDefinition.ArtifactStore.PLUGIN_NAME_FIELD)) ); } }
private Range createPluginScanRange(Id.Artifact parentArtifactId, @Nullable String type) { List<Field<?>> keys = new ArrayList<>(); keys.add(Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAMESPACE_FIELD, parentArtifactId.getNamespace().getId())); keys.add(Fields.stringField(StoreDefinition.ArtifactStore.PARENT_NAME_FIELD, parentArtifactId.getName())); if (type != null) { keys.add(Fields.stringField(StoreDefinition.ArtifactStore.PLUGIN_TYPE_FIELD, type)); } return Range.singleton(keys); }
private ArtifactCell(Id.Artifact artifactId) { this.keys = Arrays.asList( Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAMESPACE_FIELD, artifactId.getNamespace().getId()), Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAME_FIELD, artifactId.getName()), Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_VER_FIELD, artifactId.getVersion().getVersion())); }
private Range createArtifactScanRange(NamespaceId namespace) { Field<String> stringField = Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAMESPACE_FIELD, namespace.getNamespace()); return Range.singleton(Collections.singleton(stringField)); }
private Range createAppClassRange(NamespaceId namespace) { return Range.singleton(Collections.singleton(Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()))); }
private List<ArtifactDetail> getArtifacts(StructuredTable artifactDataTable, ArtifactRange range, int limit, ArtifactSortOrder order) throws IOException { Collection<Field<?>> keys = Arrays.asList(Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAMESPACE_FIELD, range.getNamespace()), Fields.stringField(StoreDefinition.ArtifactStore.ARTIFACT_NAME_FIELD, range.getName())); // here we have to query with Integer.MAX_VALUE since we want to sort the result try (CloseableIterator<StructuredRow> iterator = artifactDataTable.scan(Range.singleton(keys), Integer.MAX_VALUE)) { return getArtifacts(iterator, limit, order, range); } }
private List<Field<?>> extractKeys() { List<Field<?>> result = new ArrayList<>(); for (String key : tableSchema.getPrimaryKeys()) { // the NullPointerException should never be thrown since the primary keys must always have a type FieldType.Type type = tableSchema.getType(key); switch (Objects.requireNonNull(type)) { case INTEGER: result.add(Fields.intField(key, (int) columns.get(key))); break; case LONG: result.add(Fields.longField(key, (long) columns.get(key))); break; case STRING: result.add(Fields.stringField(key, (String) columns.get(key))); break; case BYTES: result.add(Fields.bytesField(key, (byte[]) columns.get(key))); break; default: // this should never happen since all the keys are from the table schema and should never contain other types throw new IllegalStateException( String.format("The type %s of the primary key %s is not a valid key type", type, key)); } } return result; }
/** * Get all application classes that belong to the specified namespace of the specified classname. * Results are returned as a sorted map from artifact to application classes in that artifact. * Map entries are sorted by the artifact. * * @param namespace the namespace from which to get application classes * @param className the classname of application classes to get * @return an unmodifiable map of artifact the application classes in that artifact. * The map will never be null. If there are no application classes, an empty map will be returned. */ public SortedMap<ArtifactDescriptor, ApplicationClass> getApplicationClasses(final NamespaceId namespace, final String className) { return TransactionRunners.run(transactionRunner, context -> { StructuredTable table = context.getTable(StoreDefinition.ArtifactStore.APP_DATA_TABLE); SortedMap<ArtifactDescriptor, ApplicationClass> result = Maps.newTreeMap(); Collection<Field<?>> keys = ImmutableList.of( Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace()), Fields.stringField(StoreDefinition.ArtifactStore.CLASS_NAME_FIELD, className)); try (CloseableIterator<StructuredRow> iterator = table.scan(Range.singleton(keys), Integer.MAX_VALUE)) { while (iterator.hasNext()) { StructuredRow row = iterator.next(); Map.Entry<ArtifactDescriptor, ApplicationClass> entry = extractApplicationClass(row); result.put(entry.getKey(), entry.getValue()); } } return Collections.unmodifiableSortedMap(result); }); }
/** * Get all application classes that belong to the specified namespace. * Results are returned as a sorted map from artifact to application classes in that artifact. * Map entries are sorted by the artifact. * * @param namespace the namespace from which to get application classes * @return an unmodifiable map of artifact to a list of all application classes in that artifact. * The map will never be null. If there are no application classes, an empty map will be returned. */ public SortedMap<ArtifactDescriptor, List<ApplicationClass>> getApplicationClasses(NamespaceId namespace) { return TransactionRunners.run(transactionRunner, context -> { SortedMap<ArtifactDescriptor, List<ApplicationClass>> result = Maps.newTreeMap(); StructuredTable table = context.getTable(StoreDefinition.ArtifactStore.APP_DATA_TABLE); Collection<Field<?>> keys = Collections.singleton( Fields.stringField(StoreDefinition.ArtifactStore.NAMESPACE_FIELD, namespace.getNamespace())); try (CloseableIterator<StructuredRow> iterator = table.scan(Range.singleton(keys), Integer.MAX_VALUE)) { while (iterator.hasNext()) { StructuredRow row = iterator.next(); Map.Entry<ArtifactDescriptor, ApplicationClass> entry = extractApplicationClass(row); List<ApplicationClass> existingAppClasses = result.computeIfAbsent(entry.getKey(), k -> new ArrayList<>()); existingAppClasses.add(entry.getValue()); } } return Collections.unmodifiableSortedMap(result); }); }
private Field<?> createField(String name, FieldType.Type type, Object value) { switch (type) { case BYTES: return Fields.bytesField(name, (byte[]) value); case LONG: return Fields.longField(name, (Long) value); case INTEGER: return Fields.intField(name, (Integer) value); case DOUBLE: return Fields.doubleField(name, (Double) value); case FLOAT: return Fields.floatField(name, (Float) value); case STRING: return Fields.stringField(name, (String) value); default: throw new IllegalStateException("Unknown field type " + type); } }
private Set<Field<?>> generateFieldsSet() { return ImmutableSet.of( Fields.bytesField("bytes", Bytes.toBytes("bytesval")), Fields.stringField("string", "strval"), Fields.doubleField("double", 100.0), Fields.intField("int", 30), Fields.bytesField("double-bytes", Bytes.toBytes(100.0)), Fields.bytesField("long-bytes", Bytes.toBytes(600L)) ); } }
private List<Collection<Field<?>>> writeSimpleStructuredRows(int max, String suffix) throws Exception { List<Collection<Field<?>>> expected = new ArrayList<>(max); for (int i = 0; i < max; i++) { List<Field<?>> fields = Arrays.asList(Fields.intField(KEY, i), Fields.longField(KEY2, (long) i), Fields.stringField(STRING_COL, VAL + i + suffix), Fields.doubleField(DOUBLE_COL, (double) i), Fields.floatField(FLOAT_COL, (float) i), Fields.bytesField(BYTES_COL, Bytes.toBytes("bytes-" + i))); expected.add(fields); getTransactionRunner().run(context -> { StructuredTable table = context.getTable(SIMPLE_TABLE); table.upsert(fields); }); } return expected; }
@Test public void testCompareAndSwapNonExistent() throws Exception { // Compare and swap a non-existent row Collection<Field<?>> nonExistentKeys = Arrays.asList(Fields.intField(KEY, -100), Fields.longField(KEY2, -10L)); // Verify row does not exist first getTransactionRunner().run(context -> { StructuredTable table = context.getTable(SIMPLE_TABLE); Optional<StructuredRow> row = table.read(nonExistentKeys); Assert.assertFalse(row.isPresent()); }); getTransactionRunner().run(context -> { StructuredTable table = context.getTable(SIMPLE_TABLE); boolean result = table.compareAndSwap(nonExistentKeys, Fields.stringField(STRING_COL, "non-existent"), Fields.stringField(STRING_COL, "new-val")); Assert.assertFalse(result); result = table.compareAndSwap(nonExistentKeys, Fields.stringField(STRING_COL, null), Fields.stringField(STRING_COL, "new-val")); Assert.assertTrue(result); }); // Read and verify getTransactionRunner().run(context -> { StructuredTable table = context.getTable(SIMPLE_TABLE); Optional<StructuredRow> row = table.read(nonExistentKeys); Assert.assertTrue(row.isPresent()); Assert.assertEquals("new-val", row.get().getString(STRING_COL)); }); }
Fields.stringField(KEY3, "s")), false); Fields.stringField(KEY3, "s")), false); Assert.fail("Expected InvalidFieldException"); } catch (InvalidFieldException e) {
private List<Collection<Field<?>>> scanSimpleStructuredRows(Range range, int max) throws Exception { List<Collection<Field<?>>> actual = new ArrayList<>(max); getTransactionRunner().run(context -> { StructuredTable table = context.getTable(SIMPLE_TABLE); try (CloseableIterator<StructuredRow> iterator = table.scan(range, max)) { while (iterator.hasNext()) { StructuredRow row = iterator.next(); actual.add(Arrays.asList(Fields.intField(KEY, row.getInteger(KEY)), Fields.longField(KEY2, row.getLong(KEY2)), Fields.stringField(STRING_COL, row.getString(STRING_COL)), Fields.doubleField(DOUBLE_COL, row.getDouble(DOUBLE_COL)), Fields.floatField(FLOAT_COL, row.getFloat(FLOAT_COL)), Fields.bytesField(BYTES_COL, row.getBytes(BYTES_COL)))); } } }); return actual; } }