NIFI-9443 Update NAR plugin to 1.3.3 and update data model for extension manifest to capture new fields

Signed-off-by: Joe Gresock <jgresock@gmail.com>

This closes #5570.
This commit is contained in:
Bryan Bende 2021-11-29 15:36:42 -05:00 committed by Joe Gresock
parent 53809dd83f
commit 0f027743d1
No known key found for this signature in database
GPG Key ID: 37F5B9B6E258C8B7
7 changed files with 317 additions and 33 deletions

View File

@ -94,7 +94,6 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeDeprecationNotice(final DeprecationNotice deprecationNotice) throws IOException {
if (deprecationNotice == null) {
writeEmptyElement("deprecationNotice");
return;
}
@ -127,22 +126,30 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeDescription(final String description) throws IOException {
if (description == null) {
return;
}
writeTextElement("description", description);
}
@Override
protected void writeTags(final List<String> tags) throws IOException {
if (tags == null) {
return;
}
writeTextArray("tags", "tag", tags);
}
@Override
protected void writeProperties(final List<PropertyDescriptor> properties, Map<String,ServiceAPI> propertyServices) throws IOException {
if (properties == null || properties.isEmpty()) {
return;
}
writeStartElement("properties");
if (properties != null) {
for (final PropertyDescriptor property : properties) {
writeProperty(property, propertyServices);
}
}
writeEndElement();
}
@ -152,7 +159,9 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
writeTextElement("name", property.getName());
writeTextElement("displayName", property.getDisplayName());
writeTextElement("description", property.getDescription());
if (property.getDefaultValue() != null) {
writeTextElement("defaultValue", property.getDefaultValue());
}
if (property.getControllerServiceDefinition() != null) {
writeStartElement("controllerServiceDefinition");
@ -173,11 +182,16 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
writeEndElement();
}
if (property.getAllowableValues() != null && !property.getAllowableValues().isEmpty()) {
writeArray("allowableValues", property.getAllowableValues(), this::writeAllowableValue);
}
writeBooleanElement("required", property.isRequired());
writeBooleanElement("sensitive", property.isSensitive());
writeBooleanElement("expressionLanguageSupported", property.isExpressionLanguageSupported());
writeTextElement("expressionLanguageScope", property.getExpressionLanguageScope() == null ? null : property.getExpressionLanguageScope().name());
if (property.getExpressionLanguageScope() != null) {
writeTextElement("expressionLanguageScope", property.getExpressionLanguageScope().name());
}
writeBooleanElement("dynamicallyModifiesClasspath", property.isDynamicClasspathModifier());
writeBooleanElement("dynamic", property.isDynamic());
writeResourceDefinition(property.getResourceDefinition());
@ -187,11 +201,13 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
}
private void writeResourceDefinition(final ResourceDefinition resourceDefinition) throws IOException {
if (resourceDefinition == null) {
return;
}
writeStartElement("resourceDefinition");
if (resourceDefinition != null) {
writeTextElement("cardinality", resourceDefinition.getCardinality().name());
writeArray("resourceTypes", resourceDefinition.getResourceTypes(), this::writeResourceType);
}
writeEndElement();
}
@ -237,6 +253,9 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeDynamicProperties(final List<DynamicProperty> dynamicProperties) throws IOException {
if (dynamicProperties == null || dynamicProperties.isEmpty()) {
return;
}
writeArray("dynamicProperties", dynamicProperties, this::writeDynamicProperty);
}
@ -254,21 +273,24 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeStatefulInfo(final Stateful stateful) throws IOException {
writeStartElement("stateful");
if (stateful != null) {
writeTextElement("description", stateful.description());
writeArray("scopes", Arrays.asList(stateful.scopes()), scope -> writeTextElement("scope", scope.name()));
if (stateful == null) {
return;
}
writeStartElement("stateful");
writeTextElement("description", stateful.description());
writeArray("scopes", Arrays.asList(stateful.scopes()), scope -> writeTextElement("scope", scope.name()));
writeEndElement();
}
@Override
protected void writeRestrictedInfo(final Restricted restricted) throws IOException {
if (restricted == null) {
return;
}
writeStartElement("restricted");
if (restricted != null) {
if (restricted.value() != null && !restricted.value().isEmpty()) {
writeTextElement("generalRestrictionExplanation", restricted.value());
}
@ -277,7 +299,6 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
if (restrictions != null) {
writeArray("restrictions", Arrays.asList(restrictions), this::writeRestriction);
}
}
writeEndElement();
}
@ -295,11 +316,17 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeInputRequirementInfo(final InputRequirement.Requirement requirement) throws IOException {
writeTextElement("inputRequirement", requirement == null ? null : requirement.name());
if (requirement == null) {
return;
}
writeTextElement("inputRequirement", requirement.name());
}
@Override
protected void writeSystemResourceConsiderationInfo(final List<SystemResourceConsideration> considerations) throws IOException {
if (considerations == null || considerations.isEmpty()) {
return;
}
writeArray("systemResourceConsiderations", considerations, this::writeSystemResourceConsideration);
}
@ -315,7 +342,6 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeSeeAlso(final SeeAlso seeAlso) throws IOException {
if (seeAlso == null) {
writeEmptyElement("seeAlso");
return;
}
@ -338,6 +364,10 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeRelationships(final Set<Relationship> relationships) throws IOException {
if (relationships == null || relationships.isEmpty()) {
return;
}
writeArray("relationships", relationships,rel -> {
writeStartElement("relationship");
@ -351,18 +381,21 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeDynamicRelationship(final DynamicRelationship dynamicRelationship) throws IOException {
writeStartElement("dynamicRelationship");
if (dynamicRelationship != null) {
writeTextElement("name", dynamicRelationship.name());
writeTextElement("description", dynamicRelationship.description());
if (dynamicRelationship == null) {
return;
}
writeStartElement("dynamicRelationship");
writeTextElement("name", dynamicRelationship.name());
writeTextElement("description", dynamicRelationship.description());
writeEndElement();
}
@Override
protected void writeReadsAttributes(final List<ReadsAttribute> attributes) throws IOException {
if (attributes == null || attributes.isEmpty()) {
return;
}
writeArray("readsAttributes", attributes, this::writeReadsAttribute);
}
@ -375,6 +408,9 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeWritesAttributes(final List<WritesAttribute> attributes) throws IOException {
if (attributes == null) {
return;
}
writeArray("writesAttributes", attributes, this::writeWritesAttribute);
}
@ -392,6 +428,9 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
@Override
protected void writeProvidedServices(final Collection<ServiceAPI> providedServices) throws IOException {
if (providedServices == null || providedServices.isEmpty()) {
return;
}
writeArray("providedServiceAPIs", providedServices, this::writeProvidedService);
}

View File

@ -247,6 +247,31 @@ public class TestJacksonExtensionManifestParser {
assertEquals(ResourceType.FILE, resourceTypes.get(0));
}
@Test
public void testBundleAndBuildInfo() throws IOException {
final ExtensionManifest extensionManifest = parse("src/test/resources/descriptors/extension-manifest-kafka-2-6-nar.xml");
assertNotNull(extensionManifest);
assertEquals("org.apache.nifi", extensionManifest.getGroupId());
assertEquals("nifi-kafka-2-6-nar", extensionManifest.getArtifactId());
assertEquals("1.16.0-SNAPSHOT", extensionManifest.getVersion());
assertNotNull(extensionManifest.getParentNar());
assertEquals("org.apache.nifi", extensionManifest.getParentNar().getGroupId());
assertEquals("nifi-standard-services-api-nar", extensionManifest.getParentNar().getArtifactId());
assertEquals("1.16.0-SNAPSHOT", extensionManifest.getParentNar().getVersion());
assertNotNull(extensionManifest.getBuildInfo());
assertEquals("nifi-1.15.0-RC3", extensionManifest.getBuildInfo().getTag());
assertEquals("main", extensionManifest.getBuildInfo().getBranch());
assertEquals("123", extensionManifest.getBuildInfo().getRevision());
assertEquals("1.8.0_282", extensionManifest.getBuildInfo().getJdk());
assertEquals("jsmith", extensionManifest.getBuildInfo().getBuiltBy());
assertEquals("2021-11-29T15:18:55Z", extensionManifest.getBuildInfo().getTimestamp());
assertEquals("1.16.0-SNAPSHOT", extensionManifest.getSystemApiVersion());
}
private ExtensionManifest parse(final String file) throws IOException {
try (final InputStream inputStream = new FileInputStream(file)) {
return parser.parse(inputStream);

View File

@ -1,5 +1,21 @@
<extensionManifest>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-kafka-2-6-nar</artifactId>
<version>1.16.0-SNAPSHOT</version>
<parentNar>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-standard-services-api-nar</artifactId>
<version>1.16.0-SNAPSHOT</version>
</parentNar>
<systemApiVersion>1.16.0-SNAPSHOT</systemApiVersion>
<buildInfo>
<tag>nifi-1.15.0-RC3</tag>
<branch>main</branch>
<revision>123</revision>
<jdk>1.8.0_282</jdk>
<builtBy>jsmith</builtBy>
<timestamp>2021-11-29T15:18:55Z</timestamp>
</buildInfo>
<extensions>
<extension>
<name>org.apache.nifi.processors.kafka.pubsub.ConsumeKafka_2_6</name>

View File

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.registry.extension.component.manifest;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ApiModel
@XmlAccessorType(XmlAccessType.FIELD)
public class BuildInfo {
private String tag;
private String branch;
private String revision;
private String jdk;
private String builtBy;
private String timestamp;
@ApiModelProperty(value = "The tag the NAR was built from")
public String getTag() {
return tag;
}
public void setTag(String tag) {
this.tag = tag;
}
@ApiModelProperty(value = "The branch the NAR was built from")
public String getBranch() {
return branch;
}
public void setBranch(String branch) {
this.branch = branch;
}
@ApiModelProperty(value = "The revision the NAR was built from")
public String getRevision() {
return revision;
}
public void setRevision(String revision) {
this.revision = revision;
}
@ApiModelProperty(value = "The JDK the NAR was built with")
public String getJdk() {
return jdk;
}
public void setJdk(String jdk) {
this.jdk = jdk;
}
@ApiModelProperty(value = "The OS user that performed the build")
public String getBuiltBy() {
return builtBy;
}
public void setBuiltBy(String builtBy) {
this.builtBy = builtBy;
}
@ApiModelProperty(value = "The timestamp of the build")
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}

View File

@ -17,6 +17,7 @@
package org.apache.nifi.registry.extension.component.manifest;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ -30,6 +31,14 @@ import java.util.List;
@XmlAccessorType(XmlAccessType.FIELD)
public class ExtensionManifest {
private String groupId;
private String artifactId;
private String version;
private ParentNar parentNar;
private BuildInfo buildInfo;
@XmlElement(required = true)
private String systemApiVersion;
@ -45,6 +54,43 @@ public class ExtensionManifest {
this.extensions = extensions;
}
@ApiModelProperty(value = "The group id of this NAR")
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
@ApiModelProperty(value = "The artifact id of this NAR")
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
@ApiModelProperty(value = "The version of this NAR")
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
@ApiModelProperty(value = "The info for the parent NAR of this NAR")
public ParentNar getParentNar() {
return parentNar;
}
public void setParentNar(ParentNar parentNar) {
this.parentNar = parentNar;
}
@ApiModelProperty(value = "The version of nifi-api this NAR was built against")
public String getSystemApiVersion() {
return systemApiVersion;
}
@ -53,6 +99,16 @@ public class ExtensionManifest {
this.systemApiVersion = systemApiVersion;
}
@ApiModelProperty(value = "The build info for the NAR")
public BuildInfo getBuildInfo() {
return buildInfo;
}
public void setBuildInfo(BuildInfo buildInfo) {
this.buildInfo = buildInfo;
}
@ApiModelProperty(value = "The list of extensions contained in this NAR")
public List<Extension> getExtensions() {
return extensions;
}

View File

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.registry.extension.component.manifest;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
@ApiModel
@XmlAccessorType(XmlAccessType.FIELD)
public class ParentNar {
private String groupId;
private String artifactId;
private String version;
@ApiModelProperty(value = "The group id of the parent NAR")
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
@ApiModelProperty(value = "The artifact id of the parent NAR")
public String getArtifactId() {
return artifactId;
}
public void setArtifactId(String artifactId) {
this.artifactId = artifactId;
}
@ApiModelProperty(value = "The version of the parent NAR")
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
}

View File

@ -706,7 +706,7 @@
<plugin>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-nar-maven-plugin</artifactId>
<version>1.3.2</version>
<version>1.3.3</version>
<extensions>true</extensions>
<configuration>
<enforceDocGeneration>true</enforceDocGeneration>