in plugins/core-plugin/src/main/java/com/google/cloud/teleport/plugin/model/TemplateDefinitions.java [110:334]
public ImageSpec buildSpecModel(boolean validateFlag) {
if (validateFlag) {
validate(templateAnnotation);
}
ImageSpec imageSpec = new ImageSpec();
SdkInfo sdkInfo = new SdkInfo();
// Xlang templates require the java language.
if (templateAnnotation.type() == TemplateType.XLANG) {
sdkInfo.setLanguage("JAVA");
} else {
sdkInfo.setLanguage(templateAnnotation.type().toString());
}
imageSpec.setSdkInfo(sdkInfo);
imageSpec = updateStreamingModeRelatedDefaultEnvironment(imageSpec);
ImageSpecMetadata metadata = new ImageSpecMetadata();
metadata.setInternalName(templateAnnotation.name());
metadata.setName(templateAnnotation.displayName());
metadata.setDescription(
List.of(templateAnnotation.description()).stream().collect(Collectors.joining("\n\n")));
metadata.setCategory(
new ImageSpecCategory(
templateAnnotation.category().getName(),
templateAnnotation.category().getDisplayName()));
metadata.setModule(getClassModule());
metadata.setDocumentationLink(templateAnnotation.documentation());
metadata.setGoogleReleased(
templateAnnotation.documentation() != null
&& templateAnnotation.documentation().contains("cloud.google.com"));
metadata.setHidden(templateAnnotation.hidden());
metadata.setPreview(templateAnnotation.preview());
metadata.setRequirements(Arrays.asList(templateAnnotation.requirements()));
metadata.setStreaming(templateAnnotation.streaming());
metadata.setSupportsAtLeastOnce(templateAnnotation.supportsAtLeastOnce());
metadata.setSupportsExactlyOnce(templateAnnotation.supportsExactlyOnce());
metadata.setDefaultStreamingMode(templateAnnotation.defaultStreamingMode().toString());
metadata.setAdditionalDocumentation(
Arrays.stream(templateAnnotation.additionalDocumentation())
.map(
block ->
new ImageSpecAdditionalDocumentation(
block.name(), Arrays.asList(block.content())))
.collect(Collectors.toList()));
if (templateAnnotation.placeholderClass() != null
&& templateAnnotation.placeholderClass() != void.class) {
metadata.setMainClass(templateAnnotation.placeholderClass().getName());
} else {
metadata.setMainClass(templateClass.getName());
}
LOG.info(
"Processing template for class {}. Template name: {}",
templateClass,
templateAnnotation.name());
List<MethodDefinitions> methodDefinitions = new ArrayList<>();
int order = 0;
Map<Class<?>, Integer> classOrder = new HashMap<>();
Class<?> optionsClass = templateAnnotation.optionsClass();
if (optionsClass == void.class) {
optionsClass = templateClass;
}
if (templateAnnotation.optionsOrder() != null) {
for (Class<?> options : templateAnnotation.optionsOrder()) {
classOrder.putIfAbsent(options, order++);
}
}
// If blocks were defined, go through each block's option class
if (templateAnnotation.blocks()[0] != void.class) {
try {
List<ExecutionBlock> executionBlocks = AutoTemplate.buildExecutionBlocks(templateClass);
for (ExecutionBlock block : executionBlocks) {
classOrder.putIfAbsent(block.getBlockInstance().getOptionsClass(), order++);
}
optionsClass =
AutoTemplate.createNewOptionsClass(
executionBlocks,
templateClass.getClassLoader(),
AutoTemplate.getDlqInstance(templateClass));
} catch (Exception e) {
throw new RuntimeException("Error parsing template blocks", e);
}
}
classOrder.putIfAbsent(optionsClass, order++);
Set<String> parameterNames = new HashSet<>();
Method[] methods = optionsClass.getMethods();
for (Method method : methods) {
method.setAccessible(true);
// Ignore the method if it contains @TemplateIgnoreParameter
if (method.getAnnotation(TemplateIgnoreParameter.class) != null) {
continue;
}
classOrder.putIfAbsent(method.getDeclaringClass(), order++);
Annotation parameterAnnotation = MetadataUtils.getParameterAnnotation(method);
if (parameterAnnotation == null) {
boolean runtime = false;
TemplateCreationParameters creationParameters =
method.getAnnotation(TemplateCreationParameters.class);
String methodName = method.getName();
if (creationParameters != null) {
for (TemplateCreationParameter creationParameterCandidate : creationParameters.value()) {
if (creationParameterCandidate.template().equals(templateAnnotation.name())
|| StringUtils.isEmpty(creationParameterCandidate.template())) {
runtime = true;
if (StringUtils.isNotEmpty(creationParameterCandidate.value())) {
metadata
.getRuntimeParameters()
.put(
getParameterNameFromMethod(methodName), creationParameterCandidate.value());
}
}
}
}
TemplateCreationParameter creationParameter =
method.getAnnotation(TemplateCreationParameter.class);
if (creationParameter != null) {
runtime = true;
if (StringUtils.isNotEmpty(creationParameter.value())) {
metadata
.getRuntimeParameters()
.put(getParameterNameFromMethod(methodName), creationParameter.value());
}
}
// Ignore non-annotated params in this criteria (non-options params)
if (runtime
|| methodName.startsWith("set")
|| IGNORED_FIELDS.contains(methodName)
|| method.getDeclaringClass().getName().startsWith("org.apache.beam.sdk")
|| method.getDeclaringClass().getName().startsWith("org.apache.beam.runners")
|| method.getReturnType() == void.class
|| IGNORED_DECLARING_CLASSES.contains(method.getDeclaringClass().getSimpleName())) {
continue;
}
if (validateFlag) {
validate(method);
}
continue;
}
methodDefinitions.add(new MethodDefinitions(method, parameterAnnotation, classOrder));
}
Set<String> skipOptionsSet = Set.of(templateAnnotation.skipOptions());
Set<String> optionalOptionsSet = Set.of(templateAnnotation.optionalOptions());
Collections.sort(methodDefinitions);
for (MethodDefinitions method : methodDefinitions) {
Annotation parameterAnnotation = method.getTemplateParameter();
ImageSpecParameter parameter =
getImageSpecParameter(
method.getDefiningMethod().getName(),
method.getDefiningMethod(),
parameterAnnotation);
if (skipOptionsSet.contains(parameter.getName())) {
continue;
}
if (optionalOptionsSet.contains(parameter.getName())) {
parameter.setOptional(true);
}
// Set the default value, if any
Object defaultVal = getDefault(method.getDefiningMethod());
if (defaultVal != null) {
parameter.setDefaultValue(String.valueOf(defaultVal));
}
if (parameterNames.add(parameter.getName())) {
metadata.getParameters().add(parameter);
} else {
LOG.warn(
"Parameter {} was already added for the Template {}, skipping repetition.",
parameter.getName(),
templateAnnotation.name());
}
}
boolean isFlex = StringUtils.isNotEmpty(templateAnnotation.flexContainerName());
metadata.setFlexTemplate(isFlex);
imageSpec.setAdditionalUserLabel(
"goog-dataflow-provided-template-name", templateAnnotation.name().toLowerCase());
imageSpec.setAdditionalUserLabel(
"goog-dataflow-provided-template-type", isFlex ? "flex" : "classic");
imageSpec.setImage("gcr.io/{project-id}/" + templateAnnotation.flexContainerName());
imageSpec.setMetadata(metadata);
metadata.setUdfSupport(
metadata.getParameters().stream()
.anyMatch(
parameter ->
parameter.getName().contains("javascriptTextTransformGcsPath")
|| parameter.getName().contains("javascriptTextTransformFunctionName")));
return imageSpec;
}