public class RecordKeysResolver implements TypeKeysResolver {
@Override
public String getCategoryName() {
return "Records";
}
@Override
public Set<MetadataKey> getKeys(MetadataContext context) throws MetadataResolvingException, ConnectionException {
// First we need to obtain the key IDs that will be used.
// This is where you'd normally use `context.getConfig()`
// or `context.getConnection()` to obtain the entity id's
// from a remote service, for this demo the keys will be fixed
List<String> keyIds = Arrays.asList("Author_id", "BookList_id", "Book_id");
HashSet<MetadataKey> keys = new HashSet<>();
for (String id: keyIds){
// For each possible if, we create a new MetadataKey with that ID
MetadataKeyBuilder builder = MetadataKeyBuilder.newKey(id);
// Then, we add a DisplayName to that MetadataKey,
// this will be the name shown in the UI
builder.withDisplayName(StringUtils.removeEnd(id, "_id"));
//finally, add the key to the Set of known MetadataKeys
keys.add(builder.build());
}
return keys;
}
}
Metadata Keys Parameter
To describe a dynamic metadata structure, you need to know what type to represent. This type reference is done by defining a @MetadataKeyId
parameter in the operation that contains the ID of the type (for example, Account) that will be passed to the metadata resolver defined for that parameter.
This means, for example, that if your operation can save a generic record to a remote system, but you want to provide a better design-time experience by describing the supported types Account
and Organization
, then one of your operation parameters will be a type reference containing either the ID Account
or the ID Organization
.
This parameter will be used to describe either the Account structure or the Organization structure for the record to be saved into the bucket, depending on what the end user decides to use.
Providing a List of Metadata Keys
The most common case when resolving dynamic metadata is to have a dynamic
set of keys that identify each of the possible types to be resolved. At design time, the end user will configure the connector, select an operation, and choose one of those keys from the set that gets populated dynamically, and the selected key will become the MetadataKeyId
for the metadata resolution.
Implementing the dynamic key’s resolution starts with a TypeKeysResolver
:
Above, all the elements that are required to create a dynamic set of MetadataKeys. The method to implement is getKeys
, which outputs all the keys available to the user.
The id
element, like Author_id
is used internally and must be unique for each structure that you want to represent across all the resolvers. The displayName
is the name to show to the user for that key, so it is expected to be more user friendly and readable.
Once the resolver is defined, you can use it an operation or source, associating the resolver to a given MetadataKeyId
parameter (see User-Defined MetadataKey).
public class OperationWithMetadataKey {
public void create(@MetadataKeyId(RecordKeysResolver.class) String type,
@Config MyConfig config){
//...
}
}
@MetadataScope(keysResolver = RecordKeysResolver.class)
public class DocsMetadataSource extends Source<Map<String, Object>, Void> {
@MetadataKeyId
@Parameter
public String type;
//...
}
User-Defined MetadataKey
An user-defined MetadataKey
is one that is provided freely by the end user and not defined by you as one of the possible elements of a List.
For example, this is a very common case in queries, where you use the whole query
that the end user wants to execute as a MetadataKey
.
In order to declare it, you simply annotate a parameter with @MetadataKeyId
, but you do not provide a TypesKeyResolver
.
public void query(@MetadataKeyId String query){
//...
}