mirror of https://github.com/apache/nifi.git
NIFI-9452 Generate a RuntimeManifest for NiFi at build time
- Write additional fields to extnesion-manifest.xml for processors - Update C2 model classes to support new fields for processors, properties, and scheduling - Create converter between NiFi model and C2 model - Create generator and execute during the build Add profile to nifi-assembly that skips the binary assembly, update github workflow to enable this profile instead of excluding nifi-assembly Add additional documentation on new fields in processor definition and reporting task definition Set charset to UTF-8 on the OutputStreamWriter Signed-off-by: Matthew Burgess <mattyb149@apache.org> This closes #5612
This commit is contained in:
parent
9747d6a410
commit
0f02dac3fa
|
@ -36,8 +36,8 @@ env:
|
|||
MAVEN_PROFILES: >-
|
||||
-P contrib-check
|
||||
-P include-grpc
|
||||
-P skip-nifi-bin-assembly
|
||||
MAVEN_PROJECTS: >-
|
||||
-pl -nifi-assembly
|
||||
-pl -nifi-toolkit/nifi-toolkit-assembly
|
||||
-pl -nifi-registry/nifi-registry-assembly
|
||||
-pl -minifi/minifi-assembly
|
||||
|
|
|
@ -15,9 +15,9 @@ 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.
|
||||
-->
|
||||
<project xmlns="https://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>c2-protocol</artifactId>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
|
|
|
@ -37,8 +37,25 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
private List<Relationship> supportedRelationships;
|
||||
private boolean supportsDynamicRelationships;
|
||||
|
||||
private boolean triggerSerially;
|
||||
private boolean triggerWhenEmpty;
|
||||
private boolean triggerWhenAnyDestinationAvailable;
|
||||
private boolean supportsBatching;
|
||||
private boolean supportsEventDriven;
|
||||
private boolean primaryNodeOnly;
|
||||
private boolean sideEffectFree;
|
||||
|
||||
private List<String> supportedSchedulingStrategies;
|
||||
private String defaultSchedulingStrategy;
|
||||
private Map<String, Integer> defaultConcurrentTasksBySchedulingStrategy;
|
||||
private Map<String, String> defaultSchedulingPeriodBySchedulingStrategy;
|
||||
|
||||
private String defaultPenaltyDuration;
|
||||
private String defaultYieldDuration;
|
||||
private String defaultBulletinLevel;
|
||||
|
||||
@Override
|
||||
@ApiModelProperty("Descriptions of configuration properties applicable to this reporting task")
|
||||
@ApiModelProperty("Descriptions of configuration properties applicable to this processor.")
|
||||
public Map<String, PropertyDescriptor> getPropertyDescriptors() {
|
||||
return (propertyDescriptors != null ? Collections.unmodifiableMap(propertyDescriptors) : null);
|
||||
}
|
||||
|
@ -49,7 +66,7 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
}
|
||||
|
||||
@Override
|
||||
@ApiModelProperty("Whether or not this processor makes use of dynamic (user-set) properties")
|
||||
@ApiModelProperty("Whether or not this processor makes use of dynamic (user-set) properties.")
|
||||
public boolean getSupportsDynamicProperties() {
|
||||
return supportsDynamicProperties;
|
||||
}
|
||||
|
@ -59,7 +76,7 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
this.supportsDynamicProperties = supportsDynamicProperties;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Any input requirements this processor has")
|
||||
@ApiModelProperty("Any input requirements this processor has.")
|
||||
public InputRequirement.Requirement getInputRequirement() {
|
||||
return inputRequirement;
|
||||
}
|
||||
|
@ -68,7 +85,7 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
this.inputRequirement = inputRequirement;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The supported relationships for this processor")
|
||||
@ApiModelProperty("The supported relationships for this processor.")
|
||||
public List<Relationship> getSupportedRelationships() {
|
||||
return (supportedRelationships == null ? Collections.emptyList() : Collections.unmodifiableList(supportedRelationships));
|
||||
}
|
||||
|
@ -77,7 +94,7 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
this.supportedRelationships = supportedRelationships;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor supports dynamic relationships")
|
||||
@ApiModelProperty("Whether or not this processor supports dynamic relationships.")
|
||||
public boolean getSupportsDynamicRelationships() {
|
||||
return supportsDynamicRelationships;
|
||||
}
|
||||
|
@ -85,4 +102,136 @@ public class ProcessorDefinition extends ExtensionComponent implements Configura
|
|||
public void setSupportsDynamicRelationships(boolean supportsDynamicRelationships) {
|
||||
this.supportsDynamicRelationships = supportsDynamicRelationships;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor should be triggered serially (i.e. no concurrent execution).")
|
||||
public boolean getTriggerSerially() {
|
||||
return triggerSerially;
|
||||
}
|
||||
|
||||
public void setTriggerSerially(boolean triggerSerially) {
|
||||
this.triggerSerially = triggerSerially;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor should be triggered when incoming queues are empty.")
|
||||
public boolean getTriggerWhenEmpty() {
|
||||
return triggerWhenEmpty;
|
||||
}
|
||||
|
||||
public void setTriggerWhenEmpty(boolean triggerWhenEmpty) {
|
||||
this.triggerWhenEmpty = triggerWhenEmpty;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor should be triggered when any destination queue has room.")
|
||||
public boolean getTriggerWhenAnyDestinationAvailable() {
|
||||
return triggerWhenAnyDestinationAvailable;
|
||||
}
|
||||
|
||||
public void setTriggerWhenAnyDestinationAvailable(boolean triggerWhenAnyDestinationAvailable) {
|
||||
this.triggerWhenAnyDestinationAvailable = triggerWhenAnyDestinationAvailable;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor supports batching. If a Processor uses this annotation, " +
|
||||
"it allows the Framework to batch calls to session commits, as well as allowing the Framework to return " +
|
||||
"the same session multiple times.")
|
||||
public boolean getSupportsBatching() {
|
||||
return supportsBatching;
|
||||
}
|
||||
|
||||
public void setSupportsBatching(boolean supportsBatching) {
|
||||
this.supportsBatching = supportsBatching;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor supports event driven scheduling. Indicates to the framework that the " +
|
||||
"Processor is eligible to be scheduled to run based on the occurrence of an \"Event\" " +
|
||||
"(e.g., when a FlowFile is enqueued in an incoming Connection), rather than being triggered periodically.")
|
||||
public boolean getSupportsEventDriven() {
|
||||
return supportsEventDriven;
|
||||
}
|
||||
|
||||
public void setSupportsEventDriven(boolean supportsEventDriven) {
|
||||
this.supportsEventDriven = supportsEventDriven;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor should be scheduled only on the primary node in a cluster.")
|
||||
public boolean getPrimaryNodeOnly() {
|
||||
return primaryNodeOnly;
|
||||
}
|
||||
|
||||
public void setPrimaryNodeOnly(boolean primaryNodeOnly) {
|
||||
this.primaryNodeOnly = primaryNodeOnly;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Whether or not this processor is considered side-effect free. Side-effect free indicate that the " +
|
||||
"processor's operations on FlowFiles can be safely repeated across process sessions.")
|
||||
public boolean getSideEffectFree() {
|
||||
return sideEffectFree;
|
||||
}
|
||||
|
||||
public void setSideEffectFree(boolean sideEffectFree) {
|
||||
this.sideEffectFree = sideEffectFree;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The supported scheduling strategies, such as TIME_DRIVER, CRON, or EVENT_DRIVEN.")
|
||||
public List<String> getSupportedSchedulingStrategies() {
|
||||
return supportedSchedulingStrategies;
|
||||
}
|
||||
|
||||
public void setSupportedSchedulingStrategies(List<String> supportedSchedulingStrategies) {
|
||||
this.supportedSchedulingStrategies = supportedSchedulingStrategies;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default scheduling strategy for the processor.")
|
||||
public String getDefaultSchedulingStrategy() {
|
||||
return defaultSchedulingStrategy;
|
||||
}
|
||||
|
||||
public void setDefaultSchedulingStrategy(String defaultSchedulingStrategy) {
|
||||
this.defaultSchedulingStrategy = defaultSchedulingStrategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default concurrent tasks for each scheduling strategy.")
|
||||
public Map<String, Integer> getDefaultConcurrentTasksBySchedulingStrategy() {
|
||||
return defaultConcurrentTasksBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultConcurrentTasksBySchedulingStrategy) : null;
|
||||
}
|
||||
|
||||
public void setDefaultConcurrentTasksBySchedulingStrategy(Map<String, Integer> defaultConcurrentTasksBySchedulingStrategy) {
|
||||
this.defaultConcurrentTasksBySchedulingStrategy = defaultConcurrentTasksBySchedulingStrategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default scheduling period for each scheduling strategy. " +
|
||||
"The scheduling period is expected to be a time period, such as \"30 sec\".")
|
||||
public Map<String, String> getDefaultSchedulingPeriodBySchedulingStrategy() {
|
||||
return defaultSchedulingPeriodBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultSchedulingPeriodBySchedulingStrategy) : null;
|
||||
}
|
||||
|
||||
public void setDefaultSchedulingPeriodBySchedulingStrategy(Map<String, String> defaultSchedulingPeriodBySchedulingStrategy) {
|
||||
this.defaultSchedulingPeriodBySchedulingStrategy = defaultSchedulingPeriodBySchedulingStrategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default penalty duration as a time period, such as \"30 sec\".")
|
||||
public String getDefaultPenaltyDuration() {
|
||||
return defaultPenaltyDuration;
|
||||
}
|
||||
|
||||
public void setDefaultPenaltyDuration(String defaultPenaltyDuration) {
|
||||
this.defaultPenaltyDuration = defaultPenaltyDuration;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default yield duration as a time period, such as \"1 sec\".")
|
||||
public String getDefaultYieldDuration() {
|
||||
return defaultYieldDuration;
|
||||
}
|
||||
|
||||
public void setDefaultYieldDuration(String defaultYieldDuration) {
|
||||
this.defaultYieldDuration = defaultYieldDuration;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default bulletin level, such as WARN, INFO, DEBUG, etc.")
|
||||
public String getDefaultBulletinLevel() {
|
||||
return defaultBulletinLevel;
|
||||
}
|
||||
|
||||
public void setDefaultBulletinLevel(String defaultBulletinLevel) {
|
||||
this.defaultBulletinLevel = defaultBulletinLevel;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.c2.protocol.component.api;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@ApiModel
|
||||
public class PropertyDependency implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String propertyName;
|
||||
private String propertyDisplayName;
|
||||
private List<String> dependentValues;
|
||||
|
||||
@ApiModelProperty("The name of the property that is depended upon")
|
||||
public String getPropertyName() {
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
public void setPropertyName(String propertyName) {
|
||||
this.propertyName = propertyName;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The name of the property that is depended upon")
|
||||
public String getPropertyDisplayName() {
|
||||
return propertyDisplayName;
|
||||
}
|
||||
|
||||
public void setPropertyDisplayName(String propertyDisplayName) {
|
||||
this.propertyDisplayName = propertyDisplayName;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The values that satisfy the dependency")
|
||||
public List<String> getDependentValues() {
|
||||
return dependentValues;
|
||||
}
|
||||
|
||||
public void setDependentValues(List<String> dependentValues) {
|
||||
this.dependentValues = dependentValues;
|
||||
}
|
||||
|
||||
}
|
|
@ -42,6 +42,8 @@ public class PropertyDescriptor implements Serializable {
|
|||
private String validRegex;
|
||||
private String validator;
|
||||
private boolean dynamic;
|
||||
private PropertyResourceDefinition resourceDefinition;
|
||||
private List<PropertyDependency> dependencies;
|
||||
|
||||
@ApiModelProperty(value = "The name of the property key", required = true)
|
||||
public String getName() {
|
||||
|
@ -156,4 +158,22 @@ public class PropertyDescriptor implements Serializable {
|
|||
public void setDynamic(boolean dynamic) {
|
||||
this.dynamic = dynamic;
|
||||
}
|
||||
|
||||
@ApiModelProperty("Indicates that this property references external resources")
|
||||
public PropertyResourceDefinition getResourceDefinition() {
|
||||
return resourceDefinition;
|
||||
}
|
||||
|
||||
public void setResourceDefinition(PropertyResourceDefinition resourceDefinition) {
|
||||
this.resourceDefinition = resourceDefinition;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The dependencies that this property has on other properties")
|
||||
public List<PropertyDependency> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(List<PropertyDependency> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.c2.protocol.component.api;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.components.resource.ResourceCardinality;
|
||||
import org.apache.nifi.components.resource.ResourceType;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
@ApiModel
|
||||
public class PropertyResourceDefinition implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ResourceCardinality cardinality;
|
||||
private Set<ResourceType> resourceTypes;
|
||||
|
||||
@ApiModelProperty("The cardinality of the resource definition (i.e. single or multiple)")
|
||||
public ResourceCardinality getCardinality() {
|
||||
return cardinality;
|
||||
}
|
||||
|
||||
public void setCardinality(ResourceCardinality cardinality) {
|
||||
this.cardinality = cardinality;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The types of resources that can be referenced")
|
||||
public Set<ResourceType> getResourceTypes() {
|
||||
return resourceTypes;
|
||||
}
|
||||
|
||||
public void setResourceTypes(Set<ResourceType> resourceTypes) {
|
||||
this.resourceTypes = resourceTypes;
|
||||
}
|
||||
|
||||
}
|
|
@ -32,7 +32,7 @@ public class ReportingTaskDefinition extends ExtensionComponent implements Confi
|
|||
private Map<String, PropertyDescriptor> propertyDescriptors;
|
||||
private List<String> supportedSchedulingStrategies;
|
||||
private String defaultSchedulingStrategy;
|
||||
private Map<String, Map<String, String>> defaultValuesBySchedulingStrategy;
|
||||
private Map<String, String> defaultSchedulingPeriodBySchedulingStrategy;
|
||||
private boolean supportsDynamicProperties;
|
||||
|
||||
@Override
|
||||
|
@ -57,7 +57,7 @@ public class ReportingTaskDefinition extends ExtensionComponent implements Confi
|
|||
this.supportsDynamicProperties = supportsDynamicProperties;
|
||||
}
|
||||
|
||||
@ApiModelProperty
|
||||
@ApiModelProperty("The supported scheduling strategies, such as TIME_DRIVER or CRON.")
|
||||
public List<String> getSupportedSchedulingStrategies() {
|
||||
return (supportedSchedulingStrategies != null ? Collections.unmodifiableList(supportedSchedulingStrategies) : null);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public class ReportingTaskDefinition extends ExtensionComponent implements Confi
|
|||
this.supportedSchedulingStrategies = supportedSchedulingStrategies;
|
||||
}
|
||||
|
||||
@ApiModelProperty
|
||||
@ApiModelProperty("The default scheduling strategy for the reporting task.")
|
||||
public String getDefaultSchedulingStrategy() {
|
||||
return defaultSchedulingStrategy;
|
||||
}
|
||||
|
@ -75,12 +75,14 @@ public class ReportingTaskDefinition extends ExtensionComponent implements Confi
|
|||
this.defaultSchedulingStrategy = defaultSchedulingStrategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty
|
||||
public Map<String, Map<String, String>> getDefaultValuesBySchedulingStrategy() {
|
||||
return (defaultValuesBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultValuesBySchedulingStrategy) : null);
|
||||
@ApiModelProperty("The default scheduling period for each scheduling strategy. " +
|
||||
"The scheduling period is expected to be a time period, such as \"30 sec\".")
|
||||
public Map<String, String> getDefaultSchedulingPeriodBySchedulingStrategy() {
|
||||
return defaultSchedulingPeriodBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultSchedulingPeriodBySchedulingStrategy) : null;
|
||||
}
|
||||
|
||||
public void setDefaultValuesBySchedulingStrategy(Map<String, Map<String, String>> defaultValuesBySchedulingStrategy) {
|
||||
this.defaultValuesBySchedulingStrategy = defaultValuesBySchedulingStrategy;
|
||||
public void setDefaultSchedulingPeriodBySchedulingStrategy(Map<String, String> defaultSchedulingPeriodBySchedulingStrategy) {
|
||||
this.defaultSchedulingPeriodBySchedulingStrategy = defaultSchedulingPeriodBySchedulingStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import io.swagger.annotations.ApiModelProperty;
|
|||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
@ApiModel
|
||||
public class SchedulingDefaults implements Serializable {
|
||||
|
@ -34,6 +36,9 @@ public class SchedulingDefaults implements Serializable {
|
|||
private long defaultRunDurationNanos;
|
||||
private String defaultMaxConcurrentTasks;
|
||||
|
||||
private Map<String, Integer> defaultConcurrentTasksBySchedulingStrategy;
|
||||
private Map<String, String> defaultSchedulingPeriodsBySchedulingStrategy;
|
||||
|
||||
@ApiModelProperty("The name of the default scheduling strategy")
|
||||
public SchedulingStrategy getDefaultSchedulingStrategy() {
|
||||
return defaultSchedulingStrategy;
|
||||
|
@ -88,4 +93,22 @@ public class SchedulingDefaults implements Serializable {
|
|||
this.defaultMaxConcurrentTasks = defaultMaxConcurrentTasks;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default concurrent tasks for each scheduling strategy")
|
||||
public Map<String, Integer> getDefaultConcurrentTasksBySchedulingStrategy() {
|
||||
return defaultConcurrentTasksBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultConcurrentTasksBySchedulingStrategy) : null;
|
||||
}
|
||||
|
||||
public void setDefaultConcurrentTasksBySchedulingStrategy(Map<String, Integer> defaultConcurrentTasksBySchedulingStrategy) {
|
||||
this.defaultConcurrentTasksBySchedulingStrategy = defaultConcurrentTasksBySchedulingStrategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default scheduling period for each scheduling strategy")
|
||||
public Map<String, String> getDefaultSchedulingPeriodsBySchedulingStrategy() {
|
||||
return defaultSchedulingPeriodsBySchedulingStrategy != null ? Collections.unmodifiableMap(defaultSchedulingPeriodsBySchedulingStrategy) : null;
|
||||
}
|
||||
|
||||
public void setDefaultSchedulingPeriodsBySchedulingStrategy(Map<String, String> defaultSchedulingPeriodsBySchedulingStrategy) {
|
||||
this.defaultSchedulingPeriodsBySchedulingStrategy = defaultSchedulingPeriodsBySchedulingStrategy;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,14 +19,23 @@ package org.apache.nifi.documentation;
|
|||
import org.apache.nifi.annotation.behavior.DynamicProperties;
|
||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||
import org.apache.nifi.annotation.behavior.DynamicRelationship;
|
||||
import org.apache.nifi.annotation.behavior.EventDriven;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.annotation.behavior.PrimaryNodeOnly;
|
||||
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
||||
import org.apache.nifi.annotation.behavior.ReadsAttributes;
|
||||
import org.apache.nifi.annotation.behavior.Restricted;
|
||||
import org.apache.nifi.annotation.behavior.SideEffectFree;
|
||||
import org.apache.nifi.annotation.behavior.Stateful;
|
||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||
import org.apache.nifi.annotation.behavior.SystemResourceConsideration;
|
||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||
import org.apache.nifi.annotation.behavior.TriggerWhenAnyDestinationAvailable;
|
||||
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||
import org.apache.nifi.annotation.configuration.DefaultSchedule;
|
||||
import org.apache.nifi.annotation.configuration.DefaultSettings;
|
||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||
import org.apache.nifi.annotation.documentation.DeprecationNotice;
|
||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||
|
@ -127,6 +136,15 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat
|
|||
writeDynamicRelationship(getDynamicRelationship(processor));
|
||||
writeReadsAttributes(getReadsAttributes(processor));
|
||||
writeWritesAttributes(getWritesAttributes(processor));
|
||||
|
||||
writeTriggerSerially(processor.getClass().getAnnotation(TriggerSerially.class));
|
||||
writeTriggerWhenEmpty(processor.getClass().getAnnotation(TriggerWhenEmpty.class));
|
||||
writeTriggerWhenAnyDestinationAvailable(processor.getClass().getAnnotation(TriggerWhenAnyDestinationAvailable.class));
|
||||
writeSupportsBatching(processor.getClass().getAnnotation(SupportsBatching.class));
|
||||
writeEventDriven(processor.getClass().getAnnotation(EventDriven.class));
|
||||
writePrimaryNodeOnly(processor.getClass().getAnnotation(PrimaryNodeOnly.class));
|
||||
writeSideEffectFree(processor.getClass().getAnnotation(SideEffectFree.class));
|
||||
writeDefaultSettings(processor.getClass().getAnnotation(DefaultSettings.class));
|
||||
}
|
||||
|
||||
writeStatefulInfo(component.getClass().getAnnotation(Stateful.class));
|
||||
|
@ -134,9 +152,9 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat
|
|||
writeInputRequirementInfo(getInputRequirement(component));
|
||||
writeSystemResourceConsiderationInfo(getSystemResourceConsiderations(component));
|
||||
writeSeeAlso(component.getClass().getAnnotation(SeeAlso.class));
|
||||
writeDefaultSchedule(component.getClass().getAnnotation(DefaultSchedule.class));
|
||||
}
|
||||
|
||||
|
||||
protected String getDescription(final ConfigurableComponent component) {
|
||||
final CapabilityDescription capabilityDescription = component.getClass().getAnnotation(CapabilityDescription.class);
|
||||
if (capabilityDescription == null) {
|
||||
|
@ -265,7 +283,7 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat
|
|||
|
||||
protected abstract void writeSeeAlso(SeeAlso seeAlso) throws IOException;
|
||||
|
||||
|
||||
protected abstract void writeDefaultSchedule(DefaultSchedule defaultSchedule) throws IOException;
|
||||
|
||||
// Processor-specific methods
|
||||
protected abstract void writeRelationships(Set<Relationship> relationships) throws IOException;
|
||||
|
@ -276,10 +294,25 @@ public abstract class AbstractDocumentationWriter implements ExtensionDocumentat
|
|||
|
||||
protected abstract void writeWritesAttributes(List<WritesAttribute> attributes) throws IOException;
|
||||
|
||||
protected abstract void writeTriggerSerially(TriggerSerially triggerSerially) throws IOException;
|
||||
|
||||
protected abstract void writeTriggerWhenEmpty(TriggerWhenEmpty triggerWhenEmpty) throws IOException;
|
||||
|
||||
protected abstract void writeTriggerWhenAnyDestinationAvailable(TriggerWhenAnyDestinationAvailable triggerWhenAnyDestinationAvailable) throws IOException;
|
||||
|
||||
protected abstract void writeSupportsBatching(SupportsBatching supportsBatching) throws IOException;
|
||||
|
||||
protected abstract void writeEventDriven(EventDriven eventDriven) throws IOException;
|
||||
|
||||
protected abstract void writePrimaryNodeOnly(PrimaryNodeOnly primaryNodeOnly) throws IOException;
|
||||
|
||||
protected abstract void writeSideEffectFree(SideEffectFree sideEffectFree) throws IOException;
|
||||
|
||||
protected abstract void writeDefaultSettings(DefaultSettings defaultSettings) throws IOException;
|
||||
|
||||
// ControllerService-specific methods
|
||||
protected abstract void writeProvidedServices(Collection<ServiceAPI> providedServices) throws IOException;
|
||||
|
||||
|
||||
protected abstract void writeFooter(ConfigurableComponent component) throws IOException;
|
||||
|
||||
}
|
||||
|
|
|
@ -18,13 +18,22 @@ package org.apache.nifi.documentation.xml;
|
|||
|
||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||
import org.apache.nifi.annotation.behavior.DynamicRelationship;
|
||||
import org.apache.nifi.annotation.behavior.EventDriven;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.annotation.behavior.PrimaryNodeOnly;
|
||||
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
||||
import org.apache.nifi.annotation.behavior.Restricted;
|
||||
import org.apache.nifi.annotation.behavior.Restriction;
|
||||
import org.apache.nifi.annotation.behavior.SideEffectFree;
|
||||
import org.apache.nifi.annotation.behavior.Stateful;
|
||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||
import org.apache.nifi.annotation.behavior.SystemResourceConsideration;
|
||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||
import org.apache.nifi.annotation.behavior.TriggerWhenAnyDestinationAvailable;
|
||||
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||
import org.apache.nifi.annotation.configuration.DefaultSchedule;
|
||||
import org.apache.nifi.annotation.configuration.DefaultSettings;
|
||||
import org.apache.nifi.annotation.documentation.DeprecationNotice;
|
||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||
import org.apache.nifi.components.AllowableValue;
|
||||
|
@ -421,6 +430,88 @@ public class XmlDocumentationWriter extends AbstractDocumentationWriter {
|
|||
writeEndElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTriggerSerially(TriggerSerially triggerSerially) throws IOException {
|
||||
if (triggerSerially == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("triggerSerially", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTriggerWhenEmpty(TriggerWhenEmpty triggerWhenEmpty) throws IOException {
|
||||
if (triggerWhenEmpty == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("triggerWhenEmpty", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeTriggerWhenAnyDestinationAvailable(TriggerWhenAnyDestinationAvailable triggerWhenAnyDestinationAvailable) throws IOException {
|
||||
if (triggerWhenAnyDestinationAvailable == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("triggerWhenAnyDestinationAvailable", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeSupportsBatching(SupportsBatching supportsBatching) throws IOException {
|
||||
if (supportsBatching == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("supportsBatching", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeEventDriven(EventDriven eventDriven) throws IOException {
|
||||
if (eventDriven == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("eventDriven", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePrimaryNodeOnly(PrimaryNodeOnly primaryNodeOnly) throws IOException {
|
||||
if (primaryNodeOnly == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("primaryNodeOnly", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeSideEffectFree(SideEffectFree sideEffectFree) throws IOException {
|
||||
if (sideEffectFree == null) {
|
||||
return;
|
||||
}
|
||||
writeBooleanElement("sideEffectFree", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeDefaultSchedule(DefaultSchedule defaultSchedule) throws IOException {
|
||||
if (defaultSchedule == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeStartElement("defaultSchedule");
|
||||
writeTextElement("strategy", defaultSchedule.strategy().name());
|
||||
writeTextElement("period", defaultSchedule.period());
|
||||
writeTextElement("concurrentTasks", String.valueOf(defaultSchedule.concurrentTasks()));
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeDefaultSettings(DefaultSettings defaultSettings) throws IOException {
|
||||
if (defaultSettings == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
writeStartElement("defaultSettings");
|
||||
writeTextElement("yieldDuration", defaultSettings.yieldDuration());
|
||||
writeTextElement("penaltyDuration", defaultSettings.penaltyDuration());
|
||||
writeTextElement("bulletinLevel", defaultSettings.bulletinLevel().name());
|
||||
writeEndElement();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeFooter(final ConfigurableComponent component) throws IOException {
|
||||
writeEndElement();
|
||||
|
|
|
@ -1480,5 +1480,26 @@ language governing permissions and limitations under the License. -->
|
|||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>skip-nifi-bin-assembly</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>skip-nifi-bin-assembly</name>
|
||||
</property>
|
||||
</activation>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make shared resource</id>
|
||||
<phase>none</phase>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-manifest</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-runtime-manifest-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>c2-protocol-component-api</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-bundle-utils</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi.registry</groupId>
|
||||
<artifactId>nifi-registry-data-model</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.runtime.manifest;
|
||||
|
||||
import org.apache.nifi.c2.protocol.component.api.ComponentManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.ControllerServiceDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.ProcessorDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.ReportingTaskDefinition;
|
||||
|
||||
/**
|
||||
* Builder for creating a ComponentManifest.
|
||||
*/
|
||||
public interface ComponentManifestBuilder {
|
||||
|
||||
/**
|
||||
* @param processorDefinition a processor definition to add
|
||||
* @return the builder
|
||||
*/
|
||||
ComponentManifestBuilder addProcessor(ProcessorDefinition processorDefinition);
|
||||
|
||||
/**
|
||||
* @param controllerServiceDefinition a controller service definition to add
|
||||
* @return the builder
|
||||
*/
|
||||
ComponentManifestBuilder addControllerService(ControllerServiceDefinition controllerServiceDefinition);
|
||||
|
||||
/**
|
||||
* @param reportingTaskDefinition a reporting task definition to add
|
||||
* @return the builder
|
||||
*/
|
||||
ComponentManifestBuilder addReportingTask(ReportingTaskDefinition reportingTaskDefinition);
|
||||
|
||||
/**
|
||||
* @return a component manifest containing all the added definitions
|
||||
*/
|
||||
ComponentManifest build();
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.runtime.manifest;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides a list of extension manifests.
|
||||
*/
|
||||
public interface ExtensionManifestProvider {
|
||||
|
||||
List<ExtensionManifest> getExtensionManifests();
|
||||
|
||||
}
|
|
@ -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.runtime.manifest;
|
||||
|
||||
import org.apache.nifi.c2.protocol.component.api.BuildInfo;
|
||||
import org.apache.nifi.c2.protocol.component.api.Bundle;
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.SchedulingDefaults;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
|
||||
/**
|
||||
* Builder for creating a RuntimeManifest.
|
||||
*/
|
||||
public interface RuntimeManifestBuilder {
|
||||
|
||||
/**
|
||||
* @param identifier the identifier for the manifest
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder identifier(String identifier);
|
||||
|
||||
/**
|
||||
* @param version the version for the manifest
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder version(String version);
|
||||
|
||||
/**
|
||||
* @param runtimeType the runtime type (i.e. nifi, nifi-stateless, minifi-cpp, etc)
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder runtimeType(String runtimeType);
|
||||
|
||||
/**
|
||||
* @param buildInfo the build info for the manifest
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder buildInfo(BuildInfo buildInfo);
|
||||
|
||||
/**
|
||||
* Adds a Bundle from the given ExtensionManifest.
|
||||
*
|
||||
* @param extensionManifest the extension manifest to add
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder addBundle(ExtensionManifest extensionManifest);
|
||||
|
||||
/**
|
||||
* Adds a Bundle for each of the given ExtensionManifests.
|
||||
*
|
||||
* @param extensionManifests the extension manifests to add
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder addBundles(Iterable<ExtensionManifest> extensionManifests);
|
||||
|
||||
/**
|
||||
* Adds the given Bundle.
|
||||
*
|
||||
* @param bundle the bundle to add
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder addBundle(Bundle bundle);
|
||||
|
||||
/**
|
||||
* @param schedulingDefaults the scheduling defaults
|
||||
* @return the builder
|
||||
*/
|
||||
RuntimeManifestBuilder schedulingDefaults(SchedulingDefaults schedulingDefaults);
|
||||
|
||||
/**
|
||||
* @return a RuntimeManifest containing the added bundles
|
||||
*/
|
||||
RuntimeManifest build();
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.runtime.manifest;
|
||||
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Serializer for runtime manifests.
|
||||
*/
|
||||
public interface RuntimeManifestSerializer {
|
||||
|
||||
/**
|
||||
* Serializes the given RuntimeManifest to the given OutputStream.
|
||||
*
|
||||
* @param runtimeManifest the runtime manifest
|
||||
* @param outputStream the output stream
|
||||
* @throws IOException if an I/O error occurs during serialization
|
||||
*/
|
||||
void write(RuntimeManifest runtimeManifest, OutputStream outputStream) throws IOException;
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import org.apache.nifi.registry.bundle.extract.nar.docs.ExtensionManifestParser;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
import org.apache.nifi.runtime.manifest.ExtensionManifestProvider;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* ExtensionManifestProvider that loads extension manifests from a directory where the nifi-assembly-manifests
|
||||
* artifact was unpacked.
|
||||
*/
|
||||
public class DirectoryExtensionManifestProvider implements ExtensionManifestProvider {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DirectoryExtensionManifestProvider.class);
|
||||
|
||||
private final File baseDir;
|
||||
private final ExtensionManifestParser extensionManifestParser;
|
||||
|
||||
public DirectoryExtensionManifestProvider(final File baseDir, final ExtensionManifestParser extensionManifestParser) {
|
||||
this.baseDir = baseDir;
|
||||
this.extensionManifestParser = extensionManifestParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ExtensionManifest> getExtensionManifests() {
|
||||
if (!baseDir.exists()) {
|
||||
throw new IllegalArgumentException("The specified manifest directory does not exist");
|
||||
}
|
||||
if (!baseDir.isDirectory()) {
|
||||
throw new IllegalArgumentException("The specified manifest location is not a directory");
|
||||
}
|
||||
|
||||
LOGGER.info("Loading extension manifests from: {}", baseDir.getAbsolutePath());
|
||||
|
||||
final List<ExtensionManifest> extensionManifests = new ArrayList<>();
|
||||
for (final File manifestDir : baseDir.listFiles()) {
|
||||
if (!manifestDir.isDirectory()) {
|
||||
LOGGER.debug("Skipping [{}], not a directory...", manifestDir.getAbsolutePath());
|
||||
continue;
|
||||
}
|
||||
|
||||
final File manifestFile = new File(manifestDir, "extension-manifest.xml");
|
||||
LOGGER.debug("Loading extension manifest file [{}]", manifestFile.getAbsolutePath());
|
||||
|
||||
final ExtensionManifest extensionManifest = loadExtensionManifest(manifestFile);
|
||||
extensionManifests.add(extensionManifest);
|
||||
LOGGER.debug("Successfully loaded extension manifest for [{}-{}-{}]",
|
||||
extensionManifest.getGroupId(), extensionManifest.getArtifactId(), extensionManifest.getVersion());
|
||||
}
|
||||
|
||||
LOGGER.info("Loaded {} extension manifests", extensionManifests.size());
|
||||
return extensionManifests;
|
||||
}
|
||||
|
||||
private ExtensionManifest loadExtensionManifest(final File manifestFile) {
|
||||
try (final InputStream inputStream = new FileInputStream(manifestFile)) {
|
||||
return extensionManifestParser.parse(inputStream);
|
||||
} catch (final IOException ioException) {
|
||||
throw new RuntimeException("Unable to load extension manifest: " + manifestFile.getAbsolutePath(), ioException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
import org.apache.nifi.runtime.manifest.RuntimeManifestSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Jackson implementation of RuntimeManifestSerializer.
|
||||
*/
|
||||
public class JacksonRuntimeManifestSerializer implements RuntimeManifestSerializer {
|
||||
|
||||
private final ObjectWriter objectWriter;
|
||||
|
||||
public JacksonRuntimeManifestSerializer(final ObjectWriter objectWriter) {
|
||||
this.objectWriter = objectWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(final RuntimeManifest runtimeManifest, final OutputStream outputStream) throws IOException {
|
||||
try (final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
|
||||
objectWriter.writeValue(outputStreamWriter, runtimeManifest);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import org.apache.nifi.c2.protocol.component.api.BuildInfo;
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
import org.apache.nifi.registry.bundle.extract.nar.docs.ExtensionManifestParser;
|
||||
import org.apache.nifi.registry.bundle.extract.nar.docs.JacksonExtensionManifestParser;
|
||||
import org.apache.nifi.runtime.manifest.ExtensionManifestProvider;
|
||||
import org.apache.nifi.runtime.manifest.RuntimeManifestSerializer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Runner class to be called during the build to generate a runtime manifest json file from a directory where
|
||||
* all the extension-manifest.xml files have been unpacked.
|
||||
*/
|
||||
public class RuntimeManifestGenerator {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RuntimeManifestGenerator.class);
|
||||
|
||||
private static final String PROJECT_VERSION_PROPERTY = "Project-Version";
|
||||
private static final String BUILD_REVISION = "Build-Revision";
|
||||
private static final String BUILD_TIMESTAMP = "Build-Timestamp";
|
||||
private static final String BUILD_JDK = "Build-Jdk";
|
||||
private static final String BUILD_JDK_VENDOR = "Build-Jdk-Vendor";
|
||||
|
||||
private final File extensionManifestBaseDir;
|
||||
private final File buildPropertiesFile;
|
||||
private final File runtimeManifestFile;
|
||||
private final String runtimeManifestId;
|
||||
|
||||
public RuntimeManifestGenerator(final File extensionManifestBaseDir,
|
||||
final File buildPropertiesFile,
|
||||
final File runtimeManifestFile,
|
||||
final String runtimeManifestId) {
|
||||
this.extensionManifestBaseDir = extensionManifestBaseDir;
|
||||
this.buildPropertiesFile = buildPropertiesFile;
|
||||
this.runtimeManifestFile = runtimeManifestFile;
|
||||
this.runtimeManifestId = runtimeManifestId;
|
||||
}
|
||||
|
||||
public void execute() throws IOException {
|
||||
final ExtensionManifestProvider extensionManifestProvider = createExtensionManifestProvider();
|
||||
|
||||
final Properties buildProperties = createBuildProperties();
|
||||
final String runtimeVersion = buildProperties.getProperty(PROJECT_VERSION_PROPERTY);
|
||||
final String buildRevision = buildProperties.getProperty(BUILD_REVISION);
|
||||
final String buildTimestamp = buildProperties.getProperty(BUILD_TIMESTAMP);
|
||||
final String buildJdk = buildProperties.getProperty(BUILD_JDK);
|
||||
final String buildJdkVendor = buildProperties.getProperty(BUILD_JDK_VENDOR);
|
||||
|
||||
final BuildInfo buildInfo = new BuildInfo();
|
||||
buildInfo.setVersion(runtimeVersion);
|
||||
buildInfo.setRevision(buildRevision);
|
||||
buildInfo.setTimestamp(Long.valueOf(buildTimestamp));
|
||||
buildInfo.setCompiler(buildJdkVendor + " " + buildJdk);
|
||||
|
||||
final RuntimeManifest runtimeManifest = new StandardRuntimeManifestBuilder()
|
||||
.identifier(runtimeManifestId)
|
||||
.version(runtimeVersion)
|
||||
.runtimeType("nifi")
|
||||
.buildInfo(buildInfo)
|
||||
.addBundles(extensionManifestProvider.getExtensionManifests())
|
||||
.schedulingDefaults(SchedulingDefaultsFactory.getNifiSchedulingDefaults())
|
||||
.build();
|
||||
|
||||
final RuntimeManifestSerializer runtimeManifestSerializer = createRuntimeManifestSerializer();
|
||||
try (final OutputStream outputStream = new FileOutputStream(runtimeManifestFile)) {
|
||||
runtimeManifestSerializer.write(runtimeManifest, outputStream);
|
||||
}
|
||||
}
|
||||
|
||||
private ExtensionManifestProvider createExtensionManifestProvider() {
|
||||
final ExtensionManifestParser extensionManifestParser = new JacksonExtensionManifestParser();
|
||||
return new DirectoryExtensionManifestProvider(extensionManifestBaseDir, extensionManifestParser);
|
||||
}
|
||||
|
||||
private Properties createBuildProperties() throws IOException {
|
||||
final Properties properties = new Properties();
|
||||
try (final InputStream inputStream = new FileInputStream(buildPropertiesFile)) {
|
||||
properties.load(inputStream);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private RuntimeManifestSerializer createRuntimeManifestSerializer() {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
final ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter();
|
||||
return new JacksonRuntimeManifestSerializer(objectWriter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from maven-exec-plugin during build of nifi-runtime-manifest.
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
if (args == null || args.length != 4) {
|
||||
System.out.println("USAGE: <extension-manifest-base-dir> <build-props-file> <output-file> <manifest-id>");
|
||||
return;
|
||||
}
|
||||
|
||||
final File extensionManifestBaseDir = new File(args[0]);
|
||||
final File buildPropertiesFile = new File(args[1]);
|
||||
final File runtimeManifestFile = new File(args[2]);
|
||||
final String runtimeManifestId = args[3];
|
||||
|
||||
final File runtimeManifestDir = runtimeManifestFile.getParentFile();
|
||||
if (runtimeManifestDir != null) {
|
||||
runtimeManifestDir.mkdirs();
|
||||
}
|
||||
|
||||
LOGGER.info("Writing runtime manifest to: {}", runtimeManifestFile.getAbsolutePath());
|
||||
|
||||
final RuntimeManifestGenerator runner = new RuntimeManifestGenerator(
|
||||
extensionManifestBaseDir, buildPropertiesFile, runtimeManifestFile, runtimeManifestId);
|
||||
runner.execute();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import org.apache.nifi.c2.protocol.component.api.SchedulingDefaults;
|
||||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SchedulingDefaultsFactory {
|
||||
|
||||
public static SchedulingDefaults getNifiSchedulingDefaults() {
|
||||
final Map<String, Integer> defaultConcurrentTasks = new LinkedHashMap<>(3);
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks());
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.EVENT_DRIVEN.name(), SchedulingStrategy.EVENT_DRIVEN.getDefaultConcurrentTasks());
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks());
|
||||
|
||||
final Map<String, String> defaultSchedulingPeriods = new LinkedHashMap<>(2);
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod());
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod());
|
||||
|
||||
final SchedulingDefaults schedulingDefaults = new SchedulingDefaults();
|
||||
schedulingDefaults.setDefaultSchedulingStrategy(SchedulingStrategy.TIMER_DRIVEN);
|
||||
schedulingDefaults.setDefaultSchedulingPeriodMillis(0);
|
||||
schedulingDefaults.setPenalizationPeriodMillis(30000);
|
||||
schedulingDefaults.setYieldDurationMillis(1000);
|
||||
schedulingDefaults.setDefaultRunDurationNanos(0);
|
||||
schedulingDefaults.setDefaultMaxConcurrentTasks("1");
|
||||
schedulingDefaults.setDefaultConcurrentTasksBySchedulingStrategy(defaultConcurrentTasks);
|
||||
schedulingDefaults.setDefaultSchedulingPeriodsBySchedulingStrategy(defaultSchedulingPeriods);
|
||||
return schedulingDefaults;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import org.apache.nifi.c2.protocol.component.api.ComponentManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.ControllerServiceDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.ProcessorDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.ReportingTaskDefinition;
|
||||
import org.apache.nifi.runtime.manifest.ComponentManifestBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Standard implementation of ComponentManifestBuilder.
|
||||
*/
|
||||
public class StandardComponentManifestBuilder implements ComponentManifestBuilder {
|
||||
|
||||
private final List<ProcessorDefinition> processors = new ArrayList<>();
|
||||
private final List<ControllerServiceDefinition> controllerServices = new ArrayList<>();
|
||||
private final List<ReportingTaskDefinition> reportingTasks = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
public ComponentManifestBuilder addProcessor(final ProcessorDefinition processorDefinition) {
|
||||
if (processorDefinition == null) {
|
||||
throw new IllegalArgumentException("Processor definition cannot be null");
|
||||
}
|
||||
processors.add(processorDefinition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentManifestBuilder addControllerService(final ControllerServiceDefinition controllerServiceDefinition) {
|
||||
if (controllerServiceDefinition == null) {
|
||||
throw new IllegalArgumentException("Controller Service definition cannot be null");
|
||||
}
|
||||
controllerServices.add(controllerServiceDefinition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentManifestBuilder addReportingTask(final ReportingTaskDefinition reportingTaskDefinition) {
|
||||
if (reportingTaskDefinition == null) {
|
||||
throw new IllegalArgumentException("Reporting task definition cannot be null");
|
||||
}
|
||||
reportingTasks.add(reportingTaskDefinition);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentManifest build() {
|
||||
final ComponentManifest componentManifest = new ComponentManifest();
|
||||
componentManifest.setProcessors(new ArrayList<>(processors));
|
||||
componentManifest.setControllerServices(new ArrayList<>(controllerServices));
|
||||
componentManifest.setReportingTasks(new ArrayList<>(reportingTasks));
|
||||
return componentManifest;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,502 @@
|
|||
/*
|
||||
* 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.runtime.manifest.impl;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.c2.protocol.component.api.BuildInfo;
|
||||
import org.apache.nifi.c2.protocol.component.api.Bundle;
|
||||
import org.apache.nifi.c2.protocol.component.api.ConfigurableComponentDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.ControllerServiceDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.DefinedType;
|
||||
import org.apache.nifi.c2.protocol.component.api.ExtensionComponent;
|
||||
import org.apache.nifi.c2.protocol.component.api.ProcessorDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyAllowableValue;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyDependency;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyDescriptor;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyResourceDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.Relationship;
|
||||
import org.apache.nifi.c2.protocol.component.api.ReportingTaskDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.SchedulingDefaults;
|
||||
import org.apache.nifi.components.resource.ResourceCardinality;
|
||||
import org.apache.nifi.components.resource.ResourceType;
|
||||
import org.apache.nifi.expression.ExpressionLanguageScope;
|
||||
import org.apache.nifi.logging.LogLevel;
|
||||
import org.apache.nifi.registry.extension.component.manifest.AllowableValue;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DefaultSchedule;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DefaultSettings;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Dependency;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DependentValues;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DeprecationNotice;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ExtensionManifest;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Property;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ProvidedServiceAPI;
|
||||
import org.apache.nifi.registry.extension.component.manifest.ResourceDefinition;
|
||||
import org.apache.nifi.runtime.manifest.ComponentManifestBuilder;
|
||||
import org.apache.nifi.runtime.manifest.RuntimeManifestBuilder;
|
||||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Standard builder for RuntimeManifest.
|
||||
*/
|
||||
public class StandardRuntimeManifestBuilder implements RuntimeManifestBuilder {
|
||||
|
||||
private static final String DEFAULT_YIELD_PERIOD = "1 sec";
|
||||
private static final String DEFAULT_PENALIZATION_PERIOD = "30 sec";
|
||||
private static final String DEFAULT_BULLETIN_LEVEL = LogLevel.WARN.name();
|
||||
|
||||
private String identifier;
|
||||
private String version;
|
||||
private String runtimeType;
|
||||
private BuildInfo buildInfo;
|
||||
private List<Bundle> bundles = new ArrayList<>();
|
||||
private SchedulingDefaults schedulingDefaults;
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder identifier(final String identifier) {
|
||||
this.identifier = identifier;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder version(final String version) {
|
||||
this.version = version;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder runtimeType(final String runtimeType) {
|
||||
this.runtimeType = runtimeType;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder buildInfo(final BuildInfo buildInfo) {
|
||||
this.buildInfo = buildInfo;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder addBundle(final ExtensionManifest extensionManifest) {
|
||||
Validate.notNull(extensionManifest, "Extension manifest is required");
|
||||
Validate.notBlank(extensionManifest.getGroupId(), "Extension manifest groupId is required");
|
||||
Validate.notBlank(extensionManifest.getArtifactId(), "Extension manifest artifactId is required");
|
||||
Validate.notBlank(extensionManifest.getVersion(), "Extension manifest version is required");
|
||||
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.setGroup(extensionManifest.getGroupId());
|
||||
bundle.setArtifact(extensionManifest.getArtifactId());
|
||||
bundle.setVersion(extensionManifest.getVersion());
|
||||
|
||||
if (extensionManifest.getExtensions() != null) {
|
||||
final ComponentManifestBuilder componentManifestBuilder = new StandardComponentManifestBuilder();
|
||||
extensionManifest.getExtensions().forEach(extension -> addExtension(extensionManifest, extension, componentManifestBuilder));
|
||||
bundle.setComponentManifest(componentManifestBuilder.build());
|
||||
}
|
||||
bundles.add(bundle);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder addBundles(final Iterable<ExtensionManifest> extensionManifests) {
|
||||
extensionManifests.forEach(em -> addBundle(em));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder addBundle(Bundle bundle) {
|
||||
if (bundle == null) {
|
||||
throw new IllegalArgumentException("Bundle is required");
|
||||
}
|
||||
bundles.add(bundle);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifestBuilder schedulingDefaults(final SchedulingDefaults schedulingDefaults) {
|
||||
this.schedulingDefaults = schedulingDefaults;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeManifest build() {
|
||||
final RuntimeManifest runtimeManifest = new RuntimeManifest();
|
||||
runtimeManifest.setIdentifier(identifier);
|
||||
runtimeManifest.setVersion(version);
|
||||
runtimeManifest.setAgentType(runtimeType);
|
||||
runtimeManifest.setBuildInfo(buildInfo);
|
||||
runtimeManifest.setBundles(new ArrayList<>(bundles));
|
||||
runtimeManifest.setSchedulingDefaults(schedulingDefaults);
|
||||
return runtimeManifest;
|
||||
}
|
||||
|
||||
private void addExtension(final ExtensionManifest extensionManifest, final Extension extension, final ComponentManifestBuilder componentManifestBuilder) {
|
||||
if (extension == null) {
|
||||
throw new IllegalArgumentException("Extension cannot be null");
|
||||
}
|
||||
|
||||
switch(extension.getType()) {
|
||||
case PROCESSOR:
|
||||
addProcessorDefinition(extensionManifest, extension, componentManifestBuilder);
|
||||
break;
|
||||
case CONTROLLER_SERVICE:
|
||||
addControllerServiceDefinition(extensionManifest, extension, componentManifestBuilder);
|
||||
break;
|
||||
case REPORTING_TASK:
|
||||
addReportingTaskDefinition(extensionManifest, extension, componentManifestBuilder);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown extension type: " + extension.getType());
|
||||
}
|
||||
}
|
||||
|
||||
private void addProcessorDefinition(final ExtensionManifest extensionManifest, final Extension extension, final ComponentManifestBuilder componentManifestBuilder) {
|
||||
final ProcessorDefinition processorDefinition = new ProcessorDefinition();
|
||||
populateDefinedType(extensionManifest, extension, processorDefinition);
|
||||
populateExtensionComponent(extensionManifest, extension, processorDefinition);
|
||||
populateConfigurableComponent(extension, processorDefinition);
|
||||
|
||||
// processor specific fields
|
||||
processorDefinition.setInputRequirement(getInputRequirement(extension.getInputRequirement()));
|
||||
processorDefinition.setSupportedRelationships(getSupportedRelationships(extension.getRelationships()));
|
||||
processorDefinition.setSupportsDynamicRelationships(extension.getDynamicRelationship() != null);
|
||||
processorDefinition.setTriggerWhenEmpty(extension.getTriggerWhenEmpty());
|
||||
processorDefinition.setTriggerSerially(extension.getTriggerSerially());
|
||||
processorDefinition.setTriggerWhenAnyDestinationAvailable(extension.getTriggerWhenAnyDestinationAvailable());
|
||||
processorDefinition.setSupportsBatching(extension.getSupportsBatching());
|
||||
processorDefinition.setSupportsEventDriven(extension.getEventDriven());
|
||||
processorDefinition.setPrimaryNodeOnly(extension.getPrimaryNodeOnly());
|
||||
processorDefinition.setSideEffectFree(extension.getSideEffectFree());
|
||||
|
||||
final DefaultSettings defaultSettings = extension.getDefaultSettings();
|
||||
processorDefinition.setDefaultPenaltyDuration(defaultSettings == null ? DEFAULT_PENALIZATION_PERIOD : defaultSettings.getPenaltyDuration());
|
||||
processorDefinition.setDefaultYieldDuration(defaultSettings == null ? DEFAULT_YIELD_PERIOD : defaultSettings.getYieldDuration());
|
||||
processorDefinition.setDefaultBulletinLevel(defaultSettings == null ? DEFAULT_BULLETIN_LEVEL : defaultSettings.getBulletinLevel());
|
||||
|
||||
final List<String> schedulingStrategies = new ArrayList<>();
|
||||
schedulingStrategies.add(SchedulingStrategy.TIMER_DRIVEN.name());
|
||||
schedulingStrategies.add(SchedulingStrategy.CRON_DRIVEN.name());
|
||||
if (extension.getEventDriven()) {
|
||||
schedulingStrategies.add(SchedulingStrategy.EVENT_DRIVEN.name());
|
||||
}
|
||||
|
||||
// If a default schedule is provided then use that, otherwise default to TIMER_DRIVEN
|
||||
final DefaultSchedule defaultSchedule = extension.getDefaultSchedule();
|
||||
final String defaultSchedulingStrategy = defaultSchedule == null
|
||||
? SchedulingStrategy.TIMER_DRIVEN.name() : extension.getDefaultSchedule().getStrategy();
|
||||
|
||||
final Map<String, Integer> defaultConcurrentTasks = new LinkedHashMap<>(3);
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks());
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks());
|
||||
if (extension.getEventDriven()) {
|
||||
defaultConcurrentTasks.put(SchedulingStrategy.EVENT_DRIVEN.name(), SchedulingStrategy.EVENT_DRIVEN.getDefaultConcurrentTasks());
|
||||
}
|
||||
|
||||
final Map<String, String> defaultSchedulingPeriods = new LinkedHashMap<>(2);
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod());
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod());
|
||||
|
||||
// If a default schedule is provided then replace the default values for the default strategy
|
||||
if (defaultSchedule != null) {
|
||||
defaultSchedulingPeriods.put(defaultSchedule.getStrategy(), defaultSchedule.getPeriod());
|
||||
defaultConcurrentTasks.put(defaultSchedule.getStrategy(), Integer.valueOf(defaultSchedule.getConcurrentTasks()));
|
||||
}
|
||||
|
||||
processorDefinition.setSupportedSchedulingStrategies(schedulingStrategies);
|
||||
processorDefinition.setDefaultSchedulingStrategy(defaultSchedulingStrategy);
|
||||
processorDefinition.setDefaultConcurrentTasksBySchedulingStrategy(defaultConcurrentTasks);
|
||||
processorDefinition.setDefaultSchedulingPeriodBySchedulingStrategy(defaultSchedulingPeriods);
|
||||
|
||||
componentManifestBuilder.addProcessor(processorDefinition);
|
||||
}
|
||||
|
||||
private InputRequirement.Requirement getInputRequirement(final org.apache.nifi.registry.extension.component.manifest.InputRequirement inputRequirement) {
|
||||
if (inputRequirement == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (inputRequirement) {
|
||||
case INPUT_ALLOWED:
|
||||
return InputRequirement.Requirement.INPUT_ALLOWED;
|
||||
case INPUT_REQUIRED:
|
||||
return InputRequirement.Requirement.INPUT_REQUIRED;
|
||||
case INPUT_FORBIDDEN:
|
||||
return InputRequirement.Requirement.INPUT_FORBIDDEN;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown input requirement: " + inputRequirement.name());
|
||||
}
|
||||
}
|
||||
|
||||
private List<Relationship> getSupportedRelationships(final List<org.apache.nifi.registry.extension.component.manifest.Relationship> relationships) {
|
||||
if (relationships == null || relationships.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<Relationship> componentRelationships = new ArrayList<>();
|
||||
for (final org.apache.nifi.registry.extension.component.manifest.Relationship relationship : relationships) {
|
||||
final Relationship componentRelationship = new Relationship();
|
||||
componentRelationship.setName(relationship.getName());
|
||||
componentRelationship.setDescription(relationship.getDescription());
|
||||
componentRelationships.add(componentRelationship);
|
||||
}
|
||||
return componentRelationships;
|
||||
}
|
||||
|
||||
private void addControllerServiceDefinition(final ExtensionManifest extensionManifest, final Extension extension, final ComponentManifestBuilder componentManifestBuilder) {
|
||||
final ControllerServiceDefinition controllerServiceDefinition = new ControllerServiceDefinition();
|
||||
populateDefinedType(extensionManifest, extension, controllerServiceDefinition);
|
||||
populateExtensionComponent(extensionManifest, extension, controllerServiceDefinition);
|
||||
populateConfigurableComponent(extension, controllerServiceDefinition);
|
||||
componentManifestBuilder.addControllerService(controllerServiceDefinition);
|
||||
}
|
||||
|
||||
private void addReportingTaskDefinition(final ExtensionManifest extensionManifest, final Extension extension, final ComponentManifestBuilder componentManifestBuilder) {
|
||||
final ReportingTaskDefinition reportingTaskDefinition = new ReportingTaskDefinition();
|
||||
populateDefinedType(extensionManifest, extension, reportingTaskDefinition);
|
||||
populateDefinedType(extensionManifest, extension, reportingTaskDefinition);
|
||||
populateConfigurableComponent(extension, reportingTaskDefinition);
|
||||
|
||||
final List<String> schedulingStrategies = new ArrayList<>();
|
||||
schedulingStrategies.add(SchedulingStrategy.TIMER_DRIVEN.name());
|
||||
schedulingStrategies.add(SchedulingStrategy.CRON_DRIVEN.name());
|
||||
|
||||
// If a default schedule is provided then use that, otherwise default to TIMER_DRIVEN
|
||||
final DefaultSchedule defaultSchedule = extension.getDefaultSchedule();
|
||||
final String defaultSchedulingStrategy = defaultSchedule == null
|
||||
? SchedulingStrategy.TIMER_DRIVEN.name() : extension.getDefaultSchedule().getStrategy();
|
||||
|
||||
final Map<String, String> defaultSchedulingPeriods = new LinkedHashMap<>(2);
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod());
|
||||
defaultSchedulingPeriods.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod());
|
||||
|
||||
// If a default schedule is provided then replace the default values for the default strategy
|
||||
if (defaultSchedule != null) {
|
||||
defaultSchedulingPeriods.put(defaultSchedule.getStrategy(), defaultSchedule.getPeriod());
|
||||
}
|
||||
|
||||
reportingTaskDefinition.setSupportedSchedulingStrategies(schedulingStrategies);
|
||||
reportingTaskDefinition.setDefaultSchedulingStrategy(defaultSchedulingStrategy);
|
||||
reportingTaskDefinition.setDefaultSchedulingPeriodBySchedulingStrategy(defaultSchedulingPeriods);
|
||||
|
||||
componentManifestBuilder.addReportingTask(reportingTaskDefinition);
|
||||
}
|
||||
|
||||
private void populateDefinedType(final ExtensionManifest extensionManifest, final Extension extension, final DefinedType definedType) {
|
||||
definedType.setType(extension.getName());
|
||||
definedType.setTypeDescription(extension.getDescription());
|
||||
definedType.setGroup(extensionManifest.getGroupId());
|
||||
definedType.setArtifact(extensionManifest.getArtifactId());
|
||||
definedType.setVersion(extensionManifest.getVersion());
|
||||
}
|
||||
|
||||
private void populateExtensionComponent(final ExtensionManifest extensionManifest, final Extension extension, final ExtensionComponent extensionComponent) {
|
||||
final org.apache.nifi.registry.extension.component.manifest.BuildInfo buildInfo = extensionManifest.getBuildInfo();
|
||||
if (buildInfo != null) {
|
||||
final BuildInfo componentBuildInfo = new BuildInfo();
|
||||
componentBuildInfo.setRevision(buildInfo.getRevision());
|
||||
extensionComponent.setBuildInfo(componentBuildInfo);
|
||||
}
|
||||
|
||||
final List<String> tags = extension.getTags();
|
||||
if (isNotEmpty(tags)) {
|
||||
extensionComponent.setTags(new HashSet<>(tags));
|
||||
}
|
||||
|
||||
// the extension-manifest.xml will have <deprecationNotice/> for non-deprecated components which unmarshalls into
|
||||
// a non-null DeprecationNotice, so we need to check if the reason is also non-null before setting the boolean here
|
||||
final DeprecationNotice deprecationNotice = extension.getDeprecationNotice();
|
||||
if (deprecationNotice != null && deprecationNotice.getReason() != null) {
|
||||
extensionComponent.setDeprecated(true);
|
||||
extensionComponent.setDeprecationReason(deprecationNotice.getReason());
|
||||
}
|
||||
|
||||
final List<ProvidedServiceAPI> providedServiceApis = extension.getProvidedServiceAPIs();
|
||||
if (isNotEmpty(providedServiceApis)) {
|
||||
final List<DefinedType> providedApiTypes = new ArrayList<>();
|
||||
providedServiceApis.forEach(providedServiceApi -> providedApiTypes.add(createProvidedApiType(providedServiceApi)));
|
||||
extensionComponent.setProvidedApiImplementations(providedApiTypes);
|
||||
}
|
||||
}
|
||||
|
||||
private DefinedType createProvidedApiType(final ProvidedServiceAPI providedServiceApi) {
|
||||
final DefinedType providedApiType = new DefinedType();
|
||||
providedApiType.setType(providedServiceApi.getClassName());
|
||||
providedApiType.setGroup(providedServiceApi.getGroupId());
|
||||
providedApiType.setArtifact(providedServiceApi.getArtifactId());
|
||||
providedApiType.setVersion(providedServiceApi.getVersion());
|
||||
return providedApiType;
|
||||
}
|
||||
|
||||
private void populateConfigurableComponent(final Extension extension, final ConfigurableComponentDefinition configurableComponentDefinition) {
|
||||
final List<Property> properties = extension.getProperties();
|
||||
if (isNotEmpty(properties)) {
|
||||
final LinkedHashMap<String, PropertyDescriptor> propertyDescriptors = new LinkedHashMap<>();
|
||||
properties.forEach(property -> addPropertyDescriptor(propertyDescriptors, property));
|
||||
configurableComponentDefinition.setPropertyDescriptors(propertyDescriptors);
|
||||
}
|
||||
|
||||
if (isNotEmpty(extension.getDynamicProperties())) {
|
||||
configurableComponentDefinition.setSupportsDynamicProperties(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPropertyDescriptor(final Map<String, PropertyDescriptor> propertyDescriptors, final Property property) {
|
||||
final PropertyDescriptor propertyDescriptor = createPropertyDescriptor(property);
|
||||
propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor);
|
||||
}
|
||||
|
||||
private PropertyDescriptor createPropertyDescriptor(final Property property) {
|
||||
final PropertyDescriptor descriptor = new PropertyDescriptor();
|
||||
descriptor.setName(property.getName());
|
||||
descriptor.setDisplayName(property.getDisplayName());
|
||||
descriptor.setDescription(property.getDescription());
|
||||
descriptor.setDefaultValue(property.getDefaultValue());
|
||||
descriptor.setRequired(property.isRequired());
|
||||
descriptor.setSensitive(property.isSensitive());
|
||||
descriptor.setExpressionLanguageScope(getELScope(property.getExpressionLanguageScope()));
|
||||
descriptor.setDynamic(property.isDynamic());
|
||||
descriptor.setAllowableValues(getPropertyAllowableValues(property.getAllowableValues()));
|
||||
descriptor.setTypeProvidedByValue(getControllerServiceDefinedType(property.getControllerServiceDefinition()));
|
||||
descriptor.setResourceDefinition(getPropertyResourceDefinition(property.getResourceDefinition()));
|
||||
descriptor.setDependencies(getPropertyDependencies(property.getDependencies()));
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private List<PropertyDependency> getPropertyDependencies(final List<Dependency> dependencies) {
|
||||
if (dependencies == null || dependencies.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<PropertyDependency> propertyDependencies = new ArrayList<>(dependencies.size());
|
||||
for (final Dependency dependency : dependencies) {
|
||||
final PropertyDependency propertyDependency = new PropertyDependency();
|
||||
propertyDependency.setPropertyName(dependency.getPropertyName());
|
||||
propertyDependency.setPropertyDisplayName(dependency.getPropertyDisplayName());
|
||||
|
||||
final List<String> values = new ArrayList<>();
|
||||
final DependentValues dependentValues = dependency.getDependentValues();
|
||||
if (dependentValues != null && dependentValues.getValues() != null) {
|
||||
values.addAll(dependentValues.getValues());
|
||||
}
|
||||
propertyDependency.setDependentValues(values);
|
||||
propertyDependencies.add(propertyDependency);
|
||||
}
|
||||
return propertyDependencies;
|
||||
}
|
||||
|
||||
private PropertyResourceDefinition getPropertyResourceDefinition(final ResourceDefinition resourceDefinition) {
|
||||
if (resourceDefinition == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PropertyResourceDefinition propertyResourceDefinition = new PropertyResourceDefinition();
|
||||
switch (resourceDefinition.getCardinality()) {
|
||||
case SINGLE:
|
||||
propertyResourceDefinition.setCardinality(ResourceCardinality.SINGLE);
|
||||
break;
|
||||
case MULTIPLE:
|
||||
propertyResourceDefinition.setCardinality(ResourceCardinality.MULTIPLE);
|
||||
break;
|
||||
}
|
||||
|
||||
propertyResourceDefinition.setResourceTypes(
|
||||
resourceDefinition.getResourceTypes().stream()
|
||||
.map(rt -> getResourceType(rt))
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
|
||||
return propertyResourceDefinition;
|
||||
}
|
||||
|
||||
private ResourceType getResourceType(final org.apache.nifi.registry.extension.component.manifest.ResourceType resourceType) {
|
||||
switch (resourceType) {
|
||||
case URL:
|
||||
return ResourceType.URL;
|
||||
case FILE:
|
||||
return ResourceType.FILE;
|
||||
case TEXT:
|
||||
return ResourceType.TEXT;
|
||||
case DIRECTORY:
|
||||
return ResourceType.DIRECTORY;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown resource type: " + resourceType);
|
||||
}
|
||||
}
|
||||
|
||||
private ExpressionLanguageScope getELScope(final org.apache.nifi.registry.extension.component.manifest.ExpressionLanguageScope elScope) {
|
||||
if (elScope == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (elScope) {
|
||||
case NONE:
|
||||
return ExpressionLanguageScope.NONE;
|
||||
case FLOWFILE_ATTRIBUTES:
|
||||
return ExpressionLanguageScope.FLOWFILE_ATTRIBUTES;
|
||||
case VARIABLE_REGISTRY:
|
||||
return ExpressionLanguageScope.VARIABLE_REGISTRY;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unknown Expression Language Scope: " + elScope.name());
|
||||
}
|
||||
}
|
||||
|
||||
private List<PropertyAllowableValue> getPropertyAllowableValues(final List<AllowableValue> allowableValues) {
|
||||
if (allowableValues == null || allowableValues.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final List<PropertyAllowableValue> propertyAllowableValues = new ArrayList<>();
|
||||
for (final AllowableValue allowableValue : allowableValues) {
|
||||
final PropertyAllowableValue propertyAllowableValue = new PropertyAllowableValue();
|
||||
propertyAllowableValue.setValue(allowableValue.getValue());
|
||||
propertyAllowableValue.setDisplayName(allowableValue.getDisplayName());
|
||||
propertyAllowableValue.setDescription(allowableValue.getDescription());
|
||||
propertyAllowableValues.add(propertyAllowableValue);
|
||||
}
|
||||
return propertyAllowableValues;
|
||||
}
|
||||
|
||||
private DefinedType getControllerServiceDefinedType(
|
||||
final org.apache.nifi.registry.extension.component.manifest.ControllerServiceDefinition controllerServiceDefinition) {
|
||||
if (controllerServiceDefinition == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final DefinedType serviceDefinitionType = new DefinedType();
|
||||
serviceDefinitionType.setType(controllerServiceDefinition.getClassName());
|
||||
serviceDefinitionType.setGroup(controllerServiceDefinition.getGroupId());
|
||||
serviceDefinitionType.setArtifact(controllerServiceDefinition.getArtifactId());
|
||||
serviceDefinitionType.setVersion(controllerServiceDefinition.getVersion());
|
||||
return serviceDefinitionType;
|
||||
}
|
||||
|
||||
private <T> boolean isNotEmpty(final Collection<T> collection) {
|
||||
return collection != null && !collection.isEmpty();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-manifest</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-runtime-manifest-test</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-runtime-manifest</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-runtime-manifest-core</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>extract-runtime-manifest</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<includeArtifactIds>nifi-runtime-manifest</includeArtifactIds>
|
||||
<outputDirectory>${project.build.directory}/nifi-runtime-manifest</outputDirectory>
|
||||
<excludeTransitive>true</excludeTransitive>
|
||||
<silent>false</silent>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* 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.runtime.manifest;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||
import org.apache.nifi.c2.protocol.component.api.BuildInfo;
|
||||
import org.apache.nifi.c2.protocol.component.api.Bundle;
|
||||
import org.apache.nifi.c2.protocol.component.api.ComponentManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.ProcessorDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyDependency;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyDescriptor;
|
||||
import org.apache.nifi.c2.protocol.component.api.PropertyResourceDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.Relationship;
|
||||
import org.apache.nifi.c2.protocol.component.api.ReportingTaskDefinition;
|
||||
import org.apache.nifi.c2.protocol.component.api.RuntimeManifest;
|
||||
import org.apache.nifi.c2.protocol.component.api.SchedulingDefaults;
|
||||
import org.apache.nifi.components.resource.ResourceCardinality;
|
||||
import org.apache.nifi.components.resource.ResourceType;
|
||||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class TestRuntimeManifest {
|
||||
|
||||
@Test
|
||||
public void testRuntimeManifest() throws IOException {
|
||||
final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
final RuntimeManifest runtimeManifest;
|
||||
try (final InputStream inputStream = new FileInputStream("target/nifi-runtime-manifest/nifi-runtime-manifest.json")) {
|
||||
runtimeManifest = objectMapper.readValue(inputStream, RuntimeManifest.class);
|
||||
}
|
||||
assertNotNull(runtimeManifest);
|
||||
assertEquals("apache-nifi", runtimeManifest.getIdentifier());
|
||||
assertEquals("nifi", runtimeManifest.getAgentType());
|
||||
assertNotNull(runtimeManifest.getVersion());
|
||||
|
||||
final BuildInfo buildInfo = runtimeManifest.getBuildInfo();
|
||||
assertNotNull(buildInfo);
|
||||
assertNotNull(buildInfo.getCompiler());
|
||||
assertNotNull(buildInfo.getRevision());
|
||||
assertNotNull(buildInfo.getTimestamp());
|
||||
assertNotNull(buildInfo.getVersion());
|
||||
|
||||
final SchedulingDefaults schedulingDefaults = runtimeManifest.getSchedulingDefaults();
|
||||
assertNotNull(schedulingDefaults);
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN, schedulingDefaults.getDefaultSchedulingStrategy());
|
||||
|
||||
final Map<String, Integer> defaultConcurrentTasks = schedulingDefaults.getDefaultConcurrentTasksBySchedulingStrategy();
|
||||
assertNotNull(defaultConcurrentTasks);
|
||||
assertEquals(3, defaultConcurrentTasks.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks(), defaultConcurrentTasks.get(SchedulingStrategy.TIMER_DRIVEN.name()).intValue());
|
||||
assertEquals(SchedulingStrategy.EVENT_DRIVEN.getDefaultConcurrentTasks(), defaultConcurrentTasks.get(SchedulingStrategy.EVENT_DRIVEN.name()).intValue());
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks(), defaultConcurrentTasks.get(SchedulingStrategy.CRON_DRIVEN.name()).intValue());
|
||||
|
||||
final Map<String, String> defaultSchedulingPeriods = schedulingDefaults.getDefaultSchedulingPeriodsBySchedulingStrategy();
|
||||
assertEquals(2, defaultSchedulingPeriods.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod(), defaultSchedulingPeriods.get(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod(), defaultSchedulingPeriods.get(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
|
||||
final List<Bundle> bundles = runtimeManifest.getBundles();
|
||||
assertNotNull(bundles);
|
||||
assertTrue(bundles.size() > 0);
|
||||
|
||||
// Verify ListHDFS definition
|
||||
final ProcessorDefinition listHdfsDefinition = getProcessorDefinition(bundles, "nifi-hadoop-nar", "org.apache.nifi.processors.hadoop.ListHDFS");
|
||||
assertNotNull(listHdfsDefinition);
|
||||
assertTrue(listHdfsDefinition.getPrimaryNodeOnly());
|
||||
assertTrue(listHdfsDefinition.getTriggerSerially());
|
||||
assertTrue(listHdfsDefinition.getTriggerWhenEmpty());
|
||||
assertFalse(listHdfsDefinition.getSupportsBatching());
|
||||
assertFalse(listHdfsDefinition.getSupportsEventDriven());
|
||||
assertFalse(listHdfsDefinition.getSideEffectFree());
|
||||
assertFalse(listHdfsDefinition.getTriggerWhenAnyDestinationAvailable());
|
||||
assertFalse(listHdfsDefinition.getSupportsDynamicProperties());
|
||||
assertFalse(listHdfsDefinition.getSupportsDynamicRelationships());
|
||||
assertEquals(InputRequirement.Requirement.INPUT_FORBIDDEN, listHdfsDefinition.getInputRequirement());
|
||||
|
||||
assertEquals("30 sec", listHdfsDefinition.getDefaultPenaltyDuration());
|
||||
assertEquals("1 sec", listHdfsDefinition.getDefaultYieldDuration());
|
||||
assertEquals("WARN", listHdfsDefinition.getDefaultBulletinLevel());
|
||||
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.name(), listHdfsDefinition.getDefaultSchedulingStrategy());
|
||||
|
||||
final List<String> listHdfsSchedulingStrategies = listHdfsDefinition.getSupportedSchedulingStrategies();
|
||||
assertNotNull(listHdfsSchedulingStrategies);
|
||||
assertEquals(2, listHdfsSchedulingStrategies.size());
|
||||
assertTrue(listHdfsSchedulingStrategies.contains(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertTrue(listHdfsSchedulingStrategies.contains(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
|
||||
final Map<String, Integer> listHdfsDefaultConcurrentTasks = listHdfsDefinition.getDefaultConcurrentTasksBySchedulingStrategy();
|
||||
assertNotNull(listHdfsDefaultConcurrentTasks);
|
||||
assertEquals(2, listHdfsDefaultConcurrentTasks.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks(), listHdfsDefaultConcurrentTasks.get(SchedulingStrategy.TIMER_DRIVEN.name()).intValue());
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks(), listHdfsDefaultConcurrentTasks.get(SchedulingStrategy.CRON_DRIVEN.name()).intValue());
|
||||
|
||||
final Map<String, String> listHdfsDefaultSchedulingPeriods = listHdfsDefinition.getDefaultSchedulingPeriodBySchedulingStrategy();
|
||||
assertNotNull(listHdfsDefaultSchedulingPeriods);
|
||||
assertEquals(2, listHdfsDefaultSchedulingPeriods.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod(), listHdfsDefaultSchedulingPeriods.get(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod(), listHdfsDefaultSchedulingPeriods.get(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
|
||||
final List<Relationship> relationships = listHdfsDefinition.getSupportedRelationships();
|
||||
assertNotNull(relationships);
|
||||
assertEquals(1, relationships.size());
|
||||
assertEquals("success", relationships.get(0).getName());
|
||||
|
||||
final PropertyDescriptor configResourcesProp = getPropertyDescriptor(listHdfsDefinition, "Hadoop Configuration Resources");
|
||||
|
||||
final PropertyResourceDefinition resourceDefinition = configResourcesProp.getResourceDefinition();
|
||||
assertNotNull(resourceDefinition);
|
||||
assertEquals(ResourceCardinality.MULTIPLE, resourceDefinition.getCardinality());
|
||||
assertNotNull(resourceDefinition.getResourceTypes());
|
||||
assertEquals(1, resourceDefinition.getResourceTypes().size());
|
||||
assertEquals(ResourceType.FILE, resourceDefinition.getResourceTypes().stream().findFirst().get());
|
||||
|
||||
// Verify ConsumeKafka_2_6 definition which has properties with dependencies
|
||||
final ProcessorDefinition consumeKafkaDefinition = getProcessorDefinition(bundles, "nifi-kafka-2-6-nar",
|
||||
"org.apache.nifi.processors.kafka.pubsub.ConsumeKafka_2_6");
|
||||
|
||||
final PropertyDescriptor maxUncommitProp = getPropertyDescriptor(consumeKafkaDefinition, "max-uncommit-offset-wait");
|
||||
final List<PropertyDependency> propertyDependencies = maxUncommitProp.getDependencies();
|
||||
assertNotNull(propertyDependencies);
|
||||
assertEquals(1, propertyDependencies.size());
|
||||
|
||||
final PropertyDependency propertyMaxUncommitDependency = propertyDependencies.get(0);
|
||||
assertEquals("Commit Offsets", propertyMaxUncommitDependency.getPropertyName());
|
||||
assertNotNull(propertyMaxUncommitDependency.getDependentValues());
|
||||
assertEquals(1, propertyMaxUncommitDependency.getDependentValues().size());
|
||||
assertEquals("true", propertyMaxUncommitDependency.getDependentValues().get(0));
|
||||
|
||||
// Verify AmbariReportingTask definition which also has @DefaultSchedule
|
||||
final ReportingTaskDefinition ambariReportingTaskDef = getReportingTaskDefinition(bundles, "nifi-ambari-nar",
|
||||
"org.apache.nifi.reporting.ambari.AmbariReportingTask");
|
||||
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.name(), ambariReportingTaskDef.getDefaultSchedulingStrategy());
|
||||
|
||||
final List<String> ambariSchedulingStrategies = ambariReportingTaskDef.getSupportedSchedulingStrategies();
|
||||
assertNotNull(ambariSchedulingStrategies);
|
||||
assertEquals(2, ambariSchedulingStrategies.size());
|
||||
assertTrue(ambariSchedulingStrategies.contains(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertTrue(ambariSchedulingStrategies.contains(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
|
||||
final Map<String, String> ambariDefaultSchedulingPeriods = ambariReportingTaskDef.getDefaultSchedulingPeriodBySchedulingStrategy();
|
||||
assertNotNull(ambariDefaultSchedulingPeriods);
|
||||
assertEquals(2, ambariDefaultSchedulingPeriods.size());
|
||||
// TIMER_DRIVEN period should come from the @DefaultSchedule annotation that overrides the default value
|
||||
assertEquals("1 min", ambariDefaultSchedulingPeriods.get(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod(), ambariDefaultSchedulingPeriods.get(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
|
||||
// Verify JoltTransformRecord which has @EventDriven
|
||||
final ProcessorDefinition joltTransformDef = getProcessorDefinition(bundles, "nifi-jolt-record-nar",
|
||||
"org.apache.nifi.processors.jolt.record.JoltTransformRecord");
|
||||
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.name(), joltTransformDef.getDefaultSchedulingStrategy());
|
||||
|
||||
final List<String> joltTransformSchedulingStrategies = joltTransformDef.getSupportedSchedulingStrategies();
|
||||
assertNotNull(joltTransformSchedulingStrategies);
|
||||
assertEquals(3, joltTransformSchedulingStrategies.size());
|
||||
assertTrue(joltTransformSchedulingStrategies.contains(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertTrue(joltTransformSchedulingStrategies.contains(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
assertTrue(joltTransformSchedulingStrategies.contains(SchedulingStrategy.EVENT_DRIVEN.name()));
|
||||
|
||||
final Map<String, Integer> joltTransformDefaultConcurrentTasks = joltTransformDef.getDefaultConcurrentTasksBySchedulingStrategy();
|
||||
assertNotNull(joltTransformDefaultConcurrentTasks);
|
||||
assertEquals(3, joltTransformDefaultConcurrentTasks.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks(), joltTransformDefaultConcurrentTasks.get(SchedulingStrategy.TIMER_DRIVEN.name()).intValue());
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks(), joltTransformDefaultConcurrentTasks.get(SchedulingStrategy.CRON_DRIVEN.name()).intValue());
|
||||
assertEquals(SchedulingStrategy.EVENT_DRIVEN.getDefaultConcurrentTasks(), joltTransformDefaultConcurrentTasks.get(SchedulingStrategy.EVENT_DRIVEN.name()).intValue());
|
||||
|
||||
final Map<String, String> joltTransformDefaultSchedulingPeriods = listHdfsDefinition.getDefaultSchedulingPeriodBySchedulingStrategy();
|
||||
assertNotNull(joltTransformDefaultSchedulingPeriods);
|
||||
assertEquals(2, joltTransformDefaultSchedulingPeriods.size());
|
||||
assertEquals(SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod(), joltTransformDefaultSchedulingPeriods.get(SchedulingStrategy.TIMER_DRIVEN.name()));
|
||||
assertEquals(SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod(), joltTransformDefaultSchedulingPeriods.get(SchedulingStrategy.CRON_DRIVEN.name()));
|
||||
}
|
||||
|
||||
private PropertyDescriptor getPropertyDescriptor(final ProcessorDefinition processorDefinition, final String propName) {
|
||||
final Map<String, PropertyDescriptor> propertyDescriptors = processorDefinition.getPropertyDescriptors();
|
||||
assertNotNull(propertyDescriptors);
|
||||
|
||||
final PropertyDescriptor propertyDescriptor = propertyDescriptors.values().stream()
|
||||
.filter(p -> p.getName().equals(propName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertNotNull(propertyDescriptor);
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
private ProcessorDefinition getProcessorDefinition(final List<Bundle> bundles, final String artifactId, final String type) {
|
||||
final ComponentManifest componentManifest = getComponentManifest(bundles, artifactId);
|
||||
|
||||
final List<ProcessorDefinition> processors = componentManifest.getProcessors();
|
||||
assertNotNull(processors);
|
||||
|
||||
final ProcessorDefinition processorDefinition = processors.stream()
|
||||
.filter(p -> p.getType().equals(type))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertNotNull(processorDefinition);
|
||||
return processorDefinition;
|
||||
}
|
||||
|
||||
private ReportingTaskDefinition getReportingTaskDefinition(final List<Bundle> bundles, final String artifactId, final String type) {
|
||||
final ComponentManifest componentManifest = getComponentManifest(bundles, artifactId);
|
||||
|
||||
final List<ReportingTaskDefinition> reportingTasks = componentManifest.getReportingTasks();
|
||||
assertNotNull(reportingTasks);
|
||||
|
||||
final ReportingTaskDefinition reportingTaskDefinition = reportingTasks.stream()
|
||||
.filter(p -> p.getType().equals(type))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertNotNull(reportingTaskDefinition);
|
||||
return reportingTaskDefinition;
|
||||
}
|
||||
|
||||
private ComponentManifest getComponentManifest(final List<Bundle> bundles, final String artifactId) {
|
||||
final Bundle bundle = bundles.stream().filter(b -> b.getArtifact().equals(artifactId)).findFirst().orElse(null);
|
||||
assertNotNull(bundle);
|
||||
|
||||
final ComponentManifest componentManifest = bundle.getComponentManifest();
|
||||
assertNotNull(componentManifest);
|
||||
return componentManifest;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-manifest</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-runtime-manifest</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<extension.manifest.unpack.dir>${project.build.directory}</extension.manifest.unpack.dir>
|
||||
<build.properties.file>${project.build.directory}/classes/build.properties</build.properties.file>
|
||||
<runtime.manifest.file>${project.build.directory}/classes/nifi-runtime-manifest.json</runtime.manifest.file>
|
||||
<runtime.manifest.id>apache-nifi</runtime.manifest.id>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Needed to unpack the extension-manifest.xml files during the build, marked as optional
|
||||
because it is not a real dependency for anyone depending on this module -->
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-assembly</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
<classifier>manifests</classifier>
|
||||
<type>zip</type>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- Replace variables in src/main/resource/build.properties when processing resources -->
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>build.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<!-- Populate buildBranch, buildRevision, and timestamp so variables are available to build.properties -->
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>buildnumber-maven-plugin</artifactId>
|
||||
<inherited>true</inherited>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>validate</phase>
|
||||
<goals>
|
||||
<goal>create</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<doCheck>false</doCheck>
|
||||
<doUpdate>false</doUpdate>
|
||||
<shortRevisionLength>7</shortRevisionLength>
|
||||
<getRevisionOnlyOnce>true</getRevisionOnlyOnce>
|
||||
<revisionOnScmFailure />
|
||||
<buildNumberPropertyName>buildRevision</buildNumberPropertyName>
|
||||
<scmBranchPropertyName>buildBranch</scmBranchPropertyName>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- Unpack all of NiFi's extension manifests -->
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>extract-extension-manifests</id>
|
||||
<goals>
|
||||
<goal>unpack-dependencies</goal>
|
||||
</goals>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<includeArtifactIds>nifi-assembly</includeArtifactIds>
|
||||
<includeClassifiers>manifests</includeClassifiers>
|
||||
<includes>**/extension-manifest.xml</includes>
|
||||
<excludeTransitive>true</excludeTransitive>
|
||||
<outputDirectory>${extension.manifest.unpack.dir}</outputDirectory>
|
||||
<silent>true</silent>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- Execute the runtime manifest generator -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>exec-maven-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-runtime-manifest</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>java</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<mainClass>org.apache.nifi.runtime.manifest.impl.RuntimeManifestGenerator</mainClass>
|
||||
<arguments>
|
||||
<argument>${extension.manifest.unpack.dir}/nifi-manifests</argument>
|
||||
<argument>${build.properties.file}</argument>
|
||||
<argument>${runtime.manifest.file}</argument>
|
||||
<argument>${runtime.manifest.id}</argument>
|
||||
</arguments>
|
||||
<includePluginDependencies>true</includePluginDependencies>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-runtime-manifest-core</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<!-- Specifies an empty buildRevision and buildBranch when building outside of a git repo -->
|
||||
<profile>
|
||||
<id>build-info-no-git</id>
|
||||
<activation>
|
||||
<activeByDefault>false</activeByDefault>
|
||||
<file>
|
||||
<missing>../../.git/HEAD</missing>
|
||||
</file>
|
||||
</activation>
|
||||
<properties>
|
||||
<buildRevision />
|
||||
<buildBranch />
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,29 @@
|
|||
# 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.
|
||||
|
||||
Project-Version:${project.version}
|
||||
Build-Branch:${buildBranch}
|
||||
Build-Revision:${buildRevision}
|
||||
Build-Timestamp:${timestamp}
|
||||
Built-By:${user.name}
|
||||
Maven-Home:${maven.home}
|
||||
Maven-Version:${maven.version}
|
||||
Created-By:${maven.build.version}
|
||||
Build-Java-Home:${java.home}
|
||||
Build-Jdk:${java.version}
|
||||
Build-Jdk-Vendor:${java.vendor}
|
||||
Build-Arch:${os.arch}
|
||||
Build-Os:${os.name}
|
||||
Build-Os-Version:${os.version}
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi</artifactId>
|
||||
<version>1.16.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>nifi-manifest</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>nifi-runtime-manifest-core</module>
|
||||
<module>nifi-runtime-manifest</module>
|
||||
<module>nifi-runtime-manifest-test</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
|
@ -17,6 +17,8 @@
|
|||
package org.apache.nifi.registry.bundle.extract.nar.docs;
|
||||
|
||||
import org.apache.nifi.registry.extension.component.manifest.Cardinality;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DefaultSchedule;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DefaultSettings;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Dependency;
|
||||
import org.apache.nifi.registry.extension.component.manifest.DependentValues;
|
||||
import org.apache.nifi.registry.extension.component.manifest.Extension;
|
||||
|
@ -36,6 +38,7 @@ import java.io.InputStream;
|
|||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
@ -151,6 +154,46 @@ public class TestJacksonExtensionManifestParser {
|
|||
final List<Extension> extensionDetails = extensionManifest.getExtensions();
|
||||
assertEquals(4, extensionDetails.size());
|
||||
|
||||
final Extension processor1 = extensionDetails.stream()
|
||||
.filter(extension -> extension.getName().equals("org.apache.nifi.processors.TestProcessor1"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertNotNull(processor1);
|
||||
assertTrue(processor1.getTriggerSerially());
|
||||
assertTrue(processor1.getTriggerWhenEmpty());
|
||||
assertTrue(processor1.getTriggerWhenAnyDestinationAvailable());
|
||||
assertTrue(processor1.getPrimaryNodeOnly());
|
||||
assertTrue(processor1.getEventDriven());
|
||||
assertTrue(processor1.getSupportsBatching());
|
||||
assertTrue(processor1.getSideEffectFree());
|
||||
|
||||
final DefaultSettings defaultSettingsProc1 = processor1.getDefaultSettings();
|
||||
assertNotNull(defaultSettingsProc1);
|
||||
assertEquals("10 secs", defaultSettingsProc1.getYieldDuration());
|
||||
assertEquals("20 secs", defaultSettingsProc1.getPenaltyDuration());
|
||||
assertEquals("DEBUG", defaultSettingsProc1.getBulletinLevel());
|
||||
|
||||
final DefaultSchedule defaultScheduleProc1 = processor1.getDefaultSchedule();
|
||||
assertNotNull(defaultScheduleProc1);
|
||||
assertEquals("CRON_DRIVEN", defaultScheduleProc1.getStrategy());
|
||||
assertEquals("* 1 * * *", defaultScheduleProc1.getPeriod());
|
||||
assertEquals("5", defaultScheduleProc1.getConcurrentTasks());
|
||||
|
||||
final Extension processor2 = extensionDetails.stream()
|
||||
.filter(extension -> extension.getName().equals("org.apache.nifi.processors.TestProcessor2"))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertNotNull(processor2);
|
||||
assertFalse(processor2.getTriggerSerially());
|
||||
assertFalse(processor2.getTriggerWhenEmpty());
|
||||
assertFalse(processor2.getTriggerWhenAnyDestinationAvailable());
|
||||
assertFalse(processor2.getPrimaryNodeOnly());
|
||||
assertFalse(processor2.getEventDriven());
|
||||
assertFalse(processor2.getSupportsBatching());
|
||||
assertFalse(processor2.getSideEffectFree());
|
||||
|
||||
assertNull(processor2.getDefaultSchedule());
|
||||
assertNull(processor2.getDefaultSettings());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -9,6 +9,23 @@
|
|||
<tag>test</tag>
|
||||
<tag>processor</tag>
|
||||
</tags>
|
||||
<triggerSerially>true</triggerSerially>
|
||||
<triggerWhenEmpty>true</triggerWhenEmpty>
|
||||
<triggerWhenAnyDestinationAvailable>true</triggerWhenAnyDestinationAvailable>
|
||||
<primaryNodeOnly>true</primaryNodeOnly>
|
||||
<supportsBatching>true</supportsBatching>
|
||||
<eventDriven>true</eventDriven>
|
||||
<sideEffectFree>true</sideEffectFree>
|
||||
<defaultSettings>
|
||||
<yieldDuration>10 secs</yieldDuration>
|
||||
<penaltyDuration>20 secs</penaltyDuration>
|
||||
<bulletinLevel>DEBUG</bulletinLevel>
|
||||
</defaultSettings>
|
||||
<defaultSchedule>
|
||||
<strategy>CRON_DRIVEN</strategy>
|
||||
<period>* 1 * * *</period>
|
||||
<concurrentTasks>5</concurrentTasks>
|
||||
</defaultSchedule>
|
||||
</extension>
|
||||
<extension>
|
||||
<name>org.apache.nifi.processors.TestProcessor2</name>
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 DefaultSchedule {
|
||||
|
||||
private String strategy;
|
||||
private String period;
|
||||
private String concurrentTasks;
|
||||
|
||||
@ApiModelProperty("The default scheduling strategy")
|
||||
public String getStrategy() {
|
||||
return strategy;
|
||||
}
|
||||
|
||||
public void setStrategy(String strategy) {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default scheduling period")
|
||||
public String getPeriod() {
|
||||
return period;
|
||||
}
|
||||
|
||||
public void setPeriod(String period) {
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default concurrent tasks")
|
||||
public String getConcurrentTasks() {
|
||||
return concurrentTasks;
|
||||
}
|
||||
|
||||
public void setConcurrentTasks(String concurrentTasks) {
|
||||
this.concurrentTasks = concurrentTasks;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 DefaultSettings {
|
||||
|
||||
private String yieldDuration;
|
||||
private String penaltyDuration;
|
||||
private String bulletinLevel;
|
||||
|
||||
@ApiModelProperty("The default yield duration")
|
||||
public String getYieldDuration() {
|
||||
return yieldDuration;
|
||||
}
|
||||
|
||||
public void setYieldDuration(String yieldDuration) {
|
||||
this.yieldDuration = yieldDuration;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default penalty duration")
|
||||
public String getPenaltyDuration() {
|
||||
return penaltyDuration;
|
||||
}
|
||||
|
||||
public void setPenaltyDuration(String penaltyDuration) {
|
||||
this.penaltyDuration = penaltyDuration;
|
||||
}
|
||||
|
||||
@ApiModelProperty("The default bulletin level")
|
||||
public String getBulletinLevel() {
|
||||
return bulletinLevel;
|
||||
}
|
||||
|
||||
public void setBulletinLevel(String bulletinLevel) {
|
||||
this.bulletinLevel = bulletinLevel;
|
||||
}
|
||||
|
||||
}
|
|
@ -89,6 +89,16 @@ public class Extension {
|
|||
@XmlElement(name = "providedServiceAPI")
|
||||
private List<ProvidedServiceAPI> providedServiceAPIs;
|
||||
|
||||
private DefaultSettings defaultSettings;
|
||||
private DefaultSchedule defaultSchedule;
|
||||
|
||||
private boolean triggerSerially;
|
||||
private boolean triggerWhenEmpty;
|
||||
private boolean triggerWhenAnyDestinationAvailable;
|
||||
private boolean supportsBatching;
|
||||
private boolean eventDriven;
|
||||
private boolean primaryNodeOnly;
|
||||
private boolean sideEffectFree;
|
||||
|
||||
@ApiModelProperty(value = "The name of the extension")
|
||||
public String getName() {
|
||||
|
@ -243,6 +253,87 @@ public class Extension {
|
|||
this.providedServiceAPIs = providedServiceAPIs;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The default settings for a processor")
|
||||
public DefaultSettings getDefaultSettings() {
|
||||
return defaultSettings;
|
||||
}
|
||||
|
||||
public void setDefaultSettings(DefaultSettings defaultSettings) {
|
||||
this.defaultSettings = defaultSettings;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "The default schedule for a processor reporting task")
|
||||
public DefaultSchedule getDefaultSchedule() {
|
||||
return defaultSchedule;
|
||||
}
|
||||
|
||||
public void setDefaultSchedule(DefaultSchedule defaultSchedule) {
|
||||
this.defaultSchedule = defaultSchedule;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor should be triggered serially")
|
||||
public boolean getTriggerSerially() {
|
||||
return triggerSerially;
|
||||
}
|
||||
|
||||
public void setTriggerSerially(boolean triggerSerially) {
|
||||
this.triggerSerially = triggerSerially;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor should be triggered when the incoming queues are empty")
|
||||
public boolean getTriggerWhenEmpty() {
|
||||
return triggerWhenEmpty;
|
||||
}
|
||||
|
||||
public void setTriggerWhenEmpty(boolean triggerWhenEmpty) {
|
||||
this.triggerWhenEmpty = triggerWhenEmpty;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor should be triggered when any destinations have space for flow files")
|
||||
public boolean getTriggerWhenAnyDestinationAvailable() {
|
||||
return triggerWhenAnyDestinationAvailable;
|
||||
}
|
||||
|
||||
public void setTriggerWhenAnyDestinationAvailable(boolean triggerWhenAnyDestinationAvailable) {
|
||||
this.triggerWhenAnyDestinationAvailable = triggerWhenAnyDestinationAvailable;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor supports batching")
|
||||
public boolean getSupportsBatching() {
|
||||
return supportsBatching;
|
||||
}
|
||||
|
||||
public void setSupportsBatching(boolean supportsBatching) {
|
||||
this.supportsBatching = supportsBatching;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor supports event driven scheduling")
|
||||
public boolean getEventDriven() {
|
||||
return eventDriven;
|
||||
}
|
||||
|
||||
public void setEventDriven(boolean eventDriven) {
|
||||
this.eventDriven = eventDriven;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor should be scheduled only on the primary node")
|
||||
public boolean getPrimaryNodeOnly() {
|
||||
return primaryNodeOnly;
|
||||
}
|
||||
|
||||
public void setPrimaryNodeOnly(boolean primaryNodeOnly) {
|
||||
this.primaryNodeOnly = primaryNodeOnly;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "Indicates that a processor is side effect free")
|
||||
public boolean getSideEffectFree() {
|
||||
return sideEffectFree;
|
||||
}
|
||||
|
||||
public void setSideEffectFree(boolean sideEffectFree) {
|
||||
this.sideEffectFree = sideEffectFree;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
|
Loading…
Reference in New Issue