NIFI-13804 Migrated to NiFi API 2.0.0

This closes #9314.

- Upgraded NAR Maven Plugin from 2.0.0 to 2.1.0
- Removed nifi-api module in favor of released version

Signed-off-by: Joseph Witt <joewitt@apache.org>
This commit is contained in:
exceptionfactory 2024-09-23 14:12:18 -05:00 committed by Joseph Witt
parent e9ce40d209
commit 1548a21219
No known key found for this signature in database
GPG Key ID: 9093BF854F811A1A
320 changed files with 13 additions and 27146 deletions

View File

@ -34,11 +34,6 @@ limitations under the License.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>

View File

@ -53,7 +53,6 @@ limitations under the License.
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>

View File

@ -103,7 +103,6 @@ limitations under the License.
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>

View File

@ -29,7 +29,6 @@ limitations under the License.
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>

View File

@ -44,7 +44,6 @@ limitations under the License.
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>

View File

@ -32,7 +32,6 @@
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-api</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>

View File

@ -1,43 +0,0 @@
<?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>2.0.0-SNAPSHOT</version>
</parent>
<artifactId>nifi-api</artifactId>
<packaging>jar</packaging>
<!--
This module should have no external dependencies. The following dependency is acceptable ONLY
due to the fact that it is an optional dependency, and NiFi functions perfectly without it.
Adding a dependency on nifi-api does not bring in any transitive dependencies.
The dependency is provided here because Swagger Annotations are used within the Versioned Components
objects of the NiFi API in order to provide documentation for generating REST API's, generating clients, etc.
While NiFi does not need these, any application that wants these capabilities can achieve this
simply by adding their own dependency on Swagger Annotations.
-->
<dependencies>
<dependency>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-annotations</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,47 +0,0 @@
/*
* 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.action;
import java.io.Serializable;
import java.util.Date;
import org.apache.nifi.action.component.details.ComponentDetails;
import org.apache.nifi.action.details.ActionDetails;
/**
* An action taken on the flow by a user.
*/
public interface Action extends Serializable {
Integer getId();
Date getTimestamp();
String getUserIdentity();
String getSourceId();
String getSourceName();
Component getSourceType();
ComponentDetails getComponentDetails();
Operation getOperation();
ActionDetails getActionDetails();
}

View File

@ -1,42 +0,0 @@
/*
* 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.action;
/**
* Defines possible components for a given action.
*/
public enum Component {
Controller,
Processor,
InputPort,
OutputPort,
ProcessGroup,
RemoteProcessGroup,
Funnel,
Connection,
ControllerService,
ReportingTask,
FlowAnalysisRule,
FlowRegistryClient,
ParameterContext,
ParameterProvider,
AccessPolicy,
User,
UserGroup,
Label;
}

View File

@ -1,55 +0,0 @@
/*
* 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.action;
/**
* Defines possible operations for a given action.
*/
public enum Operation {
Add("Add"),
Remove("Remove"),
Paste("Paste"),
Configure("Configure"),
Move("Move"),
Disconnect("Disconnect"),
Connect("Connect"),
Start("Start"),
Stop("Stop"),
Enable("Enable"),
Disable("Disable"),
Batch("Batch"),
Purge("Purge"),
ClearState("Clear State"),
StartVersionControl("Start Version Control"),
StopVersionControl("Stop Version Control"),
CommitLocalChanges("Commit Local Changes"),
RevertLocalChanges("Revert Local Changes"),
ChangeVersion("Change Version"),
RunOnce("RunOnce");
private final String label;
Operation(String label) {
this.label = label;
}
@Override
public String toString() {
return label;
}
}

View File

@ -1,26 +0,0 @@
/*
* 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.action.component.details;
import java.io.Serializable;
/**
* Base interface for providing component details to an Action.
*/
public interface ComponentDetails extends Serializable {
}

View File

@ -1,26 +0,0 @@
/*
* 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.action.details;
import java.io.Serializable;
/**
* Provides additional details about a given action.
*/
public interface ActionDetails extends Serializable {
}

View File

@ -1,40 +0,0 @@
/*
* 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.annotation.behavior;
import java.time.Duration;
public enum DefaultRunDuration {
NO_BATCHING(Duration.ZERO),
TWENTY_FIVE_MILLIS(Duration.ofMillis(25)),
FIFTY_MILLIS(Duration.ofMillis(50)),
ONE_HUNDRED_MILLIS(Duration.ofMillis(100)),
TWO_HUNDRED_FIFTY_MILLIS(Duration.ofMillis(250)),
FIVE_HUNDRED_MILLIS(Duration.ofMillis(500)),
ONE_SECOND(Duration.ofSeconds(1)),
TWO_SECONDS(Duration.ofSeconds(2));
private final Duration duration;
DefaultRunDuration(final Duration duration) {
this.duration = duration;
}
public Duration getDuration() {
return duration;
}
}

View File

@ -1,37 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Indicates that a component has more than one dynamic property
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicProperties {
DynamicProperty[] value();
}

View File

@ -1,47 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.ConfigurableComponent;
import org.apache.nifi.expression.ExpressionLanguageScope;
/**
* An annotation that may be placed on a {@link ConfigurableComponent} to
* indicate that it supports a dynamic property.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicProperty {
String name();
String value();
String description();
ExpressionLanguageScope expressionLanguageScope() default ExpressionLanguageScope.NONE;
}

View File

@ -1,44 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.processor.Relationship;
/**
* Annotation to indicate that a {@link Processor} supports dynamic
* relationship. A dynamic {@link Relationship} is one where the relationship is
* generated based on a user defined {@link PropertyDescriptor}
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DynamicRelationship {
String name();
String description();
}

View File

@ -1,67 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker interface that a Processor can use to indicate whether it accepts, requires, or forbids
* input from other Processors. This information is used by the framework in order to ensure that
* a Processor is marked as invalid if it is missing necessary input or has input that will be ignored.
* This information also is used by the NiFi UI in order to prevent users from making connections
* to Processors that don't make sense.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface InputRequirement {
Requirement value();
enum Requirement {
/**
* This value is used to indicate that the Processor requires input from other Processors
* in order to run. As a result, the Processor will not be valid if it does not have any
* incoming connections.
*/
INPUT_REQUIRED,
/**
* This value is used to indicate that the Processor will consume data from an incoming
* connection but does not require an incoming connection in order to perform its task.
* If the {@link InputRequirement} annotation is not present, this is the default value
* that is used.
*/
INPUT_ALLOWED,
/**
* This value is used to indicate that the Processor is a "Source Processor" and does
* not accept incoming connections. Because the Processor does not pull FlowFiles from
* an incoming connection, it can be very confusing for users who create incoming connections
* to the Processor. As a result, this value can be used in order to clarify that incoming
* connections will not be used. This prevents the user from even creating such a connection.
*/
INPUT_FORBIDDEN;
}
}

View File

@ -1,36 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a {@link org.apache.nifi.processor.Processor} implementation
* can use to indicate that the {@link org.apache.nifi.scheduling.ExecutionNode}
* of the processor is to be set to PRIMARY
*/
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface PrimaryNodeOnly {
}

View File

@ -1,41 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.processor.Processor Processor} indicating that this
* processor reads a specific FlowFile attribute.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ReadsAttribute {
public String attribute();
public String description() default "";
}

View File

@ -1,39 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.processor.Processor Processor} indicating that this
* processor reads specific FlowFile attributes.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ReadsAttributes {
ReadsAttribute[] value();
}

View File

@ -1,54 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a component can use to indicate that the framework should create a new ClassLoader
* for each instance of the component, copying all resources from the component's NARClassLoader to a
* new ClassLoader which will only be used by a given instance of the component.
*
* If cloneAncestorResources is set to true, the instance ClassLoader will include ancestor resources up to the
* first ClassLoader containing a controller service API referenced by the component, or up to the Jetty NAR.
*
* Example #1 - PutHDFS has this flag set to true and does not reference any controller services, so it will include
* resources from nifi-hadoop-nar, nifi-hadoop-libraries-nar, and nifi-standard-services-api-nar, stopping at nifi-jetty-nar.
*
* Example #2 - If PutHDFS referenced an SSLContext and has this flag set to true, then it would include
* resources from nifi-hadoop-nar, nifi-hadoop-libraries-nar, and stop before nifi-standard-services-api-nar.
*
* Example #3 - HBaseClientService_1_1_2 does not have this flag set so it defaults to false, and therefore includes
* only resources from the nifi-hbase-client-service-1_1_2-nar.
*
* NOTE: When this annotation is used it is important to note that each added instance of the component will increase
* the overall memory footprint more than that of a component without this annotation.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RequiresInstanceClassLoading {
boolean cloneAncestorResources() default false;
}

View File

@ -1,59 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marks the usage of a component as restricted to users with elevated privileges.
* </p>
* <p>
* A {@code Restricted} component is one that can be used to execute arbitrary unsanitized
* code provided by the operator through the NiFi REST API/UI or can be used to obtain
* or alter data on the NiFi host system using the NiFi OS credentials. These components
* could be used by an otherwise authorized NiFi user to go beyond the intended use of
* the application, escalate privilege, or could expose data about the internals of the
* NiFi process or the host system. All of these capabilities should be considered
* privileged, and admins should be aware of these capabilities and explicitly enable
* them for a subset of trusted users.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Restricted {
/**
* Provides a description of why the component usage is restricted. If using granular
* restrictions, specific explanations should be set in the Restriction.
*/
String value() default "";
/**
* Provides a listing of specific Restrictions. If unspecified, this component will
* require access to restricted components regardless of restrictions.
*/
Restriction[] restrictions() default {};
}

View File

@ -1,46 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.RequiredPermission;
/**
* Specific restriction for a component. Indicates what the required permission is and why the restriction exists.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Restriction {
/**
* Provides a listing of RequiredPermissions.
*/
RequiredPermission requiredPermission();
/**
* Provides a explanation of why the component usage is restricted
*/
String explanation();
}

View File

@ -1,45 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor}
* implementation can use to indicate that its operations on FlowFiles can be
* safely repeated across process sessions. If a processor has this annotation
* and it allows the framework to manage session commit and rollback then the
* framework may elect to cascade a
* {@link org.apache.nifi.processor.ProcessSession ProcessSession} given to this
* processor's onTrigger method to the onTrigger method of another processor. It
* can do this knowing that if something fails along a series of processors
* using this same session that it can all be safely rolled back without any ill
* effects on external services which could not be rolled back and thus all the
* processes could be safely repeated (implied idempotent behavior).
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SideEffectFree {
}

View File

@ -1,53 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.state.Scope;
import org.apache.nifi.components.state.StateManager;
/**
* <p>
* Annotation that a Processor, ReportingTask, FlowAnalysisRule, ParameterProvider, or Controller Service can use to indicate
* that the component makes use of the {@link StateManager}. This annotation provides the
* user with a description of what information is being stored so that the user is able to
* understand what is shown to them and know what they are clearing should they choose to
* clear the state. Additionally, the UI will not show any state information to users if
* this annotation is not present.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Stateful {
/**
* Provides a description of what information is being stored in the {@link StateManager}
*/
String description();
/**
* Indicates the Scope(s) associated with the State that is stored and retrieved.
*/
Scope[] scopes();
}

View File

@ -1,53 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a Processor implementation can use to indicate that users
* should be able to supply a Batch Duration for the Processor. If a Processor
* uses this annotation, it is allowing the Framework to batch
* {@link org.apache.nifi.processor.ProcessSession ProcessSession}s' commits, as well as
* allowing the Framework to return the same ProcessSession multiple times from
* subsequent calls to
* {@link org.apache.nifi.processor.ProcessSessionFactory ProcessSessionFactory}.
* {@link org.apache.nifi.processor.ProcessSessionFactory#createSession() createSession()}.
*
* When this Annotation is used, it is important to note that calls to
* {@link org.apache.nifi.processor.ProcessSession#commit() ProcessSession.commit()} may
* not provide a guarantee that the data has been safely stored in NiFi's
* Content Repository or FlowFile Repository. Therefore, it is not appropriate,
* for instance, to use this annotation if the Processor will call
* ProcessSession.commit() to ensure data is persisted before deleting the data
* from a remote source.
*
* When the defaultDuration parameter is set, the processor is created with the supplied duration time, which can be adjusted afterwards.
* The supplied values can be selected from {@link org.apache.nifi.annotation.behavior.DefaultRunDuration}.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SupportsBatching {
DefaultRunDuration defaultDuration() default DefaultRunDuration.NO_BATCHING;
}

View File

@ -1,36 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Component annotation indicating support for dynamic properties that can be designated as sensitive for the purpose of
* persistence and framework processing
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SupportsSensitiveDynamicProperties {
}

View File

@ -1,26 +0,0 @@
/*
* 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.annotation.behavior;
/**
* Represents a system resource.
*/
public enum SystemResource {
CPU, DISK, MEMORY, NETWORK
}

View File

@ -1,51 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.components.ConfigurableComponent Component} describes how this component may impact a
* system resource based on its configuration.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Repeatable(SystemResourceConsiderations.class)
public @interface SystemResourceConsideration {
String DEFAULT_DESCRIPTION = "An instance of this component can cause high usage of this system resource. " +
"Multiple instances or high concurrency settings may result a degradation of performance.";
/**
* The {@link SystemResource SystemResource} which may be affected by this component.
*/
SystemResource resource();
/**
* A description of how this component and its configuration may affect system resource usage.
*/
String description() default DEFAULT_DESCRIPTION;
}

View File

@ -1,37 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.components.ConfigurableComponent Component} describes how this component may impact
* system resources based on its configuration.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SystemResourceConsiderations {
SystemResourceConsideration[] value();
}

View File

@ -1,38 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor}
* implementation can use to indicate that the Processor is not safe for
* concurrent execution of its onTrigger() method. By default, Processors are
* assumed to be safe for concurrent execution.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TriggerSerially {
}

View File

@ -1,40 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor}
* implementation can use to indicate that the Processor is to be triggered if
* any of its destinations has available space for incoming FlowFiles. By
* default, Processors are triggered only when all destinations report that they
* have available space (i.e., none of the outgoing Connections is full).
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TriggerWhenAnyDestinationAvailable {
}

View File

@ -1,57 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor}
* implementation can use to indicate that the Processor should still be
* triggered even when it has no data in its work queue.
* </p>
*
* <p>
* A Processor is scheduled to be triggered based on its configured Scheduling Period
* and Scheduling Strategy. However, when the scheduling period elapses, the Processor
* will not be scheduled if it has no work to do. Normally, a Processor is said to have
* work to do if one of the following circumstances is true:
* </p>
*
* <ul>
* <li>An incoming Connection has data in its queue</li>
* <li>The Processor has no incoming Connections.</li>
* <li>All incoming Connections are self-loops (both the source and destination of the Connection are the same Processor).
* </ul>
*
* <p>
* If the Processor needs to be triggered to run even when the above conditions are all
* <code>false</code>, the Processor's class can be annotated with this annotation, which
* will cause the Processor to be triggered, even if its incoming queues are empty.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface TriggerWhenEmpty {
}

View File

@ -1,41 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.processor.Processor Processor} indicating that this
* processor writes/updates a specific FlowFile attribute.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface WritesAttribute {
String attribute();
String description() default "";
}

View File

@ -1,39 +0,0 @@
/*
* 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.annotation.behavior;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a
* {@link org.apache.nifi.processor.Processor Processor} indicating that this
* processor writes/updates specific FlowFile attributes.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface WritesAttributes {
WritesAttribute[] value();
}

View File

@ -1,45 +0,0 @@
/*
* 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.annotation.configuration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.scheduling.SchedulingStrategy;
/**
* <p>
* Marker interface that a Processor can use to configure default settings for the schedule strategy, the period and the number of concurrent tasks.
* Marker interface that a ReportingTask can use to configure default settings the schedule strategy and the period.
* Note that the number of Concurrent tasks will be ignored if the annotation @TriggerSerialy is used
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DefaultSchedule {
SchedulingStrategy strategy() default SchedulingStrategy.TIMER_DRIVEN;
String period() default "0 sec";
int concurrentTasks() default 1;
}

View File

@ -1,42 +0,0 @@
/*
* 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.annotation.configuration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.logging.LogLevel;
/**
* <p>
* Marker interface that a Processor can use to configure the yield duration, the penalty duration and the bulletin log level.
* Note that the number of Concurrent tasks will be ignored if the annotation @TriggerSerialy is used
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DefaultSettings {
String yieldDuration() default "1 sec";
String penaltyDuration() default "30 sec";
LogLevel bulletinLevel() default LogLevel.WARN;
}

View File

@ -1,43 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that may be placed on a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider},
* {@link org.apache.nifi.flowanalysis.FlowAnalysisRule FlowAnalysisRule}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} allowing for a
* description to be provided. This description can be provided to a user in
* logs, UI, etc.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface CapabilityDescription {
String value();
}

View File

@ -1,46 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.ConfigurableComponent;
/**
* Annotation that can be applied to a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} in order to
* warn about the deprecation of the component. The deprecation warning is informational only
* and doesn't affect the processor run time behavior in any way
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface DeprecationNotice {
Class<? extends ConfigurableComponent>[] alternatives() default {};
String[] classNames() default {};
String reason() default "";
}

View File

@ -1,77 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* An annotation that can be used for Processors in order to explain a specific use case that can be
* accomplished using this Processor in conjunction with at least one other Processor.
* For Processors that are able to be used for multiple use cases, the component
* may be annotated with multiple MultiProcessorUseCase annotations.
* </p>
* <p>
* Note that this annotation differs from {@link UseCase} in that UseCase should describe a use case that is
* accomplished using only the extension that is annotated. In contrast, MultiProcessorUseCase documents a use case
* that is accomplished by using both the Processor that is annotated as well as other Processors.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Repeatable(MultiProcessorUseCases.class)
public @interface MultiProcessorUseCase {
/**
* A simple 1 (at most 2) sentence description of the use case. This should not include any extraneous details, such
* as caveats, examples, etc. Those can be provided using the {@link #notes()} method.
*
* @return a simple description of the use case
*/
String description();
/**
* Most of the time, 1-2 sentences is sufficient to describe a use case. Those 1-2 sentence should then be returned
* by the {@link #description()}. In the event that the description is not sufficient, details may be provided to
* further explain, by providing examples, caveats, etc.
*
* @return any important notes that pertain to the use case
*/
String notes() default "";
/**
* An optional array of keywords that can be associated with the use case.
* @return keywords associated with the use case
*/
String[] keywords() default {};
/**
* An array of {@link ProcessorConfiguration}s that are necessary in order to accomplish the task described in this use case.
* @return an array of processor configurations
*/
ProcessorConfiguration[] configurations();
}

View File

@ -1,36 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An enclosing annotation that can be used in order to use the {@link MultiProcessorUseCase} annotation in a repeated manner.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MultiProcessorUseCases {
MultiProcessorUseCase[] value();
}

View File

@ -1,57 +0,0 @@
/*
* 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.annotation.documentation;
import org.apache.nifi.processor.Processor;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An annotation that can be used in conjunction with {@link MultiProcessorUseCase} in order to specify the different
* components that are involved in a given use case.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface ProcessorConfiguration {
/**
* Returns the class of the Processor that is to be used in the use case, if it is provided. Either the
* Processor Class or the Processor Class Name must be provided.
*
* @return the Processor's class, or <code>Processor</code> if the processor's classname is specified instead
*/
Class<? extends Processor> processorClass() default Processor.class;
/**
* @return the fully qualified classname of the component
*/
String processorClassName() default "";
/**
* @return an explanation of how the Processor should be configured.
*/
String configuration();
}

View File

@ -1,45 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.components.ConfigurableComponent;
/**
* Annotation that may be placed on a null {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider},
* {@link org.apache.nifi.flowanalysis.FlowAnalysisRule FlowAnalysisRule}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} that indicates
* this component is related to the components listed.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SeeAlso {
Class<? extends ConfigurableComponent>[] value() default {};
String[] classNames() default {};
}

View File

@ -1,44 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that can be applied to a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider},
* {@link org.apache.nifi.flowanalysis.FlowAnalysisRule FlowAnalysisRule}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} in order to
* associate tags (keywords) with the component. These tags do not affect the
* component in any way but serve as additional documentation and can be used to
* sort/filter Processors.
*
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Tags {
String[] value();
}

View File

@ -1,89 +0,0 @@
/*
* 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.annotation.documentation;
import org.apache.nifi.annotation.behavior.InputRequirement;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* An annotation that can be used for extension points in order to explain a specific use case that can be
* accomplished using this extension. For components that are able to be used for multiple use cases, the component
* may be annotated with multiple UseCase annotations.
* </p>
* <p>
* Note that this annotation differs from {@link CapabilityDescription} in that CapabilityDescription should describe the
* general purpose of the extension point. UseCase, on the other hand, documents one very specific use case that
* can be accomplished. Some extension points may use only a single UseCase annotation while others may accomplish
* many use cases.
* </p>
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Repeatable(UseCases.class)
public @interface UseCase {
/**
* A simple 1 (at most 2) sentence description of the use case. This should not include any extraneous details, such
* as caveats, examples, etc. Those can be provided using the {@link #notes()} method.
*
* @return a simple description of the use case
*/
String description();
/**
* Most of the time, 1-2 sentences is sufficient to describe a use case. Those 1-2 sentence should then be returned
* by the {@link #description()}. In the event that the description is not sufficient, details may be provided to
* further explain, by providing examples, caveats, etc.
*
* @return any important notes that pertain to the use case
*/
String notes() default "";
/**
* Most Processors specify an InputRequirement of either {@link InputRequirement.Requirement#INPUT_REQUIRED INPUT_REQUIRED}
* or {@link InputRequirement.Requirement#INPUT_FORBIDDEN}. However, some Processors use {@link InputRequirement.Requirement#INPUT_ALLOWED}
* because some use cases require input while others do not. The inputRequirement here is only relevant for Processors that use
* an InputRequirement of {@link InputRequirement.Requirement#INPUT_ALLOWED} and can indicate whether or not the Processor should have
* input (aka incoming Connections) for this particular use case.
*
* @return the {@link InputRequirement} that corresponds to this use case.
*/
InputRequirement.Requirement inputRequirement() default InputRequirement.Requirement.INPUT_ALLOWED;
/**
* An optional array of keywords that can be associated with the use case.
* @return keywords associated with the use case
*/
String[] keywords() default {};
/**
* A description of how to configure the extension for this particular use case.
* @return a description of how to configure the extension for this particular use case.
*/
String configuration() default "";
}

View File

@ -1,36 +0,0 @@
/*
* 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.annotation.documentation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* An enclosing annotation that can be used in order to use the {@link UseCase} annotation in a repeated manner.
*/
@Documented
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UseCases {
UseCase[] value();
}

View File

@ -1,49 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.registry.flow.FlowRegistryClient FlowRegistryClient},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider},
* {@link org.apache.nifi.flowanalysis.FlowAnalysisRule FlowAnalysisRule}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
* can use to indicate a method should be called whenever the component is added
* to the flow. This method will be called once for the entire life of a
* component instance.
* </p>
*
* <p>
* Methods with this annotation are called without any arguments, as all
* settings and properties can be assumed to be the defaults.
* </p>
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnAdded {
}

View File

@ -1,59 +0,0 @@
/*
* 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.annotation.lifecycle;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker Annotation that a Processor, Reporting Task, or Controller Service can use to indicate
* that the method with this Annotation should be invoked whenever the component's configuration
* is restored after a restart of NiFi.
* </p>
*
* <p>
* Methods with this annotation are permitted to take no arguments or to take a
* single argument. If using a single argument, that argument must be of type
* {@link ConfigurationContext} if the component is a ReportingTask or a
* ControllerService. If the component is a Processor, then the argument must be
* of type {@link ProcessContext}.
* </p>
*
* <p>
* Whenever a new component is added to the flow, this method will be called immediately, since
* there is no configuration to restore (in this case all configuration has already been restored,
* since there is no configuration to restore).
* </p>
*
* @since 0.5.0
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnConfigurationRestored {
}

View File

@ -1,61 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
/**
* <p>
* Marker annotation a
* {@link org.apache.nifi.controller.ControllerService ControllerService} can
* use to indicate a method should be called whenever the service is disabled.
* </p>
*
* <p>
* Methods using this annotation are permitted to take zero arguments or to take
* a single argument of type {@link ConfigurationContext}. If a method with this
* annotation throws a Throwable, a log message and bulletin will be issued for
* the service, but the service will still be marked as Disabled. The failing
* method will not be called again until the service is enabled and disabled again.
* This is done in order to prevent a ControllerService from continually failing
* in such a way that the service could not be disabled and updated without
* restarting the instance of NiFi.
* </p>
*
* <p>
* Note that this annotation will be ignored if applied to a ReportingTask, ParameterProvider or
* Processor. For a Controller Service, enabling and disabling are considered
* lifecycle events, as the action makes them usable or unusable by other
* components. However, for a Processor and a Reporting Task, these are not
* lifecycle events but rather a mechanism to allow a component to be excluded
* when starting or stopping a group of components.
* </p>
*
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnDisabled {
}

View File

@ -1,69 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a
* {@link org.apache.nifi.controller.ControllerService ControllerService} can
* use to indicate a method should be called whenever the service is enabled.
* Any method that has this annotation will be called every time a user enables
* the service. Additionally, each time that NiFi is restarted, if NiFi is
* configured to "auto-resume state" and the service is enabled, the method will
* be invoked.
* </p>
*
* <p>
* Methods using this annotation must take either 0 arguments or a single
* argument of type
* {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* </p>
*
* <p>
* If a method with this annotation throws a Throwable, a log message and
* bulletin will be issued for the component. In this event, the service will
* remain in an 'ENABLING' state and will not be usable. All methods with this
* annotation will then be called again after a delay. The service will not be
* made available for use until all methods with this annotation have returned
* without throwing anything.
* </p>
*
* <p>
* Note that this annotation will be ignored if applied to a ReportingTask, ParameterProvider or
* Processor. For a Controller Service, enabling and disabling are considered
* lifecycle events, as the action makes them usable or unusable by other
* components. However, for a Processor and a Reporting Task, these are not
* lifecycle events but rather a mechanism to allow a component to be excluded
* when starting or stopping a group of components.
* </p>
*
*
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnEnabled {
}

View File

@ -1,57 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.registry.flow.FlowRegistryClient FlowRegistryClient},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider},
* {@link org.apache.nifi.flowanalysis.FlowAnalysisRule FlowAnalysisRule}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
* can use to indicate a method should be called whenever the component is
* removed from the flow. This method will be called once for the entire life of
* a component instance. If the method throw any Throwable, that Throwable will
* be caught and logged but will not prevent subsequent methods with this
* annotation or removal of the component from the flow.
* </p>
*
* <p>
* Methods with this annotation are permitted to take no arguments or to take a
* single argument. If using a single argument, that argument must be of type
* {@link ConfigurationContext} if the component is a ReportingTask, a ParameterProvider, or a
* ControllerService. If the component is a Processor, then the argument must be
* of type {@link ProcessContext}.
* </p>
*
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnRemoved {
}

View File

@ -1,78 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor} or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
* can use to indicate a method should be called whenever the component is
* scheduled to run. This will be called before any call to 'onTrigger' and will
* be called once each time a Processor or Reporting Task is scheduled to run.
* This occurs in one of two ways: either a user clicks to schedule the
* component to run, or NiFi is restarted with the "auto-resume state"
* configuration set to true (the default value) and the component is already
* running.
* </p>
*
* <p>
* Methods using this annotation must take either 0 arguments or a single
* argument.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Processor,
* that argument must be of type
* {@link org.apache.nifi.processor.ProcessContext ProcessContext}.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Reporting
* Task, that argument must be of type
* {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* </p>
*
* <p>
* If any method annotated with this annotation throws any Throwable, the
* framework will wait a while and then attempt to invoke the method again. This
* will continue until the method succeeds, and the component will then be
* scheduled to run after this method return successfully.
* </p>
*
* <p><b>Implementation Guidelines:</b>
* <ul>
* <li>Methods with this annotation are expected to perform very quick, short-lived tasks. If the function is
* expensive or long-lived, the logic should be performed in the {@code onTrigger} method instead.</li>
* <li>If a method with this annotation does not return (exceptionally or otherwise) within a short period
* of time (the duration is configurable in the properties file), the Thread may be interrupted.</li>
* <li>Methods that make use of this interface should honor Java's Thread interruption mechanisms and not swallow
* {@link InterruptedException}.</li>
* </ul>
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnScheduled {
}

View File

@ -1,53 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor},
* {@link org.apache.nifi.controller.ControllerService ControllerService},
* {@link org.apache.nifi.parameter.ParameterProvider ParameterProvider}, or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
* can use to indicate a method should be called whenever the flow is being
* shutdown. This will be called at most once for each component in a JVM
* lifetime. It is not, however, guaranteed that this method will be called on
* shutdown, as the service may be killed suddenly.
* </p>
*
* <p>
* Methods with this annotation are permitted to take either 0 or 1 argument. If
* an argument is used, it must be of type {@link ConfigurationContext} if the
* component is a ReportingTask or Controller Service, or of type
* {@link ProcessContext} if the component is a Processor.
* </p>
*
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnShutdown {
}

View File

@ -1,75 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.apache.nifi.controller.ConfigurationContext;
import org.apache.nifi.processor.ProcessContext;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor} or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} implementation
* can use to indicate that a method should be called whenever the component is
* no longer scheduled to run. Methods marked with this annotation will be
* invoked each time the component is stopped and will be invoked only after the
* last thread has returned from the <code>onTrigger</code> method.
* </p>
*
* <p>
* This means that the thread executing in this method will be the only thread
* executing in any part of the Processor. However, since other threads may
* later execute other parts of the code, member variables must still be
* protected appropriately. However, access to multiple variables need not be
* atomic.
* </p>
*
* <p>
* To indicate that a method should be called immediately when a component is no
* longer scheduled to run (as opposed to after all threads have returned from
* the <code>onTrigger</code> method), see the {@link OnUnscheduled} annotation.
* </p>
*
* <p>
* Methods with this annotation are permitted to take either 0 or 1 argument. If
* an argument is used, it must be of type {@link ConfigurationContext} if the
* component is a ReportingTask or of type {@link ProcessContext} if the
* component is a Processor.
* </p>
*
* <p><b>Implementation Guidelines:</b>
* <ul>
* <li>Methods with this annotation are expected to perform very quick, short-lived tasks. If the function is
* expensive or long-lived, the logic should be performed in the {@code onTrigger} method instead.</li>
* <li>If a method with this annotation does not return (exceptionally or otherwise) within a short period
* of time (the duration is configurable in the properties file), the Thread may be interrupted.</li>
* <li>Methods that make use of this interface should honor Java's Thread interruption mechanisms and not swallow
* {@link InterruptedException}.</li>
* </ul>
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnStopped {
}

View File

@ -1,69 +0,0 @@
/*
* 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.annotation.lifecycle;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation a {@link org.apache.nifi.processor.Processor Processor} or
* {@link org.apache.nifi.reporting.ReportingTask ReportingTask} should be
* called whenever the component is no longer scheduled to run. Methods marked
* with this annotation will be invoked each time the framework is notified to
* stop scheduling the component. This method is invoked as other threads are
* potentially running. To invoke a method after all threads have finished
* processing, see the {@link OnStopped} annotation.
* </p>
*
* <p>
* Methods using this annotation must take either 0 arguments or a single
* argument.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Processor,
* that argument must be of type
* {@link org.apache.nifi.processor.ProcessContext ProcessContext}.
* </p>
*
* <p>
* If using 1 argument and the component using the annotation is a Reporting
* Task, that argument must be of type
* {@link org.apache.nifi.controller.ConfigurationContext ConfigurationContext}.
* </p>
*
* <p><b>Implementation Guidelines:</b>
* <ul>
* <li>Methods with this annotation are expected to perform very quick, short-lived tasks. If the function is
* expensive or long-lived, the logic should be performed in the {@code onTrigger} method instead.</li>
* <li>If a method with this annotation does not return (exceptionally or otherwise) within a short period
* of time (the duration is configurable in the properties file), the Thread may be interrupted.</li>
* <li>Methods that make use of this interface should honor Java's Thread interruption mechanisms and not swallow
* {@link InterruptedException}.</li>
* </ul>
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnUnscheduled {
}

View File

@ -1,44 +0,0 @@
/*
* 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.annotation.notification;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* Marker annotation that a component can use to indicate that a method should be
* called whenever the state of the Primary Node in a cluster has changed.
* </p>
*
* <p>
* Methods with this annotation should take either no arguments or one argument of type
* {@link PrimaryNodeState}. The {@link PrimaryNodeState} provides context about what changed
* so that the component can take appropriate action.
* </p>
*/
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface OnPrimaryNodeStateChange {
}

View File

@ -1,33 +0,0 @@
/*
* 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.annotation.notification;
/**
* Represents a state change that occurred for the Primary Node of a NiFi cluster.
*/
public enum PrimaryNodeState {
/**
* The node receiving this state has been elected the Primary Node of the NiFi cluster.
*/
ELECTED_PRIMARY_NODE,
/**
* The node receiving this state was the Primary Node but has now had its Primary Node
* role revoked.
*/
PRIMARY_NODE_REVOKED;
}

View File

@ -1,54 +0,0 @@
/*
* 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.asset;
import java.io.File;
import java.util.Optional;
/**
* An Asset is a representation of some resource that is necessary in order to run a dataflow.
* An Asset is always accessed as a local file.
*/
public interface Asset {
/**
* Returns a unique identifier for the Asset
*/
String getIdentifier();
/**
* Returns the identifier of the parameter context the Asset belongs to
*/
String getParameterContextIdentifier();
/**
* Returns the name of the Asset
*/
String getName();
/**
* Returns the local file that the Asset is associated with
*/
File getFile();
/**
* Returns the digest of the contents of the local file that the Asset is associated with.
* The digest will not be present when the asset is considered missing and the local file does not exist.
*/
Optional<String> getDigest();
}

View File

@ -1,261 +0,0 @@
/*
* 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.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public abstract class AbstractConfigurableComponent implements ConfigurableComponent {
/**
* Allows subclasses to perform their own validation on the already set
* properties. Since each property is validated as it is set this allows
* validation of groups of properties together. Default return is an empty
* set.
*
* This method will be called only when it has been determined that all
* property values are valid according to their corresponding
* PropertyDescriptor's validators.
*
* @param validationContext provides a mechanism for obtaining externally
* managed values, such as property values and supplies convenience methods
* for operating on those values
*
* @return Collection of ValidationResult objects that will be added to any
* other validation findings - may be null
*/
protected Collection<ValidationResult> customValidate(final ValidationContext validationContext) {
return Collections.emptySet();
}
/**
* @param descriptorName to lookup the descriptor
* @return a PropertyDescriptor for the name specified that is fully
* populated
*/
@Override
public final PropertyDescriptor getPropertyDescriptor(final String descriptorName) {
final PropertyDescriptor specDescriptor = new PropertyDescriptor.Builder().name(descriptorName).build();
return getPropertyDescriptor(specDescriptor);
}
private PropertyDescriptor getPropertyDescriptor(final PropertyDescriptor specDescriptor) {
//check if property supported
PropertyDescriptor descriptor = getSupportedPropertyDescriptor(specDescriptor);
if (descriptor != null) {
return descriptor;
}
descriptor = getSupportedDynamicPropertyDescriptor(specDescriptor.getName());
if (descriptor != null && !descriptor.isDynamic()) {
descriptor = new PropertyDescriptor.Builder().fromPropertyDescriptor(descriptor).dynamic(true).build();
}
if (descriptor == null) {
descriptor = new PropertyDescriptor.Builder().fromPropertyDescriptor(specDescriptor).addValidator(Validator.INVALID).dynamic(true).build();
}
return descriptor;
}
private PropertyDescriptor getSupportedPropertyDescriptor(final PropertyDescriptor specDescriptor) {
final List<PropertyDescriptor> supportedDescriptors = getSupportedPropertyDescriptors();
if (supportedDescriptors != null) {
for (final PropertyDescriptor desc : supportedDescriptors) { //find actual descriptor
if (specDescriptor.equals(desc)) {
return desc;
}
}
}
return null;
}
@Override
public final Collection<ValidationResult> validate(final ValidationContext context) {
// goes through context properties, should match supported properties + supported dynamic properties
final Collection<ValidationResult> results = new ArrayList<>();
final Set<PropertyDescriptor> contextDescriptors = context.getProperties().keySet();
for (final PropertyDescriptor descriptor : contextDescriptors) {
// If the property descriptor's dependency is not satisfied, the property does not need to be considered, as it's not relevant to the
// component's functionality.
final boolean dependencySatisfied = context.isDependencySatisfied(descriptor, this::getPropertyDescriptor);
if (!dependencySatisfied) {
continue;
}
validateDependencies(descriptor, context, results);
String value = context.getProperty(descriptor).getValue();
if (value == null) {
value = descriptor.getDefaultValue();
}
if (value == null && descriptor.isRequired()) {
String displayName = descriptor.getDisplayName();
ValidationResult.Builder builder = new ValidationResult.Builder().valid(false).input(null).subject(displayName != null ? displayName : descriptor.getName());
builder = (displayName != null) ? builder.explanation(displayName + " is required") : builder.explanation(descriptor.getName() + " is required");
results.add(builder.build());
continue;
} else if (value == null) {
continue;
}
final ValidationResult result = descriptor.validate(value, context);
if (!result.isValid()) {
results.add(result);
}
}
// only run customValidate if regular validation is successful. This allows Processor developers to not have to check
// if values are null or invalid so that they can focus only on the interaction between the properties, etc.
if (results.isEmpty()) {
final Collection<ValidationResult> customResults = customValidate(context);
if (null != customResults) {
for (final ValidationResult result : customResults) {
if (!result.isValid()) {
results.add(result);
}
}
}
}
return results;
}
private void validateDependencies(final PropertyDescriptor descriptor, final ValidationContext context, final Collection<ValidationResult> results) {
// Ensure that we don't have any dependencies on non-existent properties.
final Set<PropertyDependency> dependencies = descriptor.getDependencies();
for (final PropertyDependency dependency : dependencies) {
final String dependentPropertyName = dependency.getPropertyName();
// If there's a supported property descriptor then all is okay.
final PropertyDescriptor specDescriptor = new PropertyDescriptor.Builder().name(dependentPropertyName).build();
final PropertyDescriptor supportedDescriptor = getSupportedPropertyDescriptor(specDescriptor);
if (supportedDescriptor != null) {
continue;
}
final PropertyDescriptor dynamicPropertyDescriptor = getSupportedDynamicPropertyDescriptor(dependentPropertyName);
if (dynamicPropertyDescriptor == null) {
results.add(new ValidationResult.Builder()
.subject(descriptor.getDisplayName())
.valid(false)
.explanation("Property depends on property " + dependentPropertyName + ", which is not a known property")
.build());
}
// Dependent property is supported as a dynamic property. This is okay as long as there is a value set.
final PropertyValue value = context.getProperty(dynamicPropertyDescriptor);
if (value == null || !value.isSet()) {
results.add(new ValidationResult.Builder()
.subject(descriptor.getDisplayName())
.valid(false)
.explanation("Property depends on property " + dependentPropertyName + ", which is not a known property")
.build());
}
}
}
/**
* Hook method allowing subclasses to eagerly react to a configuration
* change for the given property descriptor. As an alternative to using this
* method a processor may simply get the latest value whenever it needs it
* and if necessary lazily evaluate it.
*
* @param descriptor of the modified property
* @param oldValue non-null property value (previous)
* @param newValue the new property value or if null indicates the property
* was removed
*/
@Override
public void onPropertyModified(final PropertyDescriptor descriptor, final String oldValue, final String newValue) {
}
/**
* <p>
* Used to allow subclasses to determine what PropertyDescriptor if any to
* use when a property is requested for which a descriptor is not already
* registered. By default this method simply returns a null descriptor. By
* overriding this method processor implementations can support dynamic
* properties since this allows them to register properties on demand. It is
* acceptable for a dynamically generated property to indicate it is
* required so long as it is understood it is only required once set.
* Dynamic properties by definition cannot be required until used.</p>
*
* <p>
* This method should be side effect free in the subclasses in terms of how
* often it is called for a given property name because there is guarantees
* how often it will be called for a given property name.</p>
*
* <p>
* Default is null.
*
* @param propertyDescriptorName used to lookup if any property descriptors exist for that name
* @return new property descriptor if supported
*/
protected PropertyDescriptor getSupportedDynamicPropertyDescriptor(final String propertyDescriptorName) {
return null;
}
/**
* Allows subclasses to register which property descriptor objects are
* supported. Default return is an empty set.
*
* @return PropertyDescriptor objects this processor currently supports
*/
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
return Collections.emptyList();
}
@Override
public final List<PropertyDescriptor> getPropertyDescriptors() {
final List<PropertyDescriptor> supported = getSupportedPropertyDescriptors();
return supported == null ? Collections.emptyList() : Collections.unmodifiableList(supported);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ConfigurableComponent)) {
return false;
}
final ConfigurableComponent other = (ConfigurableComponent) obj;
return getIdentifier().equals(other.getIdentifier());
}
@Override
public int hashCode() {
return 235 + getIdentifier().hashCode();
}
@Override
public String toString() {
return getClass().getSimpleName() + "[id=" + getIdentifier() + "]";
}
}

View File

@ -1,136 +0,0 @@
/*
* 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.components;
import java.util.Objects;
/**
* <p>
* Represents a valid value for a {@link PropertyDescriptor}
* </p>
*/
public class AllowableValue implements DescribedValue {
private final String value;
private final String displayName;
private final String description;
/**
* Constructs a new AllowableValue with the given value and and the same
* display name and no description.
*
* @param value that is allowed
*/
public AllowableValue(final String value) {
this(value, value);
}
/**
* Constructs a new AllowableValue with the given value and display name and
* no description
*
* @param value that is allowed
* @param displayName to display for the value
* @throws NullPointerException if either argument is null
*/
public AllowableValue(final String value, final String displayName) {
this(value, displayName, null);
}
/**
* Constructs a new AllowableValue with the given value, display name, and
* description
*
* @param value that is valid
* @param displayName to show for the value
* @param description of the value
* @throws NullPointerException if identifier or value is null
*/
public AllowableValue(final String value, final String displayName, final String description) {
this.value = Objects.requireNonNull(value);
this.displayName = Objects.requireNonNull(displayName);
this.description = description;
}
public static AllowableValue fromDescribedValue(final DescribedValue describedValue) {
if (describedValue instanceof AllowableValue allowableValue) {
return allowableValue;
}
return new AllowableValue(describedValue.getValue(), describedValue.getDisplayName(), describedValue.getDescription());
}
/**
* @return the value of this AllowableValue
*/
@Override
public String getValue() {
return value;
}
/**
* @return a human-readable name for this AllowableValue
*/
@Override
public String getDisplayName() {
return displayName;
}
/**
* @return a description for this value, or <code>null</code> if no
* description was provided
*/
@Override
public String getDescription() {
return description;
}
/**
* @return true if <code>this</code> is equal to <code>obj</code> of <code>obj</code> is the
* same object as <code>this</code> or if <code>obj</code> is an instance of
* <code>AllowableValue</code> and both have the same value, or if
* <code>obj</code> is a String and is equal to
* {@link #getValue() this.getValue()}.
*/
@Override
public boolean equals(final Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof AllowableValue other) {
return (this.value.equals(other.getValue()));
} else if (obj instanceof String) {
return this.value.equals(obj);
}
return false;
}
/**
* @return based solely off of the value
*/
@Override
public int hashCode() {
return 23984731 + 17 * value.hashCode();
}
@Override
public String toString() {
return value;
}
}

View File

@ -1,60 +0,0 @@
/*
* 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.components;
import org.apache.nifi.context.PropertyContext;
/**
* <p>
* There are times when a component must be created in such a way that each instance gets its own ClassLoader hierarchy,
* rather than sharing the ClassLoader with other components (see {@link org.apache.nifi.annotation.behavior.RequiresInstanceClassLoading @RequiresInstanceClassLoading}).
* This, however, can be extremely expensive, as all of the classes must be loaded again for each instance of the component. When thousands of these
* components are used in a single flow, the startup time can be great, and it can lead to massive amounts of RAM being required.
* </p>
*
* <p>
* For components that do require instance ClassLoading that clones ancestor resources, this interface can be optional implemented by the component.
* If the interface is implemented, the component is given the opportunity to return a distinct "key" that can be used to identify instances that may share
* the same ClassLoader.
* </p>
*/
public interface ClassloaderIsolationKeyProvider {
/**
* <p>
* Determines the key that identifies a shared ClassLoader that this component may use. Any two instances of the same component that return
* the same key may be assigned the same base ClassLoader (though it is not guaranteed that this will be the case).
* </p>
*
* <p>
* If a subsequent call to this method returns a different value, the component will be recreated with a different ClassLoader.
* </p>
*
* <p>
* Implementation Note: for components that implement this interface, this method will be called often. Therefore, performance characteristics
* of the implementation are critical. The method is expected to return the value of a configured property or derive a value to return based off
* of the values of a few properties. Accessing a remote resource, is too expensive. If the necessary computation is non-trivial, then it should be
* performed out of band and the pre-computed value simply returned by this method.
* </p>
*
* @param context the PropertyContext that can be used for determining the key
* @return a distinct key that can be used to indicate which shared ClassLoader is allowed to be used
*/
String getClassloaderIsolationKey(PropertyContext context);
}

View File

@ -1,83 +0,0 @@
/*
* 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.components;
public class ConfigVerificationResult {
private final Outcome outcome;
private final String verificationStepName;
private final String explanation;
private ConfigVerificationResult(final Builder builder) {
outcome = builder.outcome;
verificationStepName = builder.verificationStepName;
explanation = builder.explanation;
}
public Outcome getOutcome() {
return outcome;
}
public String getVerificationStepName() {
return verificationStepName;
}
public String getExplanation() {
return explanation;
}
@Override
public String toString() {
return "ConfigVerificationResult[" +
"outcome=" + outcome +
", verificationStepName='" + verificationStepName + "'" +
", explanation='" + explanation + "']";
}
public static class Builder {
private Outcome outcome = Outcome.SKIPPED;
private String verificationStepName = "Unknown Step Name";
private String explanation;
public Builder outcome(final Outcome outcome) {
this.outcome = outcome;
return this;
}
public Builder verificationStepName(final String verificationStepName) {
this.verificationStepName = verificationStepName;
return this;
}
public Builder explanation(final String explanation) {
this.explanation = explanation;
return this;
}
public ConfigVerificationResult build() {
return new ConfigVerificationResult(this);
}
}
public enum Outcome {
SUCCESSFUL,
FAILED,
SKIPPED;
}
}

View File

@ -1,83 +0,0 @@
/*
* 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.components;
import java.util.Collection;
import java.util.List;
import org.apache.nifi.annotation.lifecycle.OnConfigurationRestored;
public interface ConfigurableComponent {
/**
* Validates a set of properties, returning ValidationResults for any
* invalid properties. All defined properties will be validated. If they are
* not included in the purposed configuration, the default value will
* be used.
*
* @param context of validation
* @return Collection of validation result objects for any invalid findings
* only. If the collection is empty then the component is valid. Guaranteed
* non-null
*/
Collection<ValidationResult> validate(ValidationContext context);
/**
* @param name to lookup the descriptor
* @return the PropertyDescriptor with the given name, if it exists;
* otherwise, returns <code>null</code>
*/
PropertyDescriptor getPropertyDescriptor(String name);
/**
* Hook method allowing subclasses to eagerly react to a configuration
* change for the given property descriptor. This method will be invoked
* regardless of property validity. As an alternative to using this method,
* a component may simply get the latest value whenever it needs it and if
* necessary lazily evaluate it. Any throwable that escapes this method will
* simply be ignored.
*
* When NiFi is restarted, this method will be called for each 'dynamic' property that is
* added, as well as for each property that is not set to the default value. I.e., if the
* Properties are modified from the default values. If it is undesirable for your use case
* to react to properties being modified in this situation, you can add the {@link OnConfigurationRestored}
* annotation to a method - this will allow the Processor to know when configuration has
* been restored, so that it can determine whether or not to perform some action in the
* onPropertyModified method.
*
* @param descriptor the descriptor for the property being modified
* @param oldValue the value that was previously set, or null if no value
* was previously set for this property
* @param newValue the new property value or if null indicates the property
* was removed
*/
void onPropertyModified(PropertyDescriptor descriptor, String oldValue, String newValue);
/**
* Returns a {@link List} of all {@link PropertyDescriptor}s that this
* component supports.
*
* @return PropertyDescriptor objects this component currently supports
*/
List<PropertyDescriptor> getPropertyDescriptors();
/**
* @return the unique identifier that the framework assigned to this
* component
*/
String getIdentifier();
}

View File

@ -1,38 +0,0 @@
/*
* 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.components;
/**
* Describes a component property value with display name and description.
*/
public interface DescribedValue {
/**
* @return the property value as a string
*/
String getValue();
/**
* @return the property display name as a string
*/
String getDisplayName();
/**
* @return the proeprty description as a string
*/
String getDescription();
}

View File

@ -1,31 +0,0 @@
/*
* 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.components;
public enum PortFunction {
/**
* Port functions as a standard port, transferring FlowFiles to all outgoing connections.
*/
STANDARD,
/**
* Port denotes that the invocation of the stateless flow has failed. If run using the Standard Engine, will operate as a Standard port. If running
* using the Stateless Engine, the transaction is rolled back, and any input FlowFiles will be transferred to this Port.
*/
FAILURE;
}

View File

@ -1,98 +0,0 @@
/*
* 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.components;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class PropertyDependency {
private final String propertyName;
private final String displayName;
private final Set<String> dependentValues;
/**
* Creates a dependency that is satisfied if any value is set for the property with the given name
* @param propertyName the name of the property that is depended upon
* @param propertyDisplayName the display name of the property that is depended upon
*/
public PropertyDependency(final String propertyName, final String propertyDisplayName) {
this.propertyName = Objects.requireNonNull(propertyName);
this.displayName = propertyDisplayName == null ? propertyName : propertyDisplayName;
this.dependentValues = null;
}
/**
* Creates a dependency that is satisfied only if the property with the given name has a value that is in the given set of dependent values
* @param propertyName the name of the property that is depended upon
* @param propertyDisplayName the display name of the property that is depended upon
* @param dependentValues the values that satisfy the dependency
*/
public PropertyDependency(final String propertyName, final String propertyDisplayName, final Set<String> dependentValues) {
this.propertyName = Objects.requireNonNull(propertyName);
this.displayName = propertyDisplayName == null ? propertyName : propertyDisplayName;
this.dependentValues = Collections.unmodifiableSet(new HashSet<>(Objects.requireNonNull(dependentValues)));
}
/**
* @return the name of the property that is depended upon
*/
public String getPropertyName() {
return propertyName;
}
/**
* @return the display name of the property that is depended upon
*/
public String getPropertyDisplayName() {
return displayName;
}
/**
* @return the Set of values that satisfy the dependency
*/
public Set<String> getDependentValues() {
return dependentValues;
}
@Override
public String toString() {
return "PropertyDependency[propertyName=" + propertyName + ", displayName=" + displayName + ", dependentValues=" + dependentValues + "]";
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final PropertyDependency that = (PropertyDependency) o;
return Objects.equals(getPropertyName(), that.getPropertyName())
&& Objects.equals(getDependentValues(), that.getDependentValues());
}
@Override
public int hashCode() {
return Objects.hash(getPropertyName(), getDependentValues());
}
}

View File

@ -1,910 +0,0 @@
/*
* 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.components;
import org.apache.nifi.components.resource.ResourceCardinality;
import org.apache.nifi.components.resource.ResourceDefinition;
import org.apache.nifi.components.resource.ResourceReference;
import org.apache.nifi.components.resource.ResourceType;
import org.apache.nifi.components.resource.StandardResourceDefinition;
import org.apache.nifi.components.resource.StandardResourceReferenceFactory;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.expression.ExpressionLanguageScope;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
/**
* An immutable object for holding information about a type of component
* property.
*/
public final class PropertyDescriptor implements Comparable<PropertyDescriptor> {
public static final PropertyDescriptor NULL_DESCRIPTOR = new PropertyDescriptor.Builder().name("").build();
/**
* The proper name for the property. This is the primary mechanism of
* comparing equality.
*/
private final String name;
/**
* The name that should be displayed to user when referencing this property
*/
private final String displayName;
/**
* And explanation of the meaning of the given property. This description is
* meant to be displayed to a user or simply provide a mechanism of
* documenting intent.
*/
private final String description;
/**
* The default value for this property
*/
private final String defaultValue;
/**
* The allowable values for this property. If empty then the allowable
* values are not constrained
*/
private final List<AllowableValue> allowableValues;
/**
* Determines whether the property is required for this processor
*/
private final boolean required;
/**
* indicates that the value for this property should be considered sensitive
* and protected whenever stored or represented
*/
private final boolean sensitive;
/**
* indicates whether this property well-known for this processor or is
* user-defined
*/
private final boolean dynamic;
/**
* indicates whether or nor this property will evaluate expression language
* against the flow file attributes
*/
private final ExpressionLanguageScope expressionLanguageScope;
/**
* indicates whether or not this property represents resources that should be added
* to the classpath and used for loading native libraries for this instance of the component
*/
private final boolean dynamicallyModifiesClasspath;
/**
* the interface of the {@link ControllerService} that this Property refers
* to; will be null if not identifying a ControllerService.
*/
private final Class<? extends ControllerService> controllerServiceDefinition;
/**
* The validators that should be used whenever an attempt is made to set
* this property value. Any allowable values specified will be checked first
* and any validators specified will be ignored.
*/
private final List<Validator> validators;
/**
* The list of dependencies that this property has on other properties
*/
private final Set<PropertyDependency> dependencies;
/**
* The definition of the resource(s) that this property references
*/
private final ResourceDefinition resourceDefinition;
protected PropertyDescriptor(final Builder builder) {
this.displayName = builder.displayName == null ? builder.name : builder.displayName;
this.name = builder.name;
this.description = builder.description;
this.defaultValue = builder.defaultValue;
this.allowableValues = builder.allowableValues == null ? null : List.copyOf(builder.allowableValues);
this.required = builder.required;
this.sensitive = builder.sensitive;
this.dynamic = builder.dynamic;
this.dynamicallyModifiesClasspath = builder.dynamicallyModifiesClasspath;
this.expressionLanguageScope = builder.expressionLanguageScope;
this.controllerServiceDefinition = builder.controllerServiceDefinition;
this.validators = List.copyOf(builder.validators);
this.dependencies = builder.dependencies == null ? Collections.emptySet() : Set.copyOf(builder.dependencies);
this.resourceDefinition = builder.resourceDefinition;
}
@Override
public int compareTo(final PropertyDescriptor o) {
if (o == null) {
return -1;
}
return getName().compareTo(o.getName());
}
/**
* Validates the given input against this property descriptor's validator.
* If this descriptor has a set of allowable values then the given value is
* only checked against the allowable values.
*
* @param input the value to validate
* @param context the context of validation
* @return the result of validating the input
*/
public ValidationResult validate(final String input, final ValidationContext context) {
ValidationResult lastResult = Validator.INVALID.validate(this.name, input, context);
if (allowableValues != null && !allowableValues.isEmpty()) {
final ConstrainedSetValidator csValidator = new ConstrainedSetValidator(allowableValues);
final ValidationResult csResult = csValidator.validate(this.name, input, context);
if (csResult.isValid()) {
lastResult = csResult;
} else {
return csResult;
}
}
final ResourceDefinition resourceDefinition = getResourceDefinition();
if (resourceDefinition != null) {
final Validator validator = new ResourceDefinitionValidator(resourceDefinition, this.expressionLanguageScope);
final ValidationResult result = validator.validate(this.name, input, context);
if (!result.isValid()) {
return result;
}
lastResult = result;
}
for (final Validator validator : validators) {
lastResult = validator.validate(this.name, input, context);
if (!lastResult.isValid()) {
break;
}
}
if (getControllerServiceDefinition() != null) {
final ControllerService service = context.getControllerServiceLookup().getControllerService(input);
if (service == null) {
return new ValidationResult.Builder()
.input(input)
.subject(getDisplayName())
.valid(false)
.explanation("Property references a Controller Service that does not exist")
.build();
} else {
return new ValidationResult.Builder()
.valid(true)
.build();
}
}
return lastResult;
}
public static final class Builder {
private String displayName = null;
private String name = null;
private String description = "";
private String defaultValue = null;
private List<AllowableValue> allowableValues = null;
private Set<PropertyDependency> dependencies = null;
private boolean required = false;
private boolean sensitive = false;
private ExpressionLanguageScope expressionLanguageScope = ExpressionLanguageScope.NONE;
private boolean dynamic = false;
private boolean dynamicallyModifiesClasspath = false;
private Class<? extends ControllerService> controllerServiceDefinition;
private ResourceDefinition resourceDefinition;
private List<Validator> validators = new ArrayList<>();
public Builder fromPropertyDescriptor(final PropertyDescriptor specDescriptor) {
this.name = specDescriptor.name;
this.displayName = specDescriptor.displayName;
this.description = specDescriptor.description;
this.defaultValue = specDescriptor.defaultValue;
this.allowableValues = specDescriptor.allowableValues == null ? null : new ArrayList<>(specDescriptor.allowableValues);
this.required = specDescriptor.required;
this.sensitive = specDescriptor.sensitive;
this.dynamic = specDescriptor.dynamic;
this.dynamicallyModifiesClasspath = specDescriptor.dynamicallyModifiesClasspath;
this.expressionLanguageScope = specDescriptor.expressionLanguageScope;
this.controllerServiceDefinition = specDescriptor.getControllerServiceDefinition();
this.validators = new ArrayList<>(specDescriptor.validators);
this.dependencies = new HashSet<>(specDescriptor.dependencies);
this.resourceDefinition = specDescriptor.resourceDefinition;
return this;
}
/**
* Sets a unique id for the property. This field is optional and if not
* specified the PropertyDescriptor's name will be used as the
* identifying attribute. However, by supplying an id, the
* PropertyDescriptor's name can be changed without causing problems.
* This is beneficial because it allows a User Interface to represent
* the name differently.
*
* @param displayName of the property
* @return the builder
*/
public Builder displayName(final String displayName) {
if (null != displayName) {
this.displayName = displayName;
}
return this;
}
/**
* Sets the property name.
*
* @param name of the property
* @return the builder
*/
public Builder name(final String name) {
if (null != name) {
this.name = name;
}
return this;
}
/**
* Sets the scope of the expression language evaluation
*
* @param expressionLanguageScope scope of the expression language evaluation
* @return the builder
*/
public Builder expressionLanguageSupported(final ExpressionLanguageScope expressionLanguageScope) {
this.expressionLanguageScope = expressionLanguageScope;
return this;
}
/**
* @param description of the property
* @return the builder
*/
public Builder description(final String description) {
if (null != description) {
this.description = description;
}
return this;
}
/**
* Specifies the initial value and the default value that will be used if the user does not specify a value.
* <p>
* When {@link #build()} is called, if Allowable Values have been set (see {@link #allowableValues(DescribedValue...)} and overloads)
* and this value is not one of those Allowable Values, an Exception will be thrown.
* If the Allowable Values have been set, the default value should be set to
* the "Value" of the {@link DescribedValue} object (see {@link DescribedValue#getValue()}).
* There's an overload available for this (see {@link #defaultValue(DescribedValue)}).
*
* @param value default value
* @return the builder
*/
public Builder defaultValue(final String value) {
if (null != value) {
this.defaultValue = value;
}
return this;
}
/**
* Specifies the initial value and the default value that will be used if the user does not specify a value.
* <p>
* Sets the default value to the "Value" of the {@link DescribedValue} object.
* When {@link #build()} is called, if Allowable Values have been set (see {@link #allowableValues(DescribedValue...)} and overloads)
* and this value is not one of those Allowable Values, an Exception will be thrown.
* In case there is not a restricted set of Allowable Values {@link #defaultValue(String)} may be used.
*
* @param value default value holder
* @return the builder
*/
public Builder defaultValue(final DescribedValue value) {
return defaultValue(value != null ? value.getValue() : null);
}
/**
* Clears the initial value and default value from this Property.
*
* @return the builder
*/
public Builder clearDefaultValue() {
this.defaultValue = null;
return this;
}
public Builder dynamic(final boolean dynamic) {
this.dynamic = dynamic;
return this;
}
/**
* Specifies that the value of this property represents one or more resources that the
* framework should add to the classpath of as well as consider when looking for native
* libraries for the given component.
* <p/>
* NOTE: If a component contains a PropertyDescriptor where dynamicallyModifiesClasspath is set to true,
* the component may also be annotated with @RequiresInstanceClassloading, in which case every class will
* be loaded by a separate InstanceClassLoader for each processor instance.<br/>
* It also allows to load native libraries from the extra classpath.
* <p/>
* One can choose to omit the annotation. In this case the loading of native libraries from the extra classpath
* is not supported.
* Also by default, classes will be loaded by a common NarClassLoader, however it's possible to acquire an
* InstanceClassLoader by calling Thread.currentThread().getContextClassLoader() which can be used manually
* to load required classes on an instance-by-instance basis
* (by calling {@link Class#forName(String, boolean, ClassLoader)} for example).
* <p>
* Any property descriptor that dynamically modifies the classpath should also make use of the {@link #identifiesExternalResource(ResourceCardinality, ResourceType, ResourceType...)} method
* to indicate that the property descriptor references external resources and optionally restrict which types of resources and how many resources the property allows.
*
* @param dynamicallyModifiesClasspath whether or not this property should be used by the framework to modify the classpath
* @return the builder
*/
public Builder dynamicallyModifiesClasspath(final boolean dynamicallyModifiesClasspath) {
this.dynamicallyModifiesClasspath = dynamicallyModifiesClasspath;
return this;
}
/**
* Sets the Allowable Values for this Property.
*
* @param values constrained set of values
* @return the builder
*/
public Builder allowableValues(final Set<String> values) {
if (null != values) {
this.allowableValues = values.stream().map(AllowableValue::new).toList();
}
return this;
}
/**
* Sets the Allowable Values for this Property.
* <p>
* Uses the {@link Enum#name()} of each value as "Value" for the {@link AllowableValue}.
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
*
* @param values constrained set of values
* @return the builder
*/
public <E extends Enum<E>> Builder allowableValues(final E[] values) {
if (null != values) {
this.allowableValues = Arrays.stream(values)
.map(enumValue -> enumValue instanceof DescribedValue describedValue
? AllowableValue.fromDescribedValue(describedValue) : new AllowableValue(enumValue.name()))
.toList();
}
return this;
}
/**
* Sets the Allowable Values for this Property.
* <p>
* Uses the {@link Enum#name()} of each value from {@link Class#getEnumConstants()} as "Value" for the {@link AllowableValue}.
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
*
* @param enumClass an enum class that contains a set of values and optionally implements the DescribedValue interface
* @param <E> generic parameter for an enum class, that may implement the DescribedValue interface
* @return the builder
*/
public <E extends Enum<E>> Builder allowableValues(final Class<E> enumClass) {
return allowableValues(enumClass.getEnumConstants());
}
/**
* Sets the Allowable Values for this Property.
* <p>
* Uses the {@link Enum#name()} of each value of the {@link EnumSet} as "Value" for the {@link AllowableValue}.
* In case the enum value is a {@link DescribedValue}, uses the information provided instead
* (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()}, {@link DescribedValue#getDescription()}).
*
* @param enumValues an enum set that contains a set of values and optionally implements the DescribedValue interface
* @param <E> generic parameter for an enum class, that may implement the DescribedValue interface
* @return the builder
*/
public <E extends Enum<E>> Builder allowableValues(final EnumSet<E> enumValues) {
if (null != enumValues) {
this.allowableValues = enumValues.stream()
.map(enumValue -> enumValue instanceof DescribedValue describedValue
? AllowableValue.fromDescribedValue(describedValue) : new AllowableValue(enumValue.name()))
.toList();
}
return this;
}
/**
* Sets the Allowable Values for this Property.
*
* @param values constrained set of values
* @return the builder
*/
public Builder allowableValues(final String... values) {
if (null != values) {
this.allowableValues = Arrays.stream(values).map(AllowableValue::new).toList();
}
return this;
}
/**
* Sets the Allowable Values for this Property.
* <p>
* Uses the information provided by each {@link DescribedValue} (see {@link DescribedValue#getValue()}, {@link DescribedValue#getDisplayName()},
* {@link DescribedValue#getDescription()}) to populate the {@link AllowableValue}s.
*
* @param values constrained set of values
* @return the builder
*/
public Builder allowableValues(final DescribedValue... values) {
if (null != values) {
this.allowableValues = Arrays.stream(values).map(AllowableValue::fromDescribedValue).toList();
}
return this;
}
/**
* Clears all Allowable Values from this Property
*
* @return the builder
*/
public Builder clearAllowableValues() {
this.allowableValues = null;
return this;
}
/**
* @param required true if yes; false otherwise
* @return the builder
*/
public Builder required(final boolean required) {
this.required = required;
return this;
}
/**
* @param sensitive true if sensitive; false otherwise
* @return the builder
*/
public Builder sensitive(final boolean sensitive) {
this.sensitive = sensitive;
return this;
}
/**
* @param validator for the property
* @return the builder
*/
public Builder addValidator(final Validator validator) {
if (validator != null) {
validators.add(validator);
}
return this;
}
/**
* Clear all Validators from this Property
*
* @return the builder
*/
public Builder clearValidators() {
validators.clear();
return this;
}
/**
* Specifies that this property provides the identifier of a Controller
* Service that implements the given interface
*
* @param controllerServiceDefinition the interface that is implemented
* by the Controller Service
* @return the builder
*/
public Builder identifiesControllerService(final Class<? extends ControllerService> controllerServiceDefinition) {
if (controllerServiceDefinition != null) {
this.controllerServiceDefinition = controllerServiceDefinition;
}
return this;
}
private boolean isValueAllowed(final String value) {
if (allowableValues == null || value == null) {
return true;
}
for (final AllowableValue allowableValue : allowableValues) {
if (allowableValue.getValue().equals(value)) {
return true;
}
}
return false;
}
/**
* Specifies that this property references one or more resources that are external to NiFi that the component is meant to consume.
* Any property descriptor that identifies an external resource will be automatically validated against the following rules:
* <ul>
* <li>If the ResourceCardinality is SINGLE, the given property value must be a file, a directory, or a URL that uses a protocol of http/https/file.</li>
* <li>The given resourceTypes dictate which types of input are allowed. For example, if <code>identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE)</code>
* is used, the input must be a regular file. If <code>identifiesExternalResource(ResourceCardinality.SINGLE, ResourceType.FILE, ResourceType.DIRECTORY)</code> is used, then the input
* must be exactly one file OR directory.
* </li>
* <li>If the ResourceCardinality is MULTIPLE, the given property value may consist of one or more resources, each separted by a comma and optional white space.</li>
* </ul>
* <p>
* Generally, any property descriptor that makes use of the {@link #dynamicallyModifiesClasspath(boolean)} method to dynamically update its classpath should also
* make use of this method, specifying which types of resources are allowed and how many.
*
* @param cardinality specifies how many resources the property should allow
* @param resourceType the type of resource that is allowed
* @param additionalResourceTypes if more than one type of resource is allowed, any resource type in addition to the given resource type may be provided
* @return the builder
*/
public Builder identifiesExternalResource(final ResourceCardinality cardinality, final ResourceType resourceType, final ResourceType... additionalResourceTypes) {
Objects.requireNonNull(cardinality);
Objects.requireNonNull(resourceType);
final Set<ResourceType> resourceTypes = new HashSet<>();
resourceTypes.add(resourceType);
resourceTypes.addAll(Arrays.asList(additionalResourceTypes));
this.resourceDefinition = new StandardResourceDefinition(cardinality, resourceTypes);
return this;
}
/**
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a non-null value.
* Furthermore, if one or more explicit Allowable Values are provided, this Property will not be relevant unless the given Property's value is equal to one of the given Allowable Values.
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
* <p>
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
* Allowable Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
* will still be valid, because the value of this property is irrelevant.
* <p>
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
*
* @param property the property that must be set in order for this property to become relevant
* @param dependentValues the possible values for the given property for which this Property is relevant
* @return the builder
*/
public Builder dependsOn(final PropertyDescriptor property, final AllowableValue... dependentValues) {
if (dependencies == null) {
dependencies = new HashSet<>();
}
if (dependentValues.length == 0) {
dependencies.add(new PropertyDependency(property.getName(), property.getDisplayName()));
} else {
final Set<String> dependentValueSet = new HashSet<>();
for (final AllowableValue value : dependentValues) {
dependentValueSet.add(value.getValue());
}
dependencies.add(new PropertyDependency(property.getName(), property.getDisplayName(), dependentValueSet));
}
return this;
}
/**
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a value equal to one of the given
* <code>String</code> arguments.
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
* <p>
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
* Allowable Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
* will still be valid, because the value of this property is irrelevant.
* <p>
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
*
* @param property the property that must be set in order for this property to become relevant
* @param firstDependentValue the first value for the given property for which this Property is relevant
* @param additionalDependentValues any other values for the given property for which this Property is relevant
* @return the builder
*/
public Builder dependsOn(final PropertyDescriptor property, final String firstDependentValue, final String... additionalDependentValues) {
final AllowableValue[] dependentValues = new AllowableValue[additionalDependentValues.length + 1];
dependentValues[0] = new AllowableValue(firstDependentValue);
int i = 1;
for (final String additionalDependentValue : additionalDependentValues) {
dependentValues[i++] = new AllowableValue(additionalDependentValue);
}
return dependsOn(property, dependentValues);
}
/**
* Establishes a relationship between this Property and the given property by declaring that this Property is only relevant if the given Property has a value equal to one of the given
* {@link DescribedValue} arguments.
* If this method is called multiple times, each with a different dependency, then a relationship is established such that this Property is relevant only if all dependencies are satisfied.
* <p>
* In the case that this property is NOT considered to be relevant (meaning that it depends on a property whose value is not specified, or whose value does not match one of the given
* Described Values), the property will not be shown in the component's configuration in the User Interface. Additionally, this property's value will not be considered for
* validation. That is, if this property is configured with an invalid value and this property depends on Property Foo, and Property Foo does not have a value set, then the component
* will still be valid, because the value of this property is irrelevant.
* <p>
* If the given property is not relevant (because its dependencies are not satisfied), this property is also considered not to be valid.
*
* @param property the property that must be set in order for this property to become relevant
* @param firstDependentValue the first value for the given property for which this Property is relevant
* @param additionalDependentValues any other values for the given property for which this Property is relevant
* @return the builder
*/
public Builder dependsOn(final PropertyDescriptor property, final DescribedValue firstDependentValue, final DescribedValue... additionalDependentValues) {
final AllowableValue[] dependentValues = new AllowableValue[additionalDependentValues.length + 1];
dependentValues[0] = AllowableValue.fromDescribedValue(firstDependentValue);
int i = 1;
for (final DescribedValue additionalDependentValue : additionalDependentValues) {
dependentValues[i++] = AllowableValue.fromDescribedValue(additionalDependentValue);
}
return dependsOn(property, dependentValues);
}
/**
* Clear all Dependencies from this Property
*
* @return the builder
*/
public Builder clearDependsOn() {
this.dependencies = new HashSet<>();
return this;
}
/**
* @return a PropertyDescriptor as configured
* @throws IllegalStateException if allowable values are configured but
* no default value is set, or the default value is not contained within
* the allowable values.
*/
public PropertyDescriptor build() {
if (name == null) {
throw new IllegalStateException("Must specify a name");
}
if (!isValueAllowed(defaultValue)) {
throw new IllegalStateException("Default value [" + defaultValue + "] is not in the set of allowable values");
}
return new PropertyDescriptor(this);
}
}
public String getDisplayName() {
return displayName;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public String getDefaultValue() {
return defaultValue;
}
public boolean isRequired() {
return required;
}
public boolean isSensitive() {
return sensitive;
}
public boolean isDynamic() {
return dynamic;
}
public boolean isExpressionLanguageSupported() {
return !expressionLanguageScope.equals(ExpressionLanguageScope.NONE);
}
public ExpressionLanguageScope getExpressionLanguageScope() {
return expressionLanguageScope;
}
public boolean isDynamicClasspathModifier() {
return dynamicallyModifiesClasspath;
}
public Class<? extends ControllerService> getControllerServiceDefinition() {
return controllerServiceDefinition;
}
public List<Validator> getValidators() {
return validators;
}
public List<AllowableValue> getAllowableValues() {
return allowableValues;
}
public Set<PropertyDependency> getDependencies() {
return dependencies;
}
public ResourceDefinition getResourceDefinition() {
return resourceDefinition;
}
@Override
public boolean equals(final Object other) {
if (this == other) {
return true;
}
if (other instanceof PropertyDescriptor otherPropertyDescriptor) {
return this.name.equals(otherPropertyDescriptor.name);
}
return false;
}
@Override
public int hashCode() {
return 287 + this.name.hashCode() * 47;
}
@Override
public String toString() {
return getClass().getSimpleName() + "[" + displayName + "]";
}
private static final class ConstrainedSetValidator implements Validator {
private static final String POSITIVE_EXPLANATION = "Given value found in allowed set";
private static final String NEGATIVE_EXPLANATION = "Given value not found in allowed set '%1$s'";
private static final String VALUE_DELIMITER = ", ";
private final String validStrings;
private final Collection<String> validValues;
/**
* Constructs a validator that will check if the given value is in the
* given set.
*
* @param validValues values which are acceptible
* @throws NullPointerException if the given validValues is null
*/
private ConstrainedSetValidator(final Collection<AllowableValue> validValues) {
this.validValues = validValues.stream().map(AllowableValue::getValue).toList();
this.validStrings = String.join(VALUE_DELIMITER, this.validValues);
}
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
final ValidationResult.Builder builder = new ValidationResult.Builder();
builder.input(input);
builder.subject(subject);
if (validValues.contains(input)) {
builder.valid(true);
builder.explanation(POSITIVE_EXPLANATION);
} else {
builder.valid(false);
builder.explanation(String.format(NEGATIVE_EXPLANATION, validStrings));
}
return builder.build();
}
}
private static class ResourceDefinitionValidator implements Validator {
private final ResourceDefinition resourceDefinition;
private final ExpressionLanguageScope expressionLanguageScope;
public ResourceDefinitionValidator(final ResourceDefinition resourceDefinition, final ExpressionLanguageScope expressionLanguageScope) {
this.resourceDefinition = resourceDefinition;
this.expressionLanguageScope = expressionLanguageScope;
}
@Override
public ValidationResult validate(final String subject, final String configuredInput, final ValidationContext context) {
final ValidationResult.Builder resultBuilder = new ValidationResult.Builder()
.input(configuredInput)
.subject(subject);
if (configuredInput == null) {
return resultBuilder.valid(false)
.explanation("No value specified")
.build();
}
// If Expression Language is supported and is used in the property value, we cannot perform validation against the configured
// input unless the Expression Language is expressly limited to only env/syst properties variables. In that case, we can evaluate
// it and then validate the value after evaluating the Expression Language.
String input = configuredInput;
if (context.isExpressionLanguageSupported(subject) && context.isExpressionLanguagePresent(configuredInput)) {
if (expressionLanguageScope != null && expressionLanguageScope == ExpressionLanguageScope.ENVIRONMENT) {
input = context.newPropertyValue(configuredInput).evaluateAttributeExpressions().getValue();
resultBuilder.input(input);
} else {
return resultBuilder.valid(true)
.explanation("Expression Language is present, so validation of property value cannot be performed")
.build();
}
}
// If the property can be text, then there's nothing to validate. Anything that is entered may be valid.
// This will be improved in the future, by allowing the user to specify the type of resource that is being referenced.
// Until then, we will simply require that the component perform any necessary validation.
final boolean allowsText = resourceDefinition.getResourceTypes().contains(ResourceType.TEXT);
if (allowsText) {
return resultBuilder.valid(true)
.explanation("Property allows for Resource Type of Text, so validation of property value cannot be performed")
.build();
}
final String[] splits = input.split(",");
if (resourceDefinition.getCardinality() == ResourceCardinality.SINGLE && splits.length > 1) {
return resultBuilder.valid(false)
.explanation("Property only supports a single Resource but " + splits.length + " resources were specified")
.build();
}
final Set<ResourceType> resourceTypes = resourceDefinition.getResourceTypes();
final List<String> nonExistentResources = new ArrayList<>();
int count = 0;
for (final String split : splits) {
final ResourceReference resourceReference = new StandardResourceReferenceFactory().createResourceReference(split, resourceDefinition);
if (resourceReference == null) {
continue;
}
count++;
final boolean accessible = resourceReference.isAccessible();
if (!accessible) {
nonExistentResources.add(resourceReference.getLocation());
continue;
}
if (!resourceTypes.contains(resourceReference.getResourceType())) {
return resultBuilder.valid(false)
.explanation("Specified Resource is a " + resourceReference.getResourceType().name() + " but this property does not allow this type of resource")
.build();
}
}
if (count == 0) {
return resultBuilder.valid(false)
.explanation("No resources were specified")
.build();
}
if (!nonExistentResources.isEmpty()) {
return resultBuilder.valid(false)
.explanation("The specified resource(s) do not exist or could not be accessed: " + nonExistentResources)
.build();
}
return resultBuilder.valid(true)
.build();
}
}
}

View File

@ -1,371 +0,0 @@
/*
* 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.components;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.nifi.components.resource.ResourceReference;
import org.apache.nifi.components.resource.ResourceReferences;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.expression.AttributeValueDecorator;
import org.apache.nifi.flowfile.FlowFile;
import org.apache.nifi.processor.DataUnit;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.registry.EnvironmentVariables;
/**
* <p>
* A PropertyValue provides a mechanism whereby the currently configured value
* of a processor property can be obtained in different forms.
* </p>
*/
public interface PropertyValue {
/**
* @return the raw property value as a string
*/
String getValue();
/**
* @return an integer representation of the property value, or
* <code>null</code> if not set
* @throws NumberFormatException if not able to parse
*/
Integer asInteger();
/**
* @return a Long representation of the property value, or <code>null</code>
* if not set
* @throws NumberFormatException if not able to parse
*/
Long asLong();
/**
* @return a Boolean representation of the property value, or
* <code>null</code> if not set
*/
Boolean asBoolean();
/**
* @return a Float representation of the property value, or
* <code>null</code> if not set
* @throws NumberFormatException if not able to parse
*/
Float asFloat();
/**
* @return a Double representation of the property value, of
* <code>null</code> if not set
* @throws NumberFormatException if not able to parse
*/
Double asDouble();
/**
* @param timeUnit specifies the TimeUnit to convert the time duration into
* @return a Long value representing the value of the configured time period
* in terms of the specified TimeUnit; if the property is not set, returns
* <code>null</code>
*/
Long asTimePeriod(TimeUnit timeUnit);
/**
* Returns the value as a Duration
*
* @return a Duration representing the value, or <code>null</code> if the value is unset
*/
Duration asDuration();
/**
*
* @param dataUnit specifies the DataUnit to convert the data size into
* @return a Long value representing the value of the configured data size
* in terms of the specified DataUnit; if hte property is not set, returns
* <code>null</code>
*/
Double asDataSize(DataUnit dataUnit);
/**
* @return the ControllerService whose identifier is the raw value of
* <code>this</code>, or <code>null</code> if either the value is not set or
* the value does not identify a ControllerService
*/
ControllerService asControllerService();
/**
* @param <T> the generic type of the controller service
* @param serviceType the class of the Controller Service
* @return the ControllerService whose identifier is the raw value of the
* <code>this</code>, or <code>null</code> if either the value is not set or
* the value does not identify a ControllerService. The object returned by
* this method is explicitly cast to type specified, if the type specified
* is valid. Otherwise, throws an IllegalArgumentException
*
* @throws IllegalArgumentException if the value of <code>this</code> points
* to a ControllerService but that service is not of type
* <code>serviceType</code> or if <code>serviceType</code> references a
* class that is not an interface
*/
<T extends ControllerService> T asControllerService(Class<T> serviceType) throws IllegalArgumentException;
/**
* @return a ResourceReference for the configured property value, or <code>null</code> if no value was specified, or if the property references multiple resources.
* @see #asResources()
*/
ResourceReference asResource();
/**
* @return a ResourceReferences for the configured property value. If no property value is set, a ResourceReferences will be returned that references no resources.
* I.e., this method will never return <code>null</code>.
*/
ResourceReferences asResources();
/**
* Returns the property value as one of the configured allowableValues, see {@link PropertyDescriptor.Builder#allowableValues(Class)}
* <p>
* The {@link Class#getEnumConstants()} of the provided enum are searched for an entry matching the value of <code>this</code>.
* In case an enum value is a {@link DescribedValue}, uses the defined {@link DescribedValue#getValue()} for comparison.
* Otherwise, the {@link Enum#name()} is used.
*
* @param <E> the generic type of the enum used as allowableValues
* @param enumType the class of the enum used as allowableValues
* @return the matching enum entry, or <code>null</code> if the value is not set.
* @throws IllegalArgumentException if no enum entry matching the value of <code>this</code> is found.
*/
<E extends Enum<E>> E asAllowableValue(Class<E> enumType) throws IllegalArgumentException;
/**
* @return <code>true</code> if the user has configured a value, or if the
* {@link PropertyDescriptor} for the associated property has a default
* value, <code>false</code> otherwise
*/
boolean isSet();
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language;
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @return a PropertyValue with the new value is returned, supporting call
* chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions() throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language;
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param attributes a Map of attributes that the Expression can reference.
* These will take precedence over any underlying env/syst properties values.
*
* @return a PropertyValue with the new value
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(Map<String, String> attributes) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language.
* The supplied decorator is then given a chance to decorate the value, and
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param attributes a Map of attributes that the Expression can reference.
* These will take precedence over any variables in any underlying variable
* registry.
* @param decorator the decorator to use in order to update the values
* returned after variable substitution and expression language evaluation.
*
* @return a PropertyValue with the new value
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(Map<String, String> attributes, AttributeValueDecorator decorator) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language;
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param flowFile to evaluate attributes of. It's flow file properties and
* then flow file attributes will take precedence over any underlying
* env/syst properties.
* @return a PropertyValue with the new value is returned, supporting call
* chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(FlowFile flowFile) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language;
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param flowFile to evaluate attributes of. It's flow file properties and
* then flow file attributes will take precedence over any underlying
* env/syst properties.
* @param additionalAttributes a Map of additional attributes that the
* Expression can reference. These attributes will take precedence over any
* conflicting attributes in the provided flowfile or any underlying
* env/syst properties.
*
* @return a PropertyValue with the new value is returned, supporting call
* chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(FlowFile flowFile, Map<String, String> additionalAttributes) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language;
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param flowFile to evaluate attributes of. It's flow file properties and
* then flow file attributes will take precedence over any underlying
* env/syst properties.
* @param additionalAttributes a Map of additional attributes that the
* Expression can reference. These attributes will take precedence over any
* conflicting attributes in the provided flowfile or any underlying
* env/syst properties.
* @param decorator the decorator to use in order to update the values
* returned after variable substitution and expression language evaluation.
*
* @return a PropertyValue with the new value is returned, supporting call
* chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression
* Language; a PropertyValue with the new value is then returned, supporting
* call chaining.
* </p>
*
* @param flowFile to evaluate attributes of
* @param additionalAttributes a Map of additional attributes that the Expression can reference. If entries in
* this Map conflict with entries in the FlowFile's attributes, the entries in this Map are given a higher priority.
* @param decorator the decorator to use in order to update the values returned by the Expression Language
* @param stateValues a Map of the state values to be referenced explicitly by specific state accessing functions
*
* @return a PropertyValue with the new value is returned, supporting call
* chaining
*
* @throws ProcessException if the Expression cannot be compiled or evaluating
* the Expression against the given attributes causes an Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(FlowFile flowFile, Map<String, String> additionalAttributes, AttributeValueDecorator decorator, Map<String, String> stateValues)
throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language.
* The supplied decorator is then given a chance to decorate the value, and
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param decorator the decorator to use in order to update the values
* returned after variable substitution and expression language evaluation.
* @return a PropertyValue with the new value is then returned, supporting
* call chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(AttributeValueDecorator decorator) throws ProcessException;
/**
* <p>
* Replaces values in the Property Value using the NiFi Expression Language.
* The supplied decorator is then given a chance to decorate the value, and
* a PropertyValue with the new value is then returned, supporting call
* chaining. Before executing the expression language statement any
* variables names found within any underlying {@link EnvironmentVariables} will
* be substituted with their values.
* </p>
*
* @param flowFile to evaluate expressions against
* @param decorator the decorator to use in order to update the values
* returned after variable substitution and expression language evaluation.
*
*
* @return a PropertyValue with the new value is then returned, supporting
* call chaining
*
* @throws ProcessException if the Expression cannot be compiled or
* evaluating the Expression against the given attributes causes an
* Exception to be thrown
*/
PropertyValue evaluateAttributeExpressions(FlowFile flowFile, AttributeValueDecorator decorator) throws ProcessException;
/**
* <p>
* Indicates whether the value of the property uses Expression Language.
* </p>
*
* @return <code>true</code> if the property value makes use of the Expression Language, <code>false</code> otherwise.
*/
boolean isExpressionLanguagePresent();
}

View File

@ -1,57 +0,0 @@
/*
* 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.components;
import java.util.Arrays;
/**
*
*/
public enum RequiredPermission {
READ_FILESYSTEM("read-filesystem", "read filesystem"),
WRITE_FILESYSTEM("write-filesystem", "write filesystem"),
READ_DISTRIBUTED_FILESYSTEM("read-distributed-filesystem", "read distributed filesystem"),
WRITE_DISTRIBUTED_FILESYSTEM("write-distributed-filesystem", "write distributed filesystem"),
EXECUTE_CODE("execute-code", "execute code"),
ACCESS_KEYTAB("access-keytab", "access keytab"),
ACCESS_TICKET_CACHE("access-ticket-cache", "access ticket cache"),
ACCESS_ENVIRONMENT_CREDENTIALS("access-environment-credentials", "access environment credentials"),
EXPORT_NIFI_DETAILS("export-nifi-details", "export nifi details"),
REFERENCE_REMOTE_RESOURCES("reference-remote-resources", "reference remote resources");
private String permissionIdentifier;
private String permissionLabel;
RequiredPermission(String permissionIdentifier, String permissionLabel) {
this.permissionIdentifier = permissionIdentifier;
this.permissionLabel = permissionLabel;
}
public String getPermissionIdentifier() {
return permissionIdentifier;
}
public String getPermissionLabel() {
return permissionLabel;
}
public static RequiredPermission valueOfPermissionIdentifier(final String permissionIdentifier) {
return Arrays.stream(RequiredPermission.values())
.filter(candidate -> candidate.getPermissionIdentifier().equals(permissionIdentifier))
.findFirst().orElse(null);
}
}

View File

@ -1,201 +0,0 @@
/*
* 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.components;
import org.apache.nifi.annotation.behavior.InputRequirement;
import org.apache.nifi.context.PropertyContext;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.controller.ControllerServiceLookup;
import org.apache.nifi.expression.ExpressionLanguageCompiler;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
public interface ValidationContext extends PropertyContext {
/**
* @return the {@link ControllerServiceLookup} which can be used to obtain
* Controller Services
*/
ControllerServiceLookup getControllerServiceLookup();
/**
* @param controllerService to lookup the validation context of
* @return a ValidationContext that is appropriate for validating the given
* {@link ControllerService}
*/
ValidationContext getControllerServiceValidationContext(ControllerService controllerService);
/**
* @return a new {@link ExpressionLanguageCompiler} that can be used to
* compile & evaluate Attribute Expressions
*/
ExpressionLanguageCompiler newExpressionLanguageCompiler();
/**
* @param value to make a PropertyValue object for
* @return a PropertyValue that represents the given value
*/
PropertyValue newPropertyValue(String value);
/**
* @return a Map of all configured Properties
*/
Map<PropertyDescriptor, String> getProperties();
/**
* @return the currently configured Annotation Data
*/
String getAnnotationData();
/**
* There are times when the framework needs to consider a component valid,
* even if it references an invalid ControllerService. This method will
* return <code>false</code> if the component is to be considered valid even
* if the given Controller Service is referenced and is invalid.
*
* @param service to check if validation is required
* @return <code>false</code> if the component is to be considered valid
* even if the given Controller Service is referenced and is invalid
*/
boolean isValidationRequired(ControllerService service);
/**
* @param value to test whether expression language is present
* @return <code>true</code> if the given value contains a NiFi Expression
* Language expression, <code>false</code> if it does not
*/
boolean isExpressionLanguagePresent(String value);
/**
* @param propertyName to test whether expression language is supported
* @return <code>true</code> if the property with the given name supports
* the NiFi Expression Language, <code>false</code> if the property does not
* support the Expression Language or is not a valid property name
*/
boolean isExpressionLanguageSupported(String propertyName);
/**
* Returns the identifier of the ProcessGroup that the component being validated lives in
*
* @return the identifier of the ProcessGroup that the component being validated lives in
*/
String getProcessGroupIdentifier();
/**
* Returns a Collection containing the names of all Parameters that are referenced by the property with the given name
* @return a Collection containing the names of all Parameters that are referenced by the property with the given name
*/
Collection<String> getReferencedParameters(String propertyName);
/**
* @param parameterName the name of the Parameter
* @return <code>true</code> if a Parameter with the given name is defined in the currently selected Parameter Context
*/
boolean isParameterDefined(String parameterName);
/**
* Returns <code>true</code> if a Parameter with the given name is defined and has a non-null value, <code>false</code> if either the Parameter
* is not defined or the Parameter is defined but has a value of <code>null</code>.
* @param parameterName the name of the parameter
* @return <code>true</code> if the Parameter is defined and has a non-null value, false otherwise
*/
boolean isParameterSet(String parameterName);
/**
* Determines whether or not the dependencies of the given Property Descriptor are satisfied.
* If the given Property Descriptor has no dependency on another property, then the dependency is satisfied.
* If there is at least one dependency, then all dependencies must be satisfied.
* In order for a dependency to be considered satisfied, all of the following must be true:
* <ul>
* <li>The property that is depended upon has all of its dependencies satisfied.</li>
* <li>If the given Property Descriptor depends on a given AllowableValue, then the property that is depended upon has a value that falls within the given range of Allowable Values for
* the dependency.</li>
* </ul>
*
* @param propertyDescriptor the property descriptor
* @param propertyDescriptorLookup a lookup for converting from a property name to the property descriptor with that name
* @return <code>true</code> if all dependencies of the given property descriptor are satisfied, <code>false</code> otherwise
*/
default boolean isDependencySatisfied(PropertyDescriptor propertyDescriptor, Function<String, PropertyDescriptor> propertyDescriptorLookup) {
return isDependencySatisfied(propertyDescriptor, propertyDescriptorLookup, new HashSet<>());
}
private boolean isDependencySatisfied(final PropertyDescriptor propertyDescriptor, final Function<String, PropertyDescriptor> propertyDescriptorLookup, final Set<String> propertiesSeen) {
final Set<PropertyDependency> dependencies = propertyDescriptor.getDependencies();
if (dependencies.isEmpty()) {
return true;
}
final boolean added = propertiesSeen.add(propertyDescriptor.getName());
if (!added) {
return false;
}
try {
for (final PropertyDependency dependency : dependencies) {
final String dependencyName = dependency.getPropertyName();
// Check if the property being depended upon has its dependencies satisfied.
final PropertyDescriptor dependencyDescriptor = propertyDescriptorLookup.apply(dependencyName);
if (dependencyDescriptor == null) {
return false;
}
final PropertyValue propertyValue = getProperty(dependencyDescriptor);
final String dependencyValue = propertyValue == null ? dependencyDescriptor.getDefaultValue() : propertyValue.getValue();
if (dependencyValue == null) {
return false;
}
final boolean transitiveDependencySatisfied = isDependencySatisfied(dependencyDescriptor, propertyDescriptorLookup, propertiesSeen);
if (!transitiveDependencySatisfied) {
return false;
}
// Check if the property being depended upon is set to one of the values that satisfies this dependency.
// If the dependency has no dependent values, then any non-null value satisfies the dependency.
// The value is already known to be non-null due to the check above.
final Set<String> dependentValues = dependency.getDependentValues();
if (dependentValues != null && !dependentValues.contains(dependencyValue)) {
return false;
}
}
return true;
} finally {
propertiesSeen.remove(propertyDescriptor.getName());
}
}
/**
* Determines whether or not incoming and outgoing connections should be validated.
* If <code>true</code>, then the validation should verify that all Relationships either have one or more connections that include the Relationship,
* or that the Relationship is auto-terminated.
* Additionally, if <code>true</code>, then any Processor with an {@link InputRequirement} of {@link InputRequirement.Requirement#INPUT_REQUIRED}
* should be invalid unless it has an incoming (non-looping) connection, and any Processor with an {@link InputRequirement} of {@link InputRequirement.Requirement#INPUT_FORBIDDEN}
* should be invalid if it does have any incoming connection.
*
* @return <code>true</code> if Connections should be validated, <code>false</code> if Connections should be ignored
*/
default boolean isValidateConnections() {
return true;
}
}

View File

@ -1,172 +0,0 @@
/*
* 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.components;
import java.util.Objects;
/**
*
* Immutable - thread safe
*
*/
public class ValidationResult {
private final String subject;
private final String input;
private final String explanation;
private final boolean valid;
protected ValidationResult(final Builder builder) {
this.subject = builder.subject;
this.input = builder.input;
this.explanation = builder.explanation;
this.valid = builder.valid;
}
/**
* @return true if current result is valid; false otherwise
*/
public boolean isValid() {
return this.valid;
}
/**
* @return this input value that was tested for validity
*/
public String getInput() {
return this.input;
}
/**
* @return an explanation of the validation result
*/
public String getExplanation() {
return this.explanation;
}
/**
* @return the item being validated
*/
public String getSubject() {
return this.subject;
}
@Override
public int hashCode() {
int hash = 3;
hash = 79 * hash + Objects.hashCode(this.subject);
hash = 79 * hash + Objects.hashCode(this.input);
hash = 79 * hash + Objects.hashCode(this.explanation);
hash = 79 * hash + (this.valid ? 1 : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ValidationResult other = (ValidationResult) obj;
if (!Objects.equals(this.subject, other.subject)) {
return false;
}
if (!Objects.equals(this.input, other.input)) {
return false;
}
if (!Objects.equals(this.explanation, other.explanation)) {
return false;
}
if (this.valid != other.valid) {
return false;
}
return true;
}
@Override
public String toString() {
if (input == null) {
return String.format("'%s' is %s because %s", subject, (valid ? "valid" : "invalid"), explanation);
} else {
return String.format("'%s' validated against '%s' is %s because %s", subject, input, (valid ? "valid" : "invalid"), explanation);
}
}
public static final class Builder {
private boolean valid = false;
private String input = null;
private String explanation = "";
private String subject = "";
/**
* Defaults to false
*
* @param valid true if is valid; false otherwise
* @return the builder
*/
public Builder valid(final boolean valid) {
this.valid = valid;
return this;
}
/**
* Defaults to empty string
*
* @param input what was validated
* @return the builder
*/
public Builder input(final String input) {
if (null != input) {
this.input = input;
}
return this;
}
/**
* Defaults to empty string
*
* @param explanation of validation result
* @return the builder
*/
public Builder explanation(final String explanation) {
if (null != explanation) {
this.explanation = explanation;
}
return this;
}
/**
* Defaults to empty string
*
* @param subject the thing that was validated
* @return the builder
*/
public Builder subject(final String subject) {
if (null != subject) {
this.subject = subject;
}
return this;
}
public ValidationResult build() {
return new ValidationResult(this);
}
}
}

View File

@ -1,54 +0,0 @@
/*
* 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.components;
/**
*
*/
public interface Validator {
/**
* Validator object providing validation behavior in which validation always
* fails
*/
Validator INVALID = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
return new ValidationResult.Builder().subject(subject).explanation(String.format("'%s' is not a supported property or has no Validator associated with it", subject)).input(input).build();
}
};
/**
* Validator object providing validation behavior in which validation always
* passes
*/
Validator VALID = new Validator() {
@Override
public ValidationResult validate(final String subject, final String input, final ValidationContext context) {
return new ValidationResult.Builder().subject(subject).input(input).valid(true).build();
}
};
/**
* @param subject what is being validated
* @param input the string to be validated
* @param context the ValidationContext to use when validating properties
* @return ValidationResult
* @throws NullPointerException of given input is null
*/
ValidationResult validate(String subject, String input, ValidationContext context);
}

View File

@ -1,40 +0,0 @@
/*
* 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.components;
import java.util.Optional;
public interface VersionedComponent {
/**
* @return the unique identifier that maps this component to a component that is versioned
* in a Flow Registry or has been imported, or <code>Optional.empty</code> if this component has not
* been saved to a Flow Registry or imported.
*/
Optional<String> getVersionedComponentId();
/**
* Updates the versioned component identifier
*
* @param versionedComponentId the identifier of the versioned component
*
* @throws IllegalStateException if this component is already under version control with a different ID and
* the given ID is not null
*/
void setVersionedComponentId(String versionedComponentId);
}

View File

@ -1,100 +0,0 @@
/*
* 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.components.resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Objects;
public class FileResourceReference implements ResourceReference {
private final File file;
private final ResourceType resourceType;
public FileResourceReference(final File file) {
this.file = Objects.requireNonNull(file);
this.resourceType = file.isDirectory() ? ResourceType.DIRECTORY : ResourceType.FILE;
}
@Override
public File asFile() {
return file;
}
@Override
public URL asURL() {
try {
return file.toURI().toURL();
} catch (final MalformedURLException e) {
throw new AssertionError("File " + file.getAbsolutePath() + " cannot be represented as a URL"); // we won't encounter this.
}
}
@Override
public InputStream read() throws IOException {
if (resourceType != ResourceType.FILE) {
throw new FileNotFoundException("Could not read from file with name " + file.getAbsolutePath() + " because that references a directory");
}
return new FileInputStream(file);
}
@Override
public boolean isAccessible() {
return file.exists() && file.canRead();
}
@Override
public String getLocation() {
return file.getAbsolutePath();
}
@Override
public ResourceType getResourceType() {
return resourceType;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final FileResourceReference that = (FileResourceReference) o;
return Objects.equals(file, that.file)
&& resourceType == that.resourceType;
}
@Override
public int hashCode() {
return Objects.hash(file, resourceType);
}
@Override
public String toString() {
return "FileResourceReference[file=" + file + ", resourceType=" + resourceType + "]";
}
}

View File

@ -1,34 +0,0 @@
/*
* 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.components.resource;
/**
* Indicates the cardinality of how many resources can be referenced by a given property.
*/
public enum ResourceCardinality {
/**
* Exactly one resource must be specified
*/
SINGLE,
/**
* One or more resources may be supplied, as a comma-separated list
*/
MULTIPLE;
}

View File

@ -1,35 +0,0 @@
/*
* 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.components.resource;
import org.apache.nifi.components.PropertyDescriptor;
/**
* Provides the context in which a Reference Reference is to be evaluated
*/
public interface ResourceContext {
/**
* @return a ResourceReferenceFactory that can be used to parse a property value into a {@link ResourceReference} or {@link ResourceReferences}
*/
ResourceReferenceFactory getResourceReferenceFactory();
/**
* @return the PropertyDescriptor that describes the property whose value may be a resource
*/
PropertyDescriptor getPropertyDescriptor();
}

View File

@ -1,37 +0,0 @@
/*
* 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.components.resource;
import java.util.Set;
/**
* Defines the number and types of resources that allowed to be referenced by a component property
*/
public interface ResourceDefinition {
/**
* Specifies the number of resources that should be reference-able by a component property
* @return the cardinality for the number of resources that should be referenced
*/
ResourceCardinality getCardinality();
/**
* @return the types of resources that are allowed to be referenced
*/
Set<ResourceType> getResourceTypes();
}

View File

@ -1,66 +0,0 @@
/*
* 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.components.resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
/**
* A reference to a Resource that is identified by a property value
*/
public interface ResourceReference {
/**
* @return a file representation of the resource, or <code>null</code> if the Resource cannot be represented as a File
*/
File asFile();
/**
* @return a URL representation of the resource, or <code>null</code> if the Resource cannot be represented as a URL
*/
URL asURL();
/**
* @return an InputStream to read the contents of the resource
*
* @throws IOException if unable to obtain an InputStream from the resource
*/
InputStream read() throws IOException;
/**
* Indicates whether or not the resource is accessible. What it means for the resource to be accessible depends on the type of
* resource. A File resource, for example, might be accessible only if the file exists and is readable, while a URL resource might
* always be considered accessible, or might be accesssible only if the existence of the resource can be confirmed.
*
* @return <code>true</code> if the file can be accessed, <code>false</code> otherwise
*/
boolean isAccessible();
/**
* @return a String representation of the location, or <code>null</code> for a Resource that does not have an external location.
* For a File or a Directory, this will be the full path name; for a URL it will be the String form of the URL
*/
String getLocation();
/**
* @return the type of resource that is being referenced
*/
ResourceType getResourceType();
}

View File

@ -1,24 +0,0 @@
/*
* 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.components.resource;
public interface ResourceReferenceFactory {
ResourceReference createResourceReference(String value, ResourceDefinition resourceDefinition);
ResourceReferences createResourceReferences(String value, ResourceDefinition resourceDefinition);
}

View File

@ -1,73 +0,0 @@
/*
* 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.components.resource;
import java.net.URL;
import java.util.List;
/**
* A representation of zero or more {@link ResourceReference}s
*/
public interface ResourceReferences {
/**
* @return a List representation of all Resource References
*/
List<ResourceReference> asList();
/**
* @return a list of all Resource References' locations
*/
List<String> asLocations();
/**
* @return a list of all Resource References' URLs
*/
List<URL> asURLs();
/**
* @return the number of Resource References held
*/
int getCount();
/**
* Iterates through the Resource References and for any reference that may represent more than one
* resource, flattens the resource into a List of single-entity references. For example, consider that this ResourceReferences
* holds a single ResourceReference, of type DIRECTORY and the referenced directory contains 10 files. Calling {@link #asList()} would
* return a single ResourceReference. But calling <code>flatten()</code> would return a new ResourceReferences type whose {@link #asList()}
* method would return 10 ResourceReference objects, each with a ResourceType of FILE. The flatten operation is not recursive, meaning that if
* a DIRECTORY is flattened, any sub-directories will be dropped. If the contents of the subdirectories are to be retained, use {@link #flattenRecursively()}
* instead.
*
* @return a flattened ResourceReferences
*/
ResourceReferences flatten();
/**
* Recursively iterates through the Resource References and for any reference that may represent more than one
* resource, flattens the resource into a List of single-entity references. For example, consider that this ResourceReferences
* holds a single ResourceReference, of type DIRECTORY and the referenced directory contains 10 files. Calling {@link #asList()} would
* return a single ResourceReference. But calling <code>flatten()</code> would return a new ResourceReferences type whose {@link #asList()}
* method would return 10 ResourceReference objects, each with a ResourceType of FILE. The flatten operation is recursive, meaning that if
* a DIRECTORY is encountered, its reference will be replaced with a new reference for each file, even if that file exists 100 levels deep
* in the directory structure.
*
* @return a flattened ResourceReferences
*/
ResourceReferences flattenRecursively();
}

View File

@ -1,51 +0,0 @@
/*
* 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.components.resource;
public enum ResourceType {
/**
* Referenced Resource is a File on a local (or mounted) file system
*/
FILE("file"),
/**
* Referenced Resource is a directory on a local (or mounted) file system
*/
DIRECTORY("directory"),
/**
* Referenced Resource is UTF-8 text, rather than an external entity
*/
TEXT("text"),
/**
* Referenced Resource is a URL that uses the HTTP, HTTPS, or file protocol
* (i.e., <code>http://...</code>, <code>https://...</code>, or <code>file:...</code>)
*/
URL("URL");
private final String prettyPrintName;
ResourceType(final String prettyPrintName) {
this.prettyPrintName = prettyPrintName;
}
@Override
public String toString() {
return prettyPrintName;
}
}

View File

@ -1,40 +0,0 @@
/*
* 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.components.resource;
import org.apache.nifi.components.PropertyDescriptor;
public class StandardResourceContext implements ResourceContext {
private final ResourceReferenceFactory resourceReferenceFactory;
private final PropertyDescriptor propertyDescriptor;
public StandardResourceContext(final ResourceReferenceFactory resourceReferenceFactory, final PropertyDescriptor propertyDescriptor) {
this.resourceReferenceFactory = resourceReferenceFactory;
this.propertyDescriptor = propertyDescriptor;
}
@Override
public ResourceReferenceFactory getResourceReferenceFactory() {
return resourceReferenceFactory;
}
@Override
public PropertyDescriptor getPropertyDescriptor() {
return propertyDescriptor;
}
}

View File

@ -1,40 +0,0 @@
/*
* 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.components.resource;
import java.util.Set;
public class StandardResourceDefinition implements ResourceDefinition {
private final ResourceCardinality cardinality;
private final Set<ResourceType> resourceTypes;
public StandardResourceDefinition(final ResourceCardinality cardinality, final Set<ResourceType> resourceTypes) {
this.cardinality = cardinality;
this.resourceTypes = resourceTypes;
}
@Override
public ResourceCardinality getCardinality() {
return cardinality;
}
@Override
public Set<ResourceType> getResourceTypes() {
return resourceTypes;
}
}

View File

@ -1,131 +0,0 @@
/*
* 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.components.resource;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
public class StandardResourceReferenceFactory implements ResourceReferenceFactory {
private static final ResourceReferences EMPTY_RESOURCE_REFERENCES = new StandardResourceReferences(Collections.emptyList());
public ResourceReferences createResourceReferences(final String value, final ResourceDefinition resourceDefinition) {
if (value == null) {
return EMPTY_RESOURCE_REFERENCES;
}
final String trimmed = value.trim();
if (trimmed.isEmpty()) {
return EMPTY_RESOURCE_REFERENCES;
}
if (resourceDefinition == null) {
return EMPTY_RESOURCE_REFERENCES;
}
final List<ResourceReference> references;
final List<String> locations = parseResourceLocations(value);
references = new ArrayList<>(locations.size());
locations.forEach(location -> references.add(createResourceReference(location, resourceDefinition)));
return new StandardResourceReferences(references);
}
public ResourceReference createResourceReference(final String value, final ResourceDefinition resourceDefinition) {
if (value == null) {
return null;
}
final String trimmed = value.trim();
if (trimmed.isEmpty()) {
return null;
}
if (resourceDefinition == null) {
return null;
}
final Set<ResourceType> allowedResourceTypes = resourceDefinition.getResourceTypes();
if (allowedResourceTypes.contains(ResourceType.URL)) {
try {
if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
return new URLResourceReference(URI.create(trimmed).toURL());
}
if (trimmed.startsWith("file:")) {
final URL url = URI.create(trimmed).toURL();
final String filename = url.getFile();
final File file = new File(filename);
return new FileResourceReference(file);
}
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Invalid URL: " + trimmed);
}
}
final boolean fileAllowed = allowedResourceTypes.contains(ResourceType.FILE) || allowedResourceTypes.contains(ResourceType.DIRECTORY);
final boolean textAllowed = allowedResourceTypes.contains(ResourceType.TEXT);
if (fileAllowed && textAllowed) {
// We have to make a determination whether this is a file or text. Eventually, it will be best if the user tells us explicitly.
// For now, we will make a determination based on a couple of simple rules.
final File file = new File(trimmed);
if (file.isAbsolute() || file.exists()) {
return new FileResourceReference(file);
}
if (trimmed.startsWith("./") || trimmed.startsWith(".\\")) {
return new FileResourceReference(file);
}
return new Utf8TextResource(value); // Use explicit value, not trimmed value, as the white space may be important for textual content.
}
if (fileAllowed) {
final File file = new File(trimmed);
return new FileResourceReference(file);
}
if (textAllowed) {
return new Utf8TextResource(value);
}
return null;
}
private List<String> parseResourceLocations(final String rawValue) {
final List<String> resourceLocations = new ArrayList<>();
final String[] splits = rawValue.split(",");
for (final String split : splits) {
final String trimmed = split.trim();
if (trimmed.isEmpty()) {
continue;
}
resourceLocations.add(trimmed);
}
return resourceLocations;
}
}

View File

@ -1,154 +0,0 @@
/*
* 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.components.resource;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class StandardResourceReferences implements ResourceReferences {
public final List<ResourceReference> resourceReferences;
public StandardResourceReferences(final List<ResourceReference> resourceReferences) {
this.resourceReferences = new ArrayList<>(Objects.requireNonNull(resourceReferences));
}
@Override
public List<ResourceReference> asList() {
return Collections.unmodifiableList(resourceReferences);
}
@Override
public List<String> asLocations() {
final List<String> locations = new ArrayList<>(resourceReferences.size());
resourceReferences.forEach(ref -> locations.add(ref.getLocation()));
return locations;
}
@Override
public List<URL> asURLs() {
final List<URL> locations = new ArrayList<>(resourceReferences.size());
resourceReferences.forEach(ref -> locations.add(ref.asURL()));
return locations;
}
@Override
public int getCount() {
return resourceReferences.size();
}
@Override
public ResourceReferences flatten() {
if (resourceReferences.isEmpty()) {
return this;
}
final List<ResourceReference> flattened = new ArrayList<>();
resourceReferences.forEach(reference -> {
if (reference.getResourceType() == ResourceType.DIRECTORY) {
addChildren(reference.asFile(), flattened);
} else {
flattened.add(reference);
}
});
return new StandardResourceReferences(flattened);
}
private void addChildren(final File file, final List<ResourceReference> flattened) {
if (file == null) {
return;
}
if (file.isDirectory()) {
final File[] children = file.listFiles();
if (children != null) {
for (final File child : children) {
if (child.isFile()) {
flattened.add(new FileResourceReference(child));
}
}
}
} else {
flattened.add(new FileResourceReference(file));
}
}
@Override
public ResourceReferences flattenRecursively() {
if (resourceReferences.isEmpty()) {
return this;
}
final List<ResourceReference> flattened = new ArrayList<>();
resourceReferences.forEach(reference -> {
if (reference.getResourceType() == ResourceType.DIRECTORY) {
recurse(reference.asFile(), flattened);
} else {
flattened.add(reference);
}
});
return new StandardResourceReferences(flattened);
}
private void recurse(final File file, final List<ResourceReference> flattened) {
if (file == null) {
return;
}
if (file.isDirectory()) {
final File[] children = file.listFiles();
if (children != null) {
for (final File child : children) {
recurse(child, flattened);
}
}
} else {
flattened.add(new FileResourceReference(file));
}
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final StandardResourceReferences that = (StandardResourceReferences) o;
return Objects.equals(resourceReferences, that.resourceReferences);
}
@Override
public int hashCode() {
return Objects.hash(resourceReferences);
}
@Override
public String toString() {
return "StandardResourceReferences[resources=" + resourceReferences + "]";
}
}

View File

@ -1,67 +0,0 @@
/*
* 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.components.resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class URLResourceReference implements ResourceReference {
private final URL url;
public URLResourceReference(final URL url) {
this.url = url;
}
@Override
public File asFile() {
return null;
}
@Override
public URL asURL() {
return url;
}
@Override
public InputStream read() throws IOException {
return url.openStream();
}
@Override
public boolean isAccessible() {
return true;
}
@Override
public String getLocation() {
return url.toExternalForm();
}
@Override
public ResourceType getResourceType() {
return ResourceType.URL;
}
@Override
public String toString() {
return "URLResourceReference[url=" + url + "]";
}
}

View File

@ -1,68 +0,0 @@
/*
* 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.components.resource;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
public class Utf8TextResource implements ResourceReference {
private final String text;
public Utf8TextResource(final String text) {
this.text = text;
}
@Override
public File asFile() {
return null;
}
@Override
public URL asURL() {
return null;
}
@Override
public InputStream read() throws IOException {
return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
}
@Override
public boolean isAccessible() {
return true;
}
@Override
public String getLocation() {
return null;
}
@Override
public ResourceType getResourceType() {
return ResourceType.TEXT;
}
@Override
public String toString() {
return "Utf8TextResource[text=" + text.length() + " characters]";
}
}

View File

@ -1,41 +0,0 @@
/*
* 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.components.state;
/**
* A Scope represents how a NiFi component's state is to be stored and retrieved when running in a cluster.
*/
public enum Scope {
/**
* State is to be treated as "global" across the cluster. I.e., the same component on all nodes will
* have access to the same state.
*/
CLUSTER,
/**
* State is to be treated local to the node. I.e., the same component will have different state on each
* node in the cluster.
*/
LOCAL;
@Override
public String toString() {
return name();
}
}

View File

@ -1,101 +0,0 @@
/*
* 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.components.state;
import java.io.IOException;
import java.util.Map;
import org.apache.nifi.annotation.behavior.Stateful;
import org.apache.nifi.components.state.exception.StateTooLargeException;
/**
* <p>
* The StateManager is responsible for providing NiFi components a mechanism for storing
* and retrieving state.
* </p>
*
* <p>
* When calling methods in this class, the {@link Scope} is used in order to specify whether
* state should be stored/retrieved from the local state or the clustered state. However, if
* any instance of NiFi is not clustered (or is disconnected from its cluster), the Scope is
* not really relevant and the local state will be used. This allows component
* developers to not concern themselves with whether or not a particular instance of NiFi is
* clustered. Instead, developers should assume that the instance is indeed clustered and write
* the component accordingly. If not clustered, the component will still behave in the same
* manner, as a standalone node could be thought of as a "cluster of 1."
* </p>
*
* <p>
* This mechanism is designed to allow developers to easily store and retrieve small amounts of state.
* The storage mechanism is implementation-specific, but is typically either stored on a remote system
* or on disk. For that reason, one should consider the cost of storing and retrieving this data, and the
* amount of data should be kept to the minimum required.
* </p>
*
* <p>
* Any component that wishes to use the StateManager should also use the {@link Stateful} annotation to provide
* a description of what state is being stored and what Scope is used. If this annotation is not present, the UI
* will not expose such information or allow DFMs to clear the state.
* </p>
*/
public interface StateManager {
/**
* Updates the value of the component's state, setting it to given value
*
* @param state the value to change the state to
* @param scope the scope to use when storing the state
*
* @throws StateTooLargeException if attempting to store more state than is allowed by the backing storage mechanism
* @throws IOException if unable to communicate with the underlying storage mechanism
*/
void setState(Map<String, String> state, Scope scope) throws IOException;
/**
* Returns the current state for the component. This return value will never be <code>null</code>.
* If the state has not yet been set, the StateMap's version will be -1, and the map of values will be empty.
*
* @param scope the scope to use when fetching the state
* @return the current state for the component
* @throws IOException if unable to communicate with the underlying storage mechanism
*/
StateMap getState(Scope scope) throws IOException;
/**
* Updates the value of the component's state to the new value if and only if the value currently
* is the same as the given oldValue.
*
* @param oldValue the old value to compare against
* @param newValue the new value to use if and only if the state's value is the same as the given oldValue
* @param scope the scope to use for storing the new state
* @return <code>true</code> if the state was updated to the new value, <code>false</code> if the state's value was not
* equal to oldValue
*
* @throws StateTooLargeException if attempting to store more state than is allowed by the backing storage mechanism
* @throws IOException if unable to communicate with the underlying storage mechanism
*/
boolean replace(StateMap oldValue, Map<String, String> newValue, Scope scope) throws IOException;
/**
* Clears all keys and values from the component's state
*
* @param scope the scope whose values should be cleared
*
* @throws IOException if unable to communicate with the underlying storage mechanism
*/
void clear(Scope scope) throws IOException;
}

View File

@ -1,51 +0,0 @@
/*
* 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.components.state;
import java.util.Map;
import java.util.Optional;
/**
* Provides a representation of a component's state at some point in time.
*/
public interface StateMap {
/**
* Get state version is not guaranteed to be numeric, but can be used to compare against an expected version.
* The default implementation uses the available version number and considers -1 as indicating an empty version
*
* @return State version or empty when not known
*/
Optional<String> getStateVersion();
/**
* Returns the value associated with the given key
*n
* @param key the key whose value should be retrieved
* @return the value associated with the given key, or <code>null</code> if no value is associated
* with this key.
*/
String get(String key);
/**
* Returns an immutable Map representation of all keys and values for the state of a component.
*
* @return an immutable Map representation of all keys and values for the state of a component.
*/
Map<String, String> toMap();
}

View File

@ -1,33 +0,0 @@
/*
* 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.components.state.exception;
import java.io.IOException;
import org.apache.nifi.components.state.StateManager;
/**
* Thrown when attempting to store state via the {@link StateManager} but the state being
* stored is larger than is allowed by the backing storage mechanism.
*/
public class StateTooLargeException extends IOException {
private static final long serialVersionUID = 1L;
public StateTooLargeException(final String message) {
super(message);
}
}

View File

@ -1,30 +0,0 @@
/*
* 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.context;
/**
* A context for retrieving information about the state of the cluster.
*/
public interface ClusterContext {
/**
* Retrieves the current state of the cluster connection of this node.
*
* @return True if this node is connected to the cluster. False otherwise.
*/
boolean isConnectedToCluster();
}

View File

@ -1,40 +0,0 @@
/*
* 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.context;
import java.util.Map;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
/**
* A context for retrieving a PropertyValue from a PropertyDescriptor.
*/
public interface PropertyContext {
/**
* Retrieves the current value set for the given descriptor, if a value is
* set - else uses the descriptor to determine the appropriate default value
*
* @param descriptor to lookup the value of
* @return the property value of the given descriptor
*/
PropertyValue getProperty(PropertyDescriptor descriptor);
Map<String, String> getAllProperties();
}

View File

@ -1,130 +0,0 @@
/*
* 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.controller;
import org.apache.nifi.annotation.lifecycle.OnDisabled;
import org.apache.nifi.annotation.lifecycle.OnEnabled;
import org.apache.nifi.components.AbstractConfigurableComponent;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.components.state.StateManager;
import org.apache.nifi.logging.ComponentLog;
import org.apache.nifi.reporting.InitializationException;
public abstract class AbstractControllerService extends AbstractConfigurableComponent implements ControllerService {
private String identifier;
private ControllerServiceLookup serviceLookup;
private ComponentLog logger;
private StateManager stateManager;
private volatile ConfigurationContext configurationContext;
private volatile boolean enabled = false;
private NodeTypeProvider nodeTypeProvider;
@Override
public final void initialize(final ControllerServiceInitializationContext context) throws InitializationException {
this.identifier = context.getIdentifier();
serviceLookup = context.getControllerServiceLookup();
logger = context.getLogger();
stateManager = context.getStateManager();
nodeTypeProvider = context.getNodeTypeProvider();
init(context);
}
@Override
public String getIdentifier() {
return identifier;
}
/**
* @return the {@link ControllerServiceLookup} that was passed to the
* {@link #init(ControllerServiceInitializationContext)} method
*/
protected final ControllerServiceLookup getControllerServiceLookup() {
return serviceLookup;
}
/**
* @return the {@link NodeTypeProvider} that was passed to the
* {@link #init(ControllerServiceInitializationContext)} method
*/
protected final NodeTypeProvider getNodeTypeProvider() {
return nodeTypeProvider;
}
/**
* Provides a mechanism by which subclasses can perform initialization of
* the Controller Service before it is scheduled to be run
*
* @param config of initialization context
* @throws InitializationException if unable to init
*/
protected void init(final ControllerServiceInitializationContext config) throws InitializationException {
}
@OnEnabled
public final void enabled() {
this.enabled = true;
}
@OnDisabled
public final void disabled() {
this.enabled = false;
}
public boolean isEnabled() {
return this.enabled;
}
/**
* @return the logger that has been provided to the component by the
* framework in its initialize method
*/
protected ComponentLog getLogger() {
return logger;
}
/**
* @return the StateManager that can be used to store and retrieve state for this Controller Service
*/
protected StateManager getStateManager() {
return stateManager;
}
@OnEnabled
public final void abstractStoreConfigContext(final ConfigurationContext configContext) {
this.configurationContext = configContext;
}
@OnDisabled
public final void abstractClearConfigContext() {
this.configurationContext = null;
}
protected ConfigurationContext getConfigurationContext() {
final ConfigurationContext context = this.configurationContext;
if (context == null) {
throw new IllegalStateException("No Configuration Context exists");
}
return configurationContext;
}
protected PropertyValue getProperty(final PropertyDescriptor descriptor) {
return getConfigurationContext().getProperty(descriptor);
}
}

View File

@ -1,66 +0,0 @@
/*
* 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.controller;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.context.PropertyContext;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
* This context is passed to ControllerServices and Reporting Tasks in order
* to expose their configuration to them.
*/
public interface ConfigurationContext extends PropertyContext {
/**
* @return an unmodifiable map of all configured properties for this
* {@link ControllerService}
*/
Map<PropertyDescriptor, String> getProperties();
/**
* @return the annotation data configured for the component
*/
String getAnnotationData();
/**
* @return a String representation of the scheduling period, or <code>null</code> if
* the component does not have a scheduling period (e.g., for ControllerServices)
*/
String getSchedulingPeriod();
/**
* Returns the amount of time, in the given {@link TimeUnit} that will
* elapsed between the return of one execution of the
* component's <code>onTrigger</code> method and
* the time at which the method is invoked again. This method will return
* null if the component does not have a scheduling period (e.g., for ControllerServices)
*
* @param timeUnit unit of time for scheduling
* @return period of time or <code>null</code> if component does not have a scheduling
* period
*/
Long getSchedulingPeriod(TimeUnit timeUnit);
/**
* Returns the component's (ControllerService, ReportingTask, ParameterProvider, e.g.) name
* @return the String name of this component
*/
String getName();
}

View File

@ -1,211 +0,0 @@
/*
* 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.controller;
import org.apache.nifi.annotation.behavior.Stateful;
import org.apache.nifi.components.ConfigurableComponent;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.flowanalysis.FlowAnalysisRule;
import org.apache.nifi.migration.PropertyConfiguration;
import org.apache.nifi.parameter.ParameterProvider;
import org.apache.nifi.processor.ProcessContext;
import org.apache.nifi.processor.ProcessSessionFactory;
import org.apache.nifi.processor.Processor;
import org.apache.nifi.reporting.InitializationException;
import org.apache.nifi.reporting.ReportingTask;
/**
* <p>
* This interface provides a mechanism for creating services that are shared
* among all {@link Processor}s, {@link ReportingTask}s, {@link FlowAnalysisRule}s, {@link ParameterProvider}s and other
* {@code ControllerService}s.
* </p>
*
* <p>
* <code>ControllerService</code>s are discovered using Java's
* <code>ServiceLoader</code> mechanism. As a result, all implementations must
* follow these rules:
*
* <ul>
* <li>The implementation must implement this interface.</li>
* <li>The implementation must have a file named
* org.apache.nifi.controller.ControllerService located within the jar's
* <code>META-INF/services</code> directory. This file contains a list of
* fully-qualified class names of all <code>ControllerService</code>s in the
* jar, one-per-line.
* <li>The implementation must support a default constructor.</li>
* </ul>
* </p>
*
* <p>
* <b>All implementations of this interface must be thread-safe.</b>
* </p>
*
* <h2>Accessing Controller Services</h2>
* <p>
* A ControllerService is accessible only through its interface. The framework
* provides access to a ControllerService through two different mechanisms:
* <ul>
* <li>
* A {@link PropertyDescriptor} can be created via the
* {@link PropertyDescriptor.Builder} after calling the
* {@link PropertyDescriptor.Builder#identifiesControllerService(Class) identifiesControllerService(Class)}
* method and then the ControllerService is accessed via
* {@link PropertyValue#asControllerService(Class)} method.
* <p>
* For example:
* </p>
* <p>
* <code><pre>
* public static final PropertyDescriptor MY_PROPERTY = new PropertyDescriptor.Builder()
* .name("My Property")
* .description("Example Property")
* .identifiesControllerService( MyControllerServiceInterface.class )
* .build();
*
* ...
* public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
* // Obtain the user-selected controller service
* final MyControllerServiceInterface service = context.getProperty(MY_PROPERTY).asControllerService( MyControllerServiceInterface.class );
* ...
* }
*
* </pre></code></p>
* </li>
* <li>A Controller Service can be obtained via a
* {@link ControllerServiceLookup}. This lookup may be obtained, for example,
* from the {@link ProcessContext} that is provided to a {@link Processor}'s
* {@link Processor#onTrigger(ProcessContext, ProcessSessionFactory) onTrigger}
* method.
* <p>
* For example:
* </p>
* <p>
* <code><pre>
* public void onTrigger(ProcessContext context, ProcessSessionFactory sessionFactory) throws ProcessException {
* final MyControllerServiceInterface service = (MyControllerServiceInterface) context.getControllerServiceLookup().getControllerService("service_identifier");
* }
* </pre></code></p>
* </li>
* </ul>
* </p>
*
* <h2>Defining a Controller Service</h2>
* <p>
* Note in both of the examples above, that the Controller Service was accessed
* only by its interface, and this interface extends ControllerService. If we
* have an implementation named MyServiceImpl, for example, that implements
* MyControllerServiceInterface, we cannot, in either case, attempt to cast the
* ControllerService to the desired implementation. Doing so will result in a
* {@link ClassCastException}. This is by design and is done for the following
* reasons:
*
* <ul>
* <li>
* It is a good coding practice to implement such a service as an interface in
* general.
* </li>
* <li>
* A Controller Service can be referenced from different NiFi Archives (NARs).
* This means that the Controller Service may be defined in one ClassLoader and
* referenced from another unrelated ClassLoader. In order to account for this,
* NiFi will change the current thread's ClassLoader as appropriate when
* entering the Controller Service's code and revert back to the previous
* ClassLoader after exiting the Controller Service's code.
* </li>
* </ul>
* </p>
*
* <h2>Controller Services and NARs</h2>
* <p>
* Due to the fact that a Controller Service may be referenced from a different
* NAR than the one in which the implementation lives, it is crucial that both
* the Controller Service's interface and the code referencing the interface
* inherit from the same ClassLoader. This is accomplished by ensuring that the
* NAR that contains the Controller Service interface is the parent (or
* ancestor) of the NAR that references the Controller Service interface.
* </p>
*
* <p>
* Typically, this is done by creating a NAR structure as follows:
* <pre>
* + my-services-api-nar
* +--- service-X-implementation-nar
* +--- service-Y-implementation-nar
* +--- service-Z-implementation-nar
* +--- processor-A-nar
* +--- processor-B-nar
* </pre>
* </p>
*
* <p>
* In this case, the {@code MyControllerServiceInterface} interface, and any
* other Controller Service interfaces, will be defined in the
* {@code my-services-api-nar} NAR. Implementations are then encapsulated within
* the {@code service-X-implementation-nar},
* {@code service-Y-implementation-nar}, and
* {@code service-Z-implementation-nar} NARs. All Controller Services and all
* Processors defined in these NARs are able to reference any other Controller
* Services whose interfaces are provided in the {@code my-services-api-nar}
* NAR.
* </p>
*
* <p>
* For more information on NARs, see the NiFi Developer Guide.
* </p>
*/
public interface ControllerService extends ConfigurableComponent {
/**
* Provides the Controller Service with access to objects that may be of use
* throughout the life of the service. This method will be called before any
* properties are set
*
* @param context of initialization
* @throws org.apache.nifi.reporting.InitializationException if unable to init
*/
void initialize(ControllerServiceInitializationContext context) throws InitializationException;
/**
* Indicates whether this controller service, configured with the given {@link ConfigurationContext}, stores state.
* @param context provides access to convenience methods for obtaining property values
* @return True if this controller service stores state
*/
default boolean isStateful(ConfigurationContext context) {
return this.getClass().isAnnotationPresent(Stateful.class);
}
/**
* <p>
* Allows for the migration of an old property configuration to a new configuration. This allows the Controller Service to evolve over time,
* as it allows properties to be renamed, removed, or reconfigured.
* </p>
*
* <p>
* This method is called only when a Controller Service is restored from a previous configuration. For example, when NiFi is restarted and the
* flow is restored from disk, when a previously configured flow is imported (e.g., from a JSON file that was exported or a NiFi Registry),
* or when a node joins a cluster and inherits a flow that has a new Controller Service. Once called, the method will not be invoked again for this
* Controller Service until NiFi is restarted.
* </p>
*
* @param config the current property configuration
*/
default void migrateProperties(PropertyConfiguration config) {
}
}

View File

@ -1,53 +0,0 @@
/*
* 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.controller;
import org.apache.nifi.components.state.StateManager;
import org.apache.nifi.kerberos.KerberosContext;
import org.apache.nifi.logging.ComponentLog;
public interface ControllerServiceInitializationContext extends KerberosContext {
/**
* @return the identifier associated with the {@link ControllerService} with
* which this context is associated
*/
String getIdentifier();
/**
* @return the {@link ControllerServiceLookup} which can be used to obtain
* Controller Services
*/
ControllerServiceLookup getControllerServiceLookup();
/**
* @return a logger that can be used to log important events in a standard
* way and generate bulletins when appropriate
*/
ComponentLog getLogger();
/**
* @return the StateManager that can be used to store and retrieve state for this component
*/
StateManager getStateManager();
/**
* @return the {@link NodeTypeProvider} which can be used to detect the node
* type of this NiFi instance.
*/
NodeTypeProvider getNodeTypeProvider();
}

View File

@ -1,72 +0,0 @@
/*
* 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.controller;
import java.util.Set;
public interface ControllerServiceLookup {
/**
* @param serviceIdentifier of controller service
* @return the ControllerService that is registered with the given
* identifier
*/
ControllerService getControllerService(String serviceIdentifier);
/**
* @param serviceIdentifier identifier of service to check
* @return <code>true</code> if the Controller Service with the given
* identifier is enabled, <code>false</code> otherwise. If the given
* identifier is not known by this ControllerServiceLookup, returns
* <code>false</code>
*/
boolean isControllerServiceEnabled(String serviceIdentifier);
/**
* @param serviceIdentifier identifier of service to check
* @return <code>true</code> if the Controller Service with the given
* identifier has been enabled but is still in the transitioning state,
* otherwise returns <code>false</code>. If the given identifier is not
* known by this ControllerServiceLookup, returns <code>false</code>
*/
boolean isControllerServiceEnabling(String serviceIdentifier);
/**
* @param service service to check
* @return <code>true</code> if the given Controller Service is enabled,
* <code>false</code> otherwise. If the given Controller Service is not
* known by this ControllerServiceLookup, returns <code>false</code>
*/
boolean isControllerServiceEnabled(ControllerService service);
/**
*
* @param serviceType type of service to get identifiers for
*
* @return the set of all Controller Service Identifiers whose Controller
* Service is of the given type.
* @throws IllegalArgumentException if the given class is not an interface
*/
Set<String> getControllerServiceIdentifiers(Class<? extends ControllerService> serviceType) throws IllegalArgumentException;
/**
* @param serviceIdentifier identifier to look up
* @return the name of the Controller service with the given identifier. If
* no service can be found with this identifier, returns {@code null}
*/
String getControllerServiceName(String serviceIdentifier);
}

View File

@ -1,80 +0,0 @@
/*
* 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.controller;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
/**
* <p>
* This interface provides a set of methods for checking NiFi node type.
* <p>
*/
public interface NodeTypeProvider {
/**
* @return true if this instance is clustered, false otherwise.MockProcessContext
* Clustered means that a node is either connected or trying to connect to the cluster.
*/
boolean isClustered();
/**
* @return true if the expected state of clustering is true, false otherwise. Contrary to {{@link #isClustered()}}
* this does not dynamically change with the state of this node.
*/
default boolean isConfiguredForClustering() {
return false;
}
/**
* @return true if this instances is clustered and connected to the cluster.
*/
default boolean isConnected() {
return false;
}
/**
* @return true if this instance is the primary node in the cluster; false otherwise
*/
boolean isPrimary();
/**
* @return Returns with the hostname of the current node, if clustered. For For a standalone
* NiFi this returns an empty instead.
*/
default Optional<String> getCurrentNode() {
if (isClustered()) {
throw new IllegalStateException("Clustered environment is not handled!");
} else {
return Optional.empty();
}
}
/**
* @return Names/IP addresses of all expected hosts in the cluster (including the current one). For a standalone
* NiFi this returns an empty set instead.
*/
default Set<String> getClusterMembers() {
if (isClustered()) {
throw new IllegalStateException("Clustered environment is not handled!");
} else {
return Collections.emptySet();
}
}
}

View File

@ -1,43 +0,0 @@
/*
* 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.controller;
/**
* Indicates the valid values for the state of a <code>Triggerable</code> entity
* with respect to scheduling the entity to run.
*/
public enum ScheduledState {
/**
* Entity cannot be scheduled to run
*/
DISABLED,
/**
* Entity can be scheduled to run but currently is not
*/
STOPPED,
/**
* Entity is currently scheduled to run
*/
RUNNING,
STARTING,
STOPPING,
RUN_ONCE;
}

Some files were not shown because too many files have changed in this diff Show More