mirror of https://github.com/apache/nifi.git
NIFI-3050:
- Introducing a Restricted annotation for components that require elevated privileges to use. - Updating the new Processor, Controller Service, and Reporting Task dialogs to include these details and prevent unauthorized selection. - Including the Restricted description in the generated component documentation. - Updating processor access control integration test to verify restricted component creation. - Updating the developer, user, and admin guide to include the restricted component policy.
This commit is contained in:
parent
1be0871473
commit
f487682419
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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 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
|
||||||
|
*/
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -478,6 +478,7 @@ Here is a summary of policies assigned to each legacy role if the NiFi instance
|
||||||
|view policies |* | | | | |
|
|view policies |* | | | | |
|
||||||
|modify policies |* | | | | |
|
|modify policies |* | | | | |
|
||||||
|query provenance | | | |* | |
|
|query provenance | | | |* | |
|
||||||
|
|access restricted components | |* | | | |
|
||||||
|view the data | |* | |* | |*
|
|view the data | |* | |* | |*
|
||||||
|modify the data | |* | | | |*
|
|modify the data | |* | | | |*
|
||||||
|retrieve site-to-site details | | | | |* |
|
|retrieve site-to-site details | | | | |* |
|
||||||
|
@ -581,6 +582,10 @@ Global access policies govern the following system level authorizations:
|
||||||
|Allows users to submit a Provenance Search and request Event Lineage
|
|Allows users to submit a Provenance Search and request Event Lineage
|
||||||
|Data Provenance
|
|Data Provenance
|
||||||
|
|
||||||
|
|access restricted components
|
||||||
|
|Allows users to create/modify restricted components assuming otherwise sufficient permissions
|
||||||
|
|N/A
|
||||||
|
|
||||||
|access all policies
|
|access all policies
|
||||||
|Allows users to view/modify the policies for all components
|
|Allows users to view/modify the policies for all components
|
||||||
|Policies
|
|Policies
|
||||||
|
|
|
@ -565,6 +565,23 @@ for instance, they should not be
|
||||||
relied upon for critical business logic.
|
relied upon for critical business logic.
|
||||||
|
|
||||||
|
|
||||||
|
[[restricted]]
|
||||||
|
=== Restricted
|
||||||
|
|
||||||
|
A 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.
|
||||||
|
|
||||||
|
A Processor, Controller Service, or Reporting Task can be marked with the @Restricted annotation. This
|
||||||
|
will result in the component being treated as restricted and will require a user to be explicitly added to the
|
||||||
|
list of users who can access restricted components. Once a user is permitted to access restricted components,
|
||||||
|
they will be allowed to create and modify those components assuming all other permissions are permitted.
|
||||||
|
Without access to restricted components, a user will be still be aware these types of components exist but will
|
||||||
|
be unable to create or modify them even with otherwise sufficient permissions.
|
||||||
|
|
||||||
[[state_manager]]
|
[[state_manager]]
|
||||||
=== State Manager
|
=== State Manager
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
|
@ -40,15 +40,13 @@ Browser Support
|
||||||
|Browser |Version
|
|Browser |Version
|
||||||
|Chrome |Current and Current - 1
|
|Chrome |Current and Current - 1
|
||||||
|FireFox |Current and Current - 1
|
|FireFox |Current and Current - 1
|
||||||
|Edge |Current
|
|Edge |Current and Current - 1
|
||||||
|Safari |Current and Current - 1
|
|Safari |Current and Current - 1
|
||||||
|======================
|
|======================
|
||||||
|
|
||||||
Current and Current - 1 indicates that the UI is supported in the current stable release of that browser and the preceding one. For instance, if
|
Current and Current - 1 indicates that the UI is supported in the current stable release of that browser and the preceding one. For instance, if
|
||||||
the current stable release is 45.X then the officially supported versions will be 45.X and 44.X.
|
the current stable release is 45.X then the officially supported versions will be 45.X and 44.X.
|
||||||
|
|
||||||
Current indicates that the UI is supported in the current stable release of that browser.
|
|
||||||
|
|
||||||
The supported browser versions are driven by the capabilities the UI employs and the dependencies it uses. UI features will be developed and tested
|
The supported browser versions are driven by the capabilities the UI employs and the dependencies it uses. UI features will be developed and tested
|
||||||
against the supported browsers. Any problem using a supported browser should be reported to Apache NiFi.
|
against the supported browsers. Any problem using a supported browser should be reported to Apache NiFi.
|
||||||
|
|
||||||
|
@ -195,6 +193,7 @@ The available global access policies are:
|
||||||
|view the UI |Allows users to view the UI
|
|view the UI |Allows users to view the UI
|
||||||
|access the controller |Allows users to view and modify the controller including reporting tasks, Controller Services, and nodes in the cluster
|
|access the controller |Allows users to view and modify the controller including reporting tasks, Controller Services, and nodes in the cluster
|
||||||
|query provenance |Allows users to submit a provenance search and request even lineage
|
|query provenance |Allows users to submit a provenance search and request even lineage
|
||||||
|
|access restricted components |Allows users to create/modify restricted components assuming otherwise sufficient permissions
|
||||||
|access all policies |Allows users to view and modify the policies for all components
|
|access all policies |Allows users to view and modify the policies for all components
|
||||||
|access users/groups |Allows users view and modify the users and user groups
|
|access users/groups |Allows users view and modify the users and user groups
|
||||||
|retrieve site-to-site details | Allows other NiFi instances to retrieve Site-To-Site details
|
|retrieve site-to-site details | Allows other NiFi instances to retrieve Site-To-Site details
|
||||||
|
@ -270,6 +269,17 @@ Processors that allow us to ingest data via HTTP, we can select both the `http`
|
||||||
|
|
||||||
image::add-processor-with-tag-cloud.png["Add Processor with Tag Cloud"]
|
image::add-processor-with-tag-cloud.png["Add Processor with Tag Cloud"]
|
||||||
|
|
||||||
|
Restricted components will be marked with a
|
||||||
|
image:restricted.png["Restricted"]
|
||||||
|
icon next to their name. These are components 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.
|
||||||
|
|
||||||
|
Before a user is allowed to create and modify restricted components they must be granted access to restricted components. Refer to
|
||||||
|
<<UI-with-multi-tenant-authorization,multi-tenant>> documentation.
|
||||||
|
|
||||||
Clicking the `Add` button or double-clicking on a Processor Type will add the selected Processor to the canvas at the
|
Clicking the `Add` button or double-clicking on a Processor Type will add the selected Processor to the canvas at the
|
||||||
location that it was dropped.
|
location that it was dropped.
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,15 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.flume;
|
package org.apache.nifi.processors.flume;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.common.base.Throwables;
|
||||||
import java.util.Set;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import org.apache.flume.EventDeliveryException;
|
import org.apache.flume.EventDeliveryException;
|
||||||
import org.apache.flume.Sink;
|
import org.apache.flume.Sink;
|
||||||
import org.apache.flume.conf.Configurables;
|
import org.apache.flume.conf.Configurables;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -38,9 +39,8 @@ import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import java.util.List;
|
||||||
import com.google.common.collect.ImmutableList;
|
import java.util.Set;
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This processor runs a Flume sink
|
* This processor runs a Flume sink
|
||||||
|
@ -49,6 +49,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Tags({"flume", "hadoop", "put", "sink"})
|
@Tags({"flume", "hadoop", "put", "sink"})
|
||||||
@InputRequirement(Requirement.INPUT_REQUIRED)
|
@InputRequirement(Requirement.INPUT_REQUIRED)
|
||||||
@CapabilityDescription("Execute a Flume sink. Each input FlowFile is converted into a Flume Event for processing by the sink.")
|
@CapabilityDescription("Execute a Flume sink. Each input FlowFile is converted into a Flume Event for processing by the sink.")
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary Flume configurations assuming all permissions that NiFi has.")
|
||||||
public class ExecuteFlumeSink extends AbstractFlumeProcessor {
|
public class ExecuteFlumeSink extends AbstractFlumeProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor SINK_TYPE = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor SINK_TYPE = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -16,10 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.flume;
|
package org.apache.nifi.processors.flume;
|
||||||
|
|
||||||
import java.util.List;
|
import com.google.common.base.Throwables;
|
||||||
import java.util.Set;
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import org.apache.flume.EventDeliveryException;
|
import org.apache.flume.EventDeliveryException;
|
||||||
import org.apache.flume.EventDrivenSource;
|
import org.apache.flume.EventDrivenSource;
|
||||||
import org.apache.flume.PollableSource;
|
import org.apache.flume.PollableSource;
|
||||||
|
@ -29,6 +28,7 @@ import org.apache.flume.conf.Configurables;
|
||||||
import org.apache.flume.source.EventDrivenSourceRunner;
|
import org.apache.flume.source.EventDrivenSourceRunner;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -44,9 +44,9 @@ import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
import com.google.common.base.Throwables;
|
import java.util.List;
|
||||||
import com.google.common.collect.ImmutableList;
|
import java.util.Set;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This processor runs a Flume source
|
* This processor runs a Flume source
|
||||||
|
@ -55,6 +55,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
@Tags({"flume", "hadoop", "get", "source"})
|
@Tags({"flume", "hadoop", "get", "source"})
|
||||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||||
@CapabilityDescription("Execute a Flume source. Each Flume Event is sent to the success relationship as a FlowFile")
|
@CapabilityDescription("Execute a Flume source. Each Flume Event is sent to the success relationship as a FlowFile")
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary Flume configurations assuming all permissions that NiFi has.")
|
||||||
public class ExecuteFlumeSource extends AbstractFlumeProcessor {
|
public class ExecuteFlumeSource extends AbstractFlumeProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor SOURCE_TYPE = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor SOURCE_TYPE = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -17,8 +17,9 @@
|
||||||
package org.apache.nifi.web.api.dto;
|
package org.apache.nifi.web.api.dto;
|
||||||
|
|
||||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||||
import java.util.Set;
|
|
||||||
import javax.xml.bind.annotation.XmlType;
|
import javax.xml.bind.annotation.XmlType;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used for providing documentation of a specified type.
|
* Class used for providing documentation of a specified type.
|
||||||
|
@ -28,6 +29,7 @@ public class DocumentedTypeDTO {
|
||||||
|
|
||||||
private String type;
|
private String type;
|
||||||
private String description;
|
private String description;
|
||||||
|
private String usageRestriction;
|
||||||
private Set<String> tags;
|
private Set<String> tags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,6 +46,20 @@ public class DocumentedTypeDTO {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return An optional description of why the usage of this component is restricted
|
||||||
|
*/
|
||||||
|
@ApiModelProperty(
|
||||||
|
value = "The description of why the usage of this component is restricted."
|
||||||
|
)
|
||||||
|
public String getUsageRestriction() {
|
||||||
|
return usageRestriction;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsageRestriction(String usageRestriction) {
|
||||||
|
this.usageRestriction = usageRestriction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The type is the fully-qualified name of a Java class
|
* @return The type is the fully-qualified name of a Java class
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class CurrentUserEntity extends Entity {
|
||||||
private PermissionsDTO controllerPermissions;
|
private PermissionsDTO controllerPermissions;
|
||||||
private PermissionsDTO policiesPermissions;
|
private PermissionsDTO policiesPermissions;
|
||||||
private PermissionsDTO systemPermissions;
|
private PermissionsDTO systemPermissions;
|
||||||
|
private PermissionsDTO restrictedComponentsPermissions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the user identity being serialized
|
* @return the user identity being serialized
|
||||||
|
@ -132,4 +133,16 @@ public class CurrentUserEntity extends Entity {
|
||||||
public void setSystemPermissions(PermissionsDTO systemPermissions) {
|
public void setSystemPermissions(PermissionsDTO systemPermissions) {
|
||||||
this.systemPermissions = systemPermissions;
|
this.systemPermissions = systemPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return permissions for accessing the restricted components
|
||||||
|
*/
|
||||||
|
@ApiModelProperty("Permissions for accessing restricted components. Note: the read permission are not used and will always be false.")
|
||||||
|
public PermissionsDTO getRestrictedComponentsPermissions() {
|
||||||
|
return restrictedComponentsPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRestrictedComponentsPermissions(PermissionsDTO restrictedComponentsPermissions) {
|
||||||
|
this.restrictedComponentsPermissions = restrictedComponentsPermissions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.html;
|
package org.apache.nifi.documentation.html;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.xml.stream.FactoryConfigurationError;
|
|
||||||
import javax.xml.stream.XMLOutputFactory;
|
|
||||||
import javax.xml.stream.XMLStreamException;
|
|
||||||
import javax.xml.stream.XMLStreamWriter;
|
|
||||||
|
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperties;
|
import org.apache.nifi.annotation.behavior.DynamicProperties;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
|
@ -40,6 +30,16 @@ import org.apache.nifi.controller.ControllerService;
|
||||||
import org.apache.nifi.documentation.DocumentationWriter;
|
import org.apache.nifi.documentation.DocumentationWriter;
|
||||||
import org.apache.nifi.nar.ExtensionManager;
|
import org.apache.nifi.nar.ExtensionManager;
|
||||||
|
|
||||||
|
import javax.xml.stream.FactoryConfigurationError;
|
||||||
|
import javax.xml.stream.XMLOutputFactory;
|
||||||
|
import javax.xml.stream.XMLStreamException;
|
||||||
|
import javax.xml.stream.XMLStreamWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates HTML documentation for a ConfigurableComponent. This class is used
|
* Generates HTML documentation for a ConfigurableComponent. This class is used
|
||||||
* to generate documentation for ControllerService and ReportingTask because
|
* to generate documentation for ControllerService and ReportingTask because
|
||||||
|
@ -129,6 +129,7 @@ public class HtmlDocumentationWriter implements DocumentationWriter {
|
||||||
writeDynamicProperties(configurableComponent, xmlStreamWriter);
|
writeDynamicProperties(configurableComponent, xmlStreamWriter);
|
||||||
writeAdditionalBodyInfo(configurableComponent, xmlStreamWriter);
|
writeAdditionalBodyInfo(configurableComponent, xmlStreamWriter);
|
||||||
writeStatefulInfo(configurableComponent, xmlStreamWriter);
|
writeStatefulInfo(configurableComponent, xmlStreamWriter);
|
||||||
|
writeRestrictedInfo(configurableComponent, xmlStreamWriter);
|
||||||
writeSeeAlso(configurableComponent, xmlStreamWriter);
|
writeSeeAlso(configurableComponent, xmlStreamWriter);
|
||||||
xmlStreamWriter.writeEndElement();
|
xmlStreamWriter.writeEndElement();
|
||||||
}
|
}
|
||||||
|
@ -165,6 +166,24 @@ public class HtmlDocumentationWriter implements DocumentationWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the description of the Restricted annotation if provided in this component.
|
||||||
|
*
|
||||||
|
* @param configurableComponent the component to describe
|
||||||
|
* @param xmlStreamWriter the stream writer to use
|
||||||
|
* @throws XMLStreamException thrown if there was a problem writing the XML
|
||||||
|
*/
|
||||||
|
private void writeRestrictedInfo(ConfigurableComponent configurableComponent, XMLStreamWriter xmlStreamWriter)
|
||||||
|
throws XMLStreamException {
|
||||||
|
final Restricted restricted = configurableComponent.getClass().getAnnotation(Restricted.class);
|
||||||
|
|
||||||
|
writeSimpleElement(xmlStreamWriter, "h3", "Restricted: ");
|
||||||
|
|
||||||
|
if(restricted != null) {
|
||||||
|
writeSimpleElement(xmlStreamWriter, "td", restricted.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the list of components that may be linked from this component.
|
* Writes the list of components that may be linked from this component.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,10 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.example;
|
package org.apache.nifi.documentation.example;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
import org.apache.nifi.annotation.lifecycle.OnRemoved;
|
import org.apache.nifi.annotation.lifecycle.OnRemoved;
|
||||||
|
@ -29,8 +26,13 @@ import org.apache.nifi.controller.AbstractControllerService;
|
||||||
import org.apache.nifi.controller.ConfigurationContext;
|
import org.apache.nifi.controller.ConfigurationContext;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@CapabilityDescription("A documented controller service that can help you do things")
|
@CapabilityDescription("A documented controller service that can help you do things")
|
||||||
@Tags({ "one", "two", "three" })
|
@Tags({ "one", "two", "three" })
|
||||||
|
@Restricted("controller service restriction description")
|
||||||
public class FullyDocumentedControllerService extends AbstractControllerService implements SampleService {
|
public class FullyDocumentedControllerService extends AbstractControllerService implements SampleService {
|
||||||
|
|
||||||
public static final PropertyDescriptor KEYSTORE = new PropertyDescriptor.Builder().name("Keystore Filename").description("The fully-qualified filename of the Keystore").defaultValue(null)
|
public static final PropertyDescriptor KEYSTORE = new PropertyDescriptor.Builder().name("Keystore Filename").description("The fully-qualified filename of the Keystore").defaultValue(null)
|
||||||
|
|
|
@ -16,15 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.example;
|
package org.apache.nifi.documentation.example;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicRelationship;
|
import org.apache.nifi.annotation.behavior.DynamicRelationship;
|
||||||
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
@ -44,6 +39,12 @@ import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Tags({"one", "two", "three"})
|
@Tags({"one", "two", "three"})
|
||||||
@CapabilityDescription("This is a processor that is used to test documentation.")
|
@CapabilityDescription("This is a processor that is used to test documentation.")
|
||||||
@WritesAttributes({
|
@WritesAttributes({
|
||||||
|
@ -54,6 +55,7 @@ import org.apache.nifi.processor.util.StandardValidators;
|
||||||
@DynamicProperty(name = "Relationship Name", supportsExpressionLanguage = true, value = "some XPath", description = "Routes FlowFiles to relationships based on XPath")
|
@DynamicProperty(name = "Relationship Name", supportsExpressionLanguage = true, value = "some XPath", description = "Routes FlowFiles to relationships based on XPath")
|
||||||
@DynamicRelationship(name = "name from dynamic property", description = "all files that match the properties XPath")
|
@DynamicRelationship(name = "name from dynamic property", description = "all files that match the properties XPath")
|
||||||
@Stateful(scopes = {Scope.CLUSTER, Scope.LOCAL}, description = "state management description")
|
@Stateful(scopes = {Scope.CLUSTER, Scope.LOCAL}, description = "state management description")
|
||||||
|
@Restricted("processor restriction description")
|
||||||
public class FullyDocumentedProcessor extends AbstractProcessor {
|
public class FullyDocumentedProcessor extends AbstractProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor DIRECTORY = new PropertyDescriptor.Builder().name("Input Directory")
|
public static final PropertyDescriptor DIRECTORY = new PropertyDescriptor.Builder().name("Input Directory")
|
||||||
|
|
|
@ -16,20 +16,22 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.example;
|
package org.apache.nifi.documentation.example;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.controller.ConfigurationContext;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
import org.apache.nifi.annotation.lifecycle.OnRemoved;
|
import org.apache.nifi.annotation.lifecycle.OnRemoved;
|
||||||
import org.apache.nifi.annotation.lifecycle.OnShutdown;
|
import org.apache.nifi.annotation.lifecycle.OnShutdown;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.controller.ConfigurationContext;
|
||||||
import org.apache.nifi.reporting.AbstractReportingTask;
|
import org.apache.nifi.reporting.AbstractReportingTask;
|
||||||
import org.apache.nifi.reporting.ReportingContext;
|
import org.apache.nifi.reporting.ReportingContext;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@CapabilityDescription("A helper reporting task to do...")
|
@CapabilityDescription("A helper reporting task to do...")
|
||||||
@Tags({"first", "second", "third"})
|
@Tags({"first", "second", "third"})
|
||||||
|
@Restricted("reporting task restriction description")
|
||||||
public class FullyDocumentedReportingTask extends AbstractReportingTask {
|
public class FullyDocumentedReportingTask extends AbstractReportingTask {
|
||||||
|
|
||||||
public static final PropertyDescriptor SHOW_DELTAS = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor SHOW_DELTAS = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.html;
|
package org.apache.nifi.documentation.html;
|
||||||
|
|
||||||
import static org.apache.nifi.documentation.html.XmlValidator.assertContains;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.nifi.controller.ControllerService;
|
import org.apache.nifi.controller.ControllerService;
|
||||||
import org.apache.nifi.documentation.DocumentationWriter;
|
import org.apache.nifi.documentation.DocumentationWriter;
|
||||||
import org.apache.nifi.documentation.example.ControllerServiceWithLogger;
|
import org.apache.nifi.documentation.example.ControllerServiceWithLogger;
|
||||||
|
@ -37,6 +31,12 @@ import org.apache.nifi.reporting.ReportingTask;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.apache.nifi.documentation.html.XmlValidator.assertContains;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class HtmlDocumentationWriterTest {
|
public class HtmlDocumentationWriterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -77,6 +77,9 @@ public class HtmlDocumentationWriterTest {
|
||||||
assertContains(results, "PKCS12");
|
assertContains(results, "PKCS12");
|
||||||
assertContains(results, "Sensitive Property: true");
|
assertContains(results, "Sensitive Property: true");
|
||||||
|
|
||||||
|
// restricted
|
||||||
|
assertContains(results, "controller service restriction description");
|
||||||
|
|
||||||
// verify the right OnRemoved and OnShutdown methods were called
|
// verify the right OnRemoved and OnShutdown methods were called
|
||||||
Assert.assertEquals(0, controllerService.getOnRemovedArgs());
|
Assert.assertEquals(0, controllerService.getOnRemovedArgs());
|
||||||
Assert.assertEquals(0, controllerService.getOnRemovedNoArgs());
|
Assert.assertEquals(0, controllerService.getOnRemovedNoArgs());
|
||||||
|
@ -114,6 +117,9 @@ public class HtmlDocumentationWriterTest {
|
||||||
assertContains(results, "true");
|
assertContains(results, "true");
|
||||||
assertContains(results, "false");
|
assertContains(results, "false");
|
||||||
|
|
||||||
|
// restricted
|
||||||
|
assertContains(results, "reporting task restriction description");
|
||||||
|
|
||||||
// verify the right OnRemoved and OnShutdown methods were called
|
// verify the right OnRemoved and OnShutdown methods were called
|
||||||
Assert.assertEquals(0, reportingTask.getOnRemovedArgs());
|
Assert.assertEquals(0, reportingTask.getOnRemovedArgs());
|
||||||
Assert.assertEquals(0, reportingTask.getOnRemovedNoArgs());
|
Assert.assertEquals(0, reportingTask.getOnRemovedNoArgs());
|
||||||
|
|
|
@ -16,12 +16,6 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.documentation.html;
|
package org.apache.nifi.documentation.html;
|
||||||
|
|
||||||
import static org.apache.nifi.documentation.html.XmlValidator.assertContains;
|
|
||||||
import static org.apache.nifi.documentation.html.XmlValidator.assertNotContains;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.documentation.DocumentationWriter;
|
import org.apache.nifi.documentation.DocumentationWriter;
|
||||||
import org.apache.nifi.documentation.example.FullyDocumentedProcessor;
|
import org.apache.nifi.documentation.example.FullyDocumentedProcessor;
|
||||||
|
@ -31,6 +25,12 @@ import org.apache.nifi.documentation.init.ProcessorInitializer;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.apache.nifi.documentation.html.XmlValidator.assertContains;
|
||||||
|
import static org.apache.nifi.documentation.html.XmlValidator.assertNotContains;
|
||||||
|
|
||||||
public class ProcessorDocumentationWriterTest {
|
public class ProcessorDocumentationWriterTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -69,6 +69,8 @@ public class ProcessorDocumentationWriterTest {
|
||||||
assertContains(results, "CLUSTER, LOCAL");
|
assertContains(results, "CLUSTER, LOCAL");
|
||||||
assertContains(results, "state management description");
|
assertContains(results, "state management description");
|
||||||
|
|
||||||
|
assertContains(results, "processor restriction description");
|
||||||
|
|
||||||
assertNotContains(results, "iconSecure.png");
|
assertNotContains(results, "iconSecure.png");
|
||||||
assertContains(results, FullyDocumentedProcessor.class.getAnnotation(CapabilityDescription.class)
|
assertContains(results, FullyDocumentedProcessor.class.getAnnotation(CapabilityDescription.class)
|
||||||
.value());
|
.value());
|
||||||
|
|
|
@ -333,6 +333,9 @@ public class FileAuthorizer extends AbstractPolicyBasedAuthorizer {
|
||||||
addAccessPolicy(authorizations, ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, adminUser.getIdentifier(), WRITE_CODE);
|
addAccessPolicy(authorizations, ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, adminUser.getIdentifier(), WRITE_CODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// grant the user write to restricted components
|
||||||
|
addAccessPolicy(authorizations, ResourceType.RestrictedComponents.getValue(), adminUser.getIdentifier(), WRITE_CODE);
|
||||||
|
|
||||||
// grant the user read/write access to the /tenants resource
|
// grant the user read/write access to the /tenants resource
|
||||||
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), READ_CODE);
|
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), READ_CODE);
|
||||||
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), WRITE_CODE);
|
addAccessPolicy(authorizations, ResourceType.Tenant.getValue(), adminUser.getIdentifier(), WRITE_CODE);
|
||||||
|
|
|
@ -72,6 +72,7 @@ public final class RoleAccessPolicy {
|
||||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), READ_ACTION));
|
||||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), WRITE_ACTION));
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.Controller.getValue(), WRITE_ACTION));
|
||||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.System.getValue(), READ_ACTION));
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.System.getValue(), READ_ACTION));
|
||||||
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.RestrictedComponents.getValue(), WRITE_ACTION));
|
||||||
if (rootGroupId != null) {
|
if (rootGroupId != null) {
|
||||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, READ_ACTION));
|
||||||
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, WRITE_ACTION));
|
dfmPolicies.add(new RoleAccessPolicy(ResourceType.ProcessGroup.getValue() + "/" + rootGroupId, WRITE_ACTION));
|
||||||
|
|
|
@ -312,7 +312,7 @@ public class FileAuthorizerTest {
|
||||||
|
|
||||||
// verify user3's policies
|
// verify user3's policies
|
||||||
final Map<String,Set<RequestAction>> user3Policies = getResourceActions(policies, user3);
|
final Map<String,Set<RequestAction>> user3Policies = getResourceActions(policies, user3);
|
||||||
assertEquals(5, user3Policies.size());
|
assertEquals(6, user3Policies.size());
|
||||||
|
|
||||||
assertTrue(user3Policies.containsKey(ResourceType.Flow.getValue()));
|
assertTrue(user3Policies.containsKey(ResourceType.Flow.getValue()));
|
||||||
assertEquals(1, user3Policies.get(ResourceType.Flow.getValue()).size());
|
assertEquals(1, user3Policies.get(ResourceType.Flow.getValue()).size());
|
||||||
|
@ -502,7 +502,7 @@ public class FileAuthorizerTest {
|
||||||
assertEquals(adminIdentity, adminUser.getIdentity());
|
assertEquals(adminIdentity, adminUser.getIdentity());
|
||||||
|
|
||||||
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
||||||
assertEquals(11, policies.size());
|
assertEquals(12, policies.size());
|
||||||
|
|
||||||
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
||||||
|
|
||||||
|
@ -540,7 +540,7 @@ public class FileAuthorizerTest {
|
||||||
assertEquals(adminIdentity, adminUser.getIdentity());
|
assertEquals(adminIdentity, adminUser.getIdentity());
|
||||||
|
|
||||||
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
||||||
assertEquals(7, policies.size());
|
assertEquals(8, policies.size());
|
||||||
|
|
||||||
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
||||||
|
|
||||||
|
@ -578,7 +578,7 @@ public class FileAuthorizerTest {
|
||||||
assertEquals(adminIdentity, adminUser.getIdentity());
|
assertEquals(adminIdentity, adminUser.getIdentity());
|
||||||
|
|
||||||
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
final Set<AccessPolicy> policies = authorizer.getAccessPolicies();
|
||||||
assertEquals(7, policies.size());
|
assertEquals(8, policies.size());
|
||||||
|
|
||||||
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
final String rootGroupResource = ResourceType.ProcessGroup.getValue() + "/" + ROOT_GROUP_ID;
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,18 @@ public final class ResourceFactory {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final static Resource RESTRICTED_COMPONENTS_RESOURCE = new Resource() {
|
||||||
|
@Override
|
||||||
|
public String getIdentifier() {
|
||||||
|
return ResourceType.RestrictedComponents.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Restricted Components";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final static Resource TENANT_RESOURCE = new Resource() {
|
private final static Resource TENANT_RESOURCE = new Resource() {
|
||||||
@Override
|
@Override
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
|
@ -241,6 +253,15 @@ public final class ResourceFactory {
|
||||||
return SYSTEM_RESOURCE;
|
return SYSTEM_RESOURCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the Resource for accessing restricted components.
|
||||||
|
*
|
||||||
|
* @return The restricted components resource
|
||||||
|
*/
|
||||||
|
public static Resource getRestrictedComponentsResource() {
|
||||||
|
return RESTRICTED_COMPONENTS_RESOURCE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the Resource for accessing Tenants which includes creating, modifying, and deleting Users and UserGroups.
|
* Gets the Resource for accessing Tenants which includes creating, modifying, and deleting Users and UserGroups.
|
||||||
*
|
*
|
||||||
|
|
|
@ -37,6 +37,7 @@ public enum ResourceType {
|
||||||
SiteToSite("/site-to-site"),
|
SiteToSite("/site-to-site"),
|
||||||
DataTransfer("/data-transfer"),
|
DataTransfer("/data-transfer"),
|
||||||
System("/system"),
|
System("/system"),
|
||||||
|
RestrictedComponents("/restricted-components"),
|
||||||
Template("/templates"),
|
Template("/templates"),
|
||||||
Tenant("/tenants");
|
Tenant("/tenants");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.authorization.resource;
|
||||||
|
|
||||||
|
import org.apache.nifi.authorization.Resource;
|
||||||
|
|
||||||
|
public class RestrictedComponentsAuthorizable implements Authorizable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authorizable getParentAuthorizable() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resource getResource() {
|
||||||
|
return ResourceFactory.getRestrictedComponentsResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,7 +16,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.controller;
|
package org.apache.nifi.controller;
|
||||||
|
|
||||||
|
import org.apache.nifi.authorization.AccessDeniedException;
|
||||||
|
import org.apache.nifi.authorization.AuthorizationResult;
|
||||||
|
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
||||||
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.resource.ComponentAuthorizable;
|
import org.apache.nifi.authorization.resource.ComponentAuthorizable;
|
||||||
|
import org.apache.nifi.authorization.resource.RestrictedComponentsAuthorizable;
|
||||||
|
import org.apache.nifi.authorization.user.NiFiUser;
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
import org.apache.nifi.components.ValidationResult;
|
import org.apache.nifi.components.ValidationResult;
|
||||||
|
|
||||||
|
@ -58,4 +65,37 @@ public interface ConfiguredComponent extends ComponentAuthorizable {
|
||||||
*/
|
*/
|
||||||
String getCanonicalClassName();
|
String getCanonicalClassName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return whether or not the underlying implementation is restricted
|
||||||
|
*/
|
||||||
|
boolean isRestricted();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) {
|
||||||
|
// if this is a modification request and the reporting task is restricted ensure the user has elevated privileges. if this
|
||||||
|
// is not a modification request, we just want to use the normal rules
|
||||||
|
if (RequestAction.WRITE.equals(action) && isRestricted()) {
|
||||||
|
final RestrictedComponentsAuthorizable restrictedComponentsAuthorizable = new RestrictedComponentsAuthorizable();
|
||||||
|
final AuthorizationResult result = restrictedComponentsAuthorizable.checkAuthorization(authorizer, RequestAction.WRITE, user, resourceContext);
|
||||||
|
if (Result.Denied.equals(result.getResult())) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// defer to the base authorization check
|
||||||
|
return ComponentAuthorizable.super.checkAuthorization(authorizer, action, user, resourceContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
default void authorize(Authorizer authorizer, RequestAction action, NiFiUser user, Map<String, String> resourceContext) throws AccessDeniedException {
|
||||||
|
// if this is a modification request and the reporting task is restricted ensure the user has elevated privileges. if this
|
||||||
|
// is not a modification request, we just want to use the normal rules
|
||||||
|
if (RequestAction.WRITE.equals(action) && isRestricted()) {
|
||||||
|
final RestrictedComponentsAuthorizable restrictedComponentsAuthorizable = new RestrictedComponentsAuthorizable();
|
||||||
|
restrictedComponentsAuthorizable.authorize(authorizer, RequestAction.WRITE, user, resourceContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
// defer to the base authorization check
|
||||||
|
ComponentAuthorizable.super.authorize(authorizer, action, user, resourceContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.apache.commons.lang3.builder.HashCodeBuilder;
|
||||||
import org.apache.nifi.annotation.behavior.EventDriven;
|
import org.apache.nifi.annotation.behavior.EventDriven;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.SideEffectFree;
|
import org.apache.nifi.annotation.behavior.SideEffectFree;
|
||||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||||
|
@ -56,8 +57,8 @@ import org.apache.nifi.processor.Processor;
|
||||||
import org.apache.nifi.processor.Relationship;
|
import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.SimpleProcessLogger;
|
import org.apache.nifi.processor.SimpleProcessLogger;
|
||||||
import org.apache.nifi.registry.VariableRegistry;
|
import org.apache.nifi.registry.VariableRegistry;
|
||||||
import org.apache.nifi.scheduling.SchedulingStrategy;
|
|
||||||
import org.apache.nifi.scheduling.ExecutionNode;
|
import org.apache.nifi.scheduling.ExecutionNode;
|
||||||
|
import org.apache.nifi.scheduling.SchedulingStrategy;
|
||||||
import org.apache.nifi.util.FormatUtils;
|
import org.apache.nifi.util.FormatUtils;
|
||||||
import org.apache.nifi.util.NiFiProperties;
|
import org.apache.nifi.util.NiFiProperties;
|
||||||
import org.apache.nifi.util.ReflectionUtils;
|
import org.apache.nifi.util.ReflectionUtils;
|
||||||
|
@ -236,6 +237,11 @@ public class StandardProcessorNode extends ProcessorNode implements Connectable
|
||||||
return ResourceFactory.getComponentResource(ResourceType.Processor, getIdentifier(), getName());
|
return ResourceFactory.getComponentResource(ResourceType.Processor, getIdentifier(), getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return getProcessor().getClass().isAnnotationPresent(Restricted.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides and opportunity to retain information about this particular
|
* Provides and opportunity to retain information about this particular
|
||||||
* processor instance
|
* processor instance
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.controller.reporting;
|
package org.apache.nifi.controller.reporting;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.authorization.Resource;
|
import org.apache.nifi.authorization.Resource;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
import org.apache.nifi.authorization.resource.ResourceFactory;
|
import org.apache.nifi.authorization.resource.ResourceFactory;
|
||||||
|
@ -57,6 +58,11 @@ public class StandardReportingTaskNode extends AbstractReportingTaskNode impleme
|
||||||
return ResourceFactory.getComponentResource(ResourceType.ReportingTask, getIdentifier(), getName());
|
return ResourceFactory.getComponentResource(ResourceType.ReportingTask, getIdentifier(), getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return getReportingTask().getClass().isAnnotationPresent(Restricted.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReportingContext getReportingContext() {
|
public ReportingContext getReportingContext() {
|
||||||
return new StandardReportingContext(flowController, flowController.getBulletinRepository(), getProperties(), flowController, getReportingTask(), getVariableRegistry());
|
return new StandardReportingContext(flowController, flowController.getBulletinRepository(), getProperties(), flowController, getReportingTask(), getVariableRegistry());
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package org.apache.nifi.controller.service;
|
package org.apache.nifi.controller.service;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.lifecycle.OnDisabled;
|
import org.apache.nifi.annotation.lifecycle.OnDisabled;
|
||||||
import org.apache.nifi.annotation.lifecycle.OnEnabled;
|
import org.apache.nifi.annotation.lifecycle.OnEnabled;
|
||||||
import org.apache.nifi.authorization.Resource;
|
import org.apache.nifi.authorization.Resource;
|
||||||
|
@ -120,6 +121,11 @@ public class StandardControllerServiceNode extends AbstractConfiguredComponent i
|
||||||
return ResourceFactory.getComponentResource(ResourceType.ControllerService, getIdentifier(), getName());
|
return ResourceFactory.getComponentResource(ResourceType.ControllerService, getIdentifier(), getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return getControllerServiceImplementation().getClass().isAnnotationPresent(Restricted.class);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerService getProxiedControllerService() {
|
public ControllerService getProxiedControllerService() {
|
||||||
return proxedControllerService;
|
return proxedControllerService;
|
||||||
|
|
|
@ -34,7 +34,7 @@ public interface AuthorizableLookup {
|
||||||
* @param id processor id
|
* @param id processor id
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getProcessor(String id);
|
ConfigurableComponentAuthorizable getProcessor(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable for this Processor. This will create a dummy instance of the
|
* Get the authorizable for this Processor. This will create a dummy instance of the
|
||||||
|
@ -44,7 +44,7 @@ public interface AuthorizableLookup {
|
||||||
* @param type processor type
|
* @param type processor type
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getProcessorByType(String type);
|
ConfigurableComponentAuthorizable getProcessorByType(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable for querying Provenance.
|
* Get the authorizable for querying Provenance.
|
||||||
|
@ -156,7 +156,7 @@ public interface AuthorizableLookup {
|
||||||
* @param id controller service id
|
* @param id controller service id
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getControllerService(String id);
|
ConfigurableComponentAuthorizable getControllerService(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable for this Controller Service. This will create a dummy instance of the
|
* Get the authorizable for this Controller Service. This will create a dummy instance of the
|
||||||
|
@ -166,7 +166,7 @@ public interface AuthorizableLookup {
|
||||||
* @param type processor type
|
* @param type processor type
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getControllerServiceByType(String type);
|
ConfigurableComponentAuthorizable getControllerServiceByType(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable referencing component.
|
* Get the authorizable referencing component.
|
||||||
|
@ -183,7 +183,7 @@ public interface AuthorizableLookup {
|
||||||
* @param id reporting task id
|
* @param id reporting task id
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getReportingTask(String id);
|
ConfigurableComponentAuthorizable getReportingTask(String id);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable for this Reporting Task. This will create a dummy instance of the
|
* Get the authorizable for this Reporting Task. This will create a dummy instance of the
|
||||||
|
@ -193,7 +193,7 @@ public interface AuthorizableLookup {
|
||||||
* @param type processor type
|
* @param type processor type
|
||||||
* @return authorizable
|
* @return authorizable
|
||||||
*/
|
*/
|
||||||
ControllerServiceReferencingComponentAuthorizable getReportingTaskByType(String type);
|
ConfigurableComponentAuthorizable getReportingTaskByType(String type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the authorizable Template.
|
* Get the authorizable Template.
|
||||||
|
@ -271,4 +271,10 @@ public interface AuthorizableLookup {
|
||||||
*/
|
*/
|
||||||
Authorizable getSystem();
|
Authorizable getSystem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authorizable for accessing restricted components.
|
||||||
|
*
|
||||||
|
* @return authorizable
|
||||||
|
*/
|
||||||
|
Authorizable getRestrictedComponents();
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public final class AuthorizeControllerServiceReference {
|
||||||
* @param authorizer authorizer
|
* @param authorizer authorizer
|
||||||
* @param lookup lookup
|
* @param lookup lookup
|
||||||
*/
|
*/
|
||||||
public static void authorizeControllerServiceReferences(final Map<String, String> proposedProperties, final ControllerServiceReferencingComponentAuthorizable authorizable,
|
public static void authorizeControllerServiceReferences(final Map<String, String> proposedProperties, final ConfigurableComponentAuthorizable authorizable,
|
||||||
final Authorizer authorizer, final AuthorizableLookup lookup) {
|
final Authorizer authorizer, final AuthorizableLookup lookup) {
|
||||||
|
|
||||||
// only attempt to authorize if properties are changing
|
// only attempt to authorize if properties are changing
|
||||||
|
|
|
@ -22,7 +22,7 @@ import org.apache.nifi.components.PropertyDescriptor;
|
||||||
/**
|
/**
|
||||||
* Authorizable for a component that references a ControllerService.
|
* Authorizable for a component that references a ControllerService.
|
||||||
*/
|
*/
|
||||||
public interface ControllerServiceReferencingComponentAuthorizable {
|
public interface ConfigurableComponentAuthorizable {
|
||||||
/**
|
/**
|
||||||
* Returns the base authorizable for this ControllerServiceReference. Non null
|
* Returns the base authorizable for this ControllerServiceReference. Non null
|
||||||
*
|
*
|
||||||
|
@ -30,6 +30,13 @@ public interface ControllerServiceReferencingComponentAuthorizable {
|
||||||
*/
|
*/
|
||||||
Authorizable getAuthorizable();
|
Authorizable getAuthorizable();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the underlying configurable component is restricted.
|
||||||
|
*
|
||||||
|
* @return whether or not the underlying configurable component is restricted
|
||||||
|
*/
|
||||||
|
boolean isRestricted();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the property descriptor for the specified property.
|
* Returns the property descriptor for the specified property.
|
||||||
*
|
*
|
|
@ -23,6 +23,7 @@ import org.apache.nifi.authorization.resource.DataAuthorizable;
|
||||||
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
|
import org.apache.nifi.authorization.resource.DataTransferAuthorizable;
|
||||||
import org.apache.nifi.authorization.resource.ResourceFactory;
|
import org.apache.nifi.authorization.resource.ResourceFactory;
|
||||||
import org.apache.nifi.authorization.resource.ResourceType;
|
import org.apache.nifi.authorization.resource.ResourceType;
|
||||||
|
import org.apache.nifi.authorization.resource.RestrictedComponentsAuthorizable;
|
||||||
import org.apache.nifi.authorization.resource.TenantAuthorizable;
|
import org.apache.nifi.authorization.resource.TenantAuthorizable;
|
||||||
import org.apache.nifi.authorization.user.NiFiUser;
|
import org.apache.nifi.authorization.user.NiFiUser;
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
@ -62,6 +63,8 @@ import java.util.Set;
|
||||||
class StandardAuthorizableLookup implements AuthorizableLookup {
|
class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
|
|
||||||
private static final TenantAuthorizable TENANT_AUTHORIZABLE = new TenantAuthorizable();
|
private static final TenantAuthorizable TENANT_AUTHORIZABLE = new TenantAuthorizable();
|
||||||
|
private static final Authorizable RESTRICTED_COMPONENTS_AUTHORIZABLE = new RestrictedComponentsAuthorizable();
|
||||||
|
|
||||||
private static final Authorizable POLICIES_AUTHORIZABLE = new Authorizable() {
|
private static final Authorizable POLICIES_AUTHORIZABLE = new Authorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getParentAuthorizable() {
|
public Authorizable getParentAuthorizable() {
|
||||||
|
@ -134,14 +137,19 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getProcessor(final String id) {
|
public ConfigurableComponentAuthorizable getProcessor(final String id) {
|
||||||
final ProcessorNode processorNode = processorDAO.getProcessor(id);
|
final ProcessorNode processorNode = processorDAO.getProcessor(id);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return processorNode;
|
return processorNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return processorNode.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return processorNode.getProperty(propertyDescriptor);
|
return processorNode.getProperty(propertyDescriptor);
|
||||||
|
@ -155,15 +163,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getProcessorByType(String type) {
|
public ConfigurableComponentAuthorizable getProcessorByType(String type) {
|
||||||
try {
|
try {
|
||||||
final ProcessorNode processorNode = controllerFacade.createTemporaryProcessor(type);
|
final ProcessorNode processorNode = controllerFacade.createTemporaryProcessor(type);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return processorNode;
|
return processorNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return processorNode.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return processorNode.getProperty(propertyDescriptor);
|
return processorNode.getProperty(propertyDescriptor);
|
||||||
|
@ -328,14 +341,19 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getControllerService(final String id) {
|
public ConfigurableComponentAuthorizable getControllerService(final String id) {
|
||||||
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id);
|
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return controllerService;
|
return controllerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return controllerService.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return controllerService.getProperty(propertyDescriptor);
|
return controllerService.getProperty(propertyDescriptor);
|
||||||
|
@ -349,15 +367,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getControllerServiceByType(String type) {
|
public ConfigurableComponentAuthorizable getControllerServiceByType(String type) {
|
||||||
try {
|
try {
|
||||||
final ControllerServiceNode controllerService = controllerFacade.createTemporaryControllerService(type);
|
final ControllerServiceNode controllerService = controllerFacade.createTemporaryControllerService(type);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return controllerService;
|
return controllerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return controllerService.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return controllerService.getProperty(propertyDescriptor);
|
return controllerService.getProperty(propertyDescriptor);
|
||||||
|
@ -417,14 +440,19 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getReportingTask(final String id) {
|
public ConfigurableComponentAuthorizable getReportingTask(final String id) {
|
||||||
final ReportingTaskNode reportingTaskNode = reportingTaskDAO.getReportingTask(id);
|
final ReportingTaskNode reportingTaskNode = reportingTaskDAO.getReportingTask(id);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return reportingTaskNode;
|
return reportingTaskNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return reportingTaskNode.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return reportingTaskNode.getProperty(propertyDescriptor);
|
return reportingTaskNode.getProperty(propertyDescriptor);
|
||||||
|
@ -438,15 +466,20 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ControllerServiceReferencingComponentAuthorizable getReportingTaskByType(String type) {
|
public ConfigurableComponentAuthorizable getReportingTaskByType(String type) {
|
||||||
try {
|
try {
|
||||||
final ReportingTaskNode reportingTask = controllerFacade.createTemporaryReportingTask(type);
|
final ReportingTaskNode reportingTask = controllerFacade.createTemporaryReportingTask(type);
|
||||||
return new ControllerServiceReferencingComponentAuthorizable() {
|
return new ConfigurableComponentAuthorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getAuthorizable() {
|
public Authorizable getAuthorizable() {
|
||||||
return reportingTask;
|
return reportingTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRestricted() {
|
||||||
|
return reportingTask.isRestricted();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getValue(PropertyDescriptor propertyDescriptor) {
|
public String getValue(PropertyDescriptor propertyDescriptor) {
|
||||||
return reportingTask.getProperty(propertyDescriptor);
|
return reportingTask.getProperty(propertyDescriptor);
|
||||||
|
@ -603,17 +636,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
authorizable = getController();
|
authorizable = getController();
|
||||||
break;
|
break;
|
||||||
case Counters:
|
case Counters:
|
||||||
authorizable = new Authorizable() {
|
authorizable = getCounters();
|
||||||
@Override
|
|
||||||
public Authorizable getParentAuthorizable() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource getResource() {
|
|
||||||
return ResourceFactory.getCountersResource();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
case Flow:
|
case Flow:
|
||||||
authorizable = new Authorizable() {
|
authorizable = new Authorizable() {
|
||||||
|
@ -629,17 +652,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case Provenance:
|
case Provenance:
|
||||||
authorizable = new Authorizable() {
|
authorizable = getProvenance();
|
||||||
@Override
|
|
||||||
public Authorizable getParentAuthorizable() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource getResource() {
|
|
||||||
return ResourceFactory.getProvenanceResource();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
case Proxy:
|
case Proxy:
|
||||||
authorizable = new Authorizable() {
|
authorizable = new Authorizable() {
|
||||||
|
@ -655,7 +668,7 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case Policy:
|
case Policy:
|
||||||
authorizable = POLICIES_AUTHORIZABLE;
|
authorizable = getPolicies();
|
||||||
break;
|
break;
|
||||||
case Resource:
|
case Resource:
|
||||||
authorizable = new Authorizable() {
|
authorizable = new Authorizable() {
|
||||||
|
@ -671,7 +684,6 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case SiteToSite:
|
case SiteToSite:
|
||||||
// TODO - new site-to-site and port specific site-to-site
|
|
||||||
authorizable = new Authorizable() {
|
authorizable = new Authorizable() {
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getParentAuthorizable() {
|
public Authorizable getParentAuthorizable() {
|
||||||
|
@ -685,21 +697,14 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case System:
|
case System:
|
||||||
authorizable = new Authorizable() {
|
authorizable = getSystem();
|
||||||
@Override
|
|
||||||
public Authorizable getParentAuthorizable() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource getResource() {
|
|
||||||
return ResourceFactory.getSystemResource();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
break;
|
break;
|
||||||
case Tenant:
|
case Tenant:
|
||||||
authorizable = getTenant();
|
authorizable = getTenant();
|
||||||
break;
|
break;
|
||||||
|
case RestrictedComponents:
|
||||||
|
authorizable = getRestrictedComponents();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authorizable == null) {
|
if (authorizable == null) {
|
||||||
|
@ -720,6 +725,11 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
|
||||||
return group.findConnectable(id);
|
return group.findConnectable(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authorizable getRestrictedComponents() {
|
||||||
|
return RESTRICTED_COMPONENTS_AUTHORIZABLE;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authorizable getSystem() {
|
public Authorizable getSystem() {
|
||||||
return SYSTEM_AUTHORIZABLE;
|
return SYSTEM_AUTHORIZABLE;
|
||||||
|
|
|
@ -2958,6 +2958,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
||||||
entity.setControllerPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController()));
|
entity.setControllerPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController()));
|
||||||
entity.setPoliciesPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getPolicies()));
|
entity.setPoliciesPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getPolicies()));
|
||||||
entity.setSystemPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getSystem()));
|
entity.setSystemPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getSystem()));
|
||||||
|
entity.setRestrictedComponentsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getRestrictedComponents()));
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.apache.nifi.authorization.AuthorizationResult;
|
||||||
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.UserContextKeys;
|
import org.apache.nifi.authorization.UserContextKeys;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
|
@ -397,7 +397,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
|
||||||
// authorize access
|
// authorize access
|
||||||
serviceFacade.authorizeAccess(lookup -> {
|
serviceFacade.authorizeAccess(lookup -> {
|
||||||
// authorize the processor
|
// authorize the processor
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessor(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
|
||||||
// authorize any referenced service
|
// authorize any referenced service
|
||||||
|
@ -588,7 +588,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
|
||||||
// authorize access
|
// authorize access
|
||||||
serviceFacade.authorizeAccess(lookup -> {
|
serviceFacade.authorizeAccess(lookup -> {
|
||||||
// authorize the controller service
|
// authorize the controller service
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getControllerService(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
|
||||||
// authorize any referenced service
|
// authorize any referenced service
|
||||||
|
@ -753,7 +753,7 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
|
||||||
// authorize access
|
// authorize access
|
||||||
serviceFacade.authorizeAccess(lookup -> {
|
serviceFacade.authorizeAccess(lookup -> {
|
||||||
// authorize the reporting task
|
// authorize the reporting task
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getReportingTask(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
|
||||||
// authorize any referenced service
|
// authorize any referenced service
|
||||||
|
|
|
@ -30,7 +30,7 @@ import org.apache.nifi.authorization.AuthorizationResult;
|
||||||
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.UserContextKeys;
|
import org.apache.nifi.authorization.UserContextKeys;
|
||||||
import org.apache.nifi.authorization.resource.ResourceFactory;
|
import org.apache.nifi.authorization.resource.ResourceFactory;
|
||||||
|
@ -283,8 +283,12 @@ public class ControllerResource extends ApplicationResource {
|
||||||
lookup -> {
|
lookup -> {
|
||||||
authorizeController(RequestAction.WRITE);
|
authorizeController(RequestAction.WRITE);
|
||||||
|
|
||||||
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestReportingTask.getType());
|
||||||
|
if (authorizable.isRestricted()) {
|
||||||
|
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
}
|
||||||
|
|
||||||
if (requestReportingTask.getProperties() != null) {
|
if (requestReportingTask.getProperties() != null) {
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTaskByType(requestReportingTask.getType());
|
|
||||||
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(), authorizable, authorizer, lookup);
|
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestReportingTask.getProperties(), authorizable, authorizer, lookup);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -376,8 +380,12 @@ public class ControllerResource extends ApplicationResource {
|
||||||
lookup -> {
|
lookup -> {
|
||||||
authorizeController(RequestAction.WRITE);
|
authorizeController(RequestAction.WRITE);
|
||||||
|
|
||||||
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestControllerService.getType());
|
||||||
|
if (authorizable.isRestricted()) {
|
||||||
|
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
}
|
||||||
|
|
||||||
if (requestControllerService.getProperties() != null) {
|
if (requestControllerService.getProperties() != null) {
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
|
|
||||||
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
|
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||||
|
@ -621,7 +621,7 @@ public class ControllerServiceResource extends ApplicationResource {
|
||||||
requestRevision,
|
requestRevision,
|
||||||
lookup -> {
|
lookup -> {
|
||||||
// authorize the service
|
// authorize the service
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerService(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getControllerService(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
|
||||||
// authorize any referenced services
|
// authorize any referenced services
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AuthorizableLookup;
|
import org.apache.nifi.authorization.AuthorizableLookup;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.ProcessGroupAuthorizable;
|
import org.apache.nifi.authorization.ProcessGroupAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
|
@ -615,12 +615,18 @@ public class ProcessGroupResource extends ApplicationResource {
|
||||||
serviceFacade,
|
serviceFacade,
|
||||||
requestProcessorEntity,
|
requestProcessorEntity,
|
||||||
lookup -> {
|
lookup -> {
|
||||||
|
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||||
|
|
||||||
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
|
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
|
||||||
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
processGroup.authorize(authorizer, RequestAction.WRITE, user);
|
||||||
|
|
||||||
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestProcessor.getType());
|
||||||
|
if (authorizable.isRestricted()) {
|
||||||
|
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
|
||||||
|
}
|
||||||
|
|
||||||
final ProcessorConfigDTO config = requestProcessor.getConfig();
|
final ProcessorConfigDTO config = requestProcessor.getConfig();
|
||||||
if (config != null && config.getProperties() != null) {
|
if (config != null && config.getProperties() != null) {
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessorByType(requestProcessor.getType());
|
|
||||||
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
|
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(config.getProperties(), authorizable, authorizer, lookup);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2129,11 +2135,17 @@ public class ProcessGroupResource extends ApplicationResource {
|
||||||
serviceFacade,
|
serviceFacade,
|
||||||
requestControllerServiceEntity,
|
requestControllerServiceEntity,
|
||||||
lookup -> {
|
lookup -> {
|
||||||
|
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||||
|
|
||||||
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
|
final Authorizable processGroup = lookup.getProcessGroup(groupId).getAuthorizable();
|
||||||
processGroup.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
processGroup.authorize(authorizer, RequestAction.WRITE, user);
|
||||||
|
|
||||||
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessorByType(requestControllerService.getType());
|
||||||
|
if (authorizable.isRestricted()) {
|
||||||
|
lookup.getRestrictedComponents().authorize(authorizer, RequestAction.WRITE, user);
|
||||||
|
}
|
||||||
|
|
||||||
if (requestControllerService.getProperties() != null) {
|
if (requestControllerService.getProperties() != null) {
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getControllerServiceByType(requestControllerService.getType());
|
|
||||||
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
|
AuthorizeControllerServiceReference.authorizeControllerServiceReferences(requestControllerService.getProperties(), authorizable, authorizer, lookup);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
import org.apache.nifi.authorization.user.NiFiUser;
|
import org.apache.nifi.authorization.user.NiFiUser;
|
||||||
|
@ -448,7 +448,7 @@ public class ProcessorResource extends ApplicationResource {
|
||||||
lookup -> {
|
lookup -> {
|
||||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||||
|
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getProcessor(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getProcessor(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, user);
|
||||||
|
|
||||||
final ProcessorConfigDTO config = requestProcessorDTO.getConfig();
|
final ProcessorConfigDTO config = requestProcessorDTO.getConfig();
|
||||||
|
|
|
@ -25,7 +25,7 @@ import com.wordnik.swagger.annotations.Authorization;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
import org.apache.nifi.authorization.AuthorizeControllerServiceReference;
|
||||||
import org.apache.nifi.authorization.Authorizer;
|
import org.apache.nifi.authorization.Authorizer;
|
||||||
import org.apache.nifi.authorization.ControllerServiceReferencingComponentAuthorizable;
|
import org.apache.nifi.authorization.ConfigurableComponentAuthorizable;
|
||||||
import org.apache.nifi.authorization.RequestAction;
|
import org.apache.nifi.authorization.RequestAction;
|
||||||
import org.apache.nifi.authorization.resource.Authorizable;
|
import org.apache.nifi.authorization.resource.Authorizable;
|
||||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||||
|
@ -425,7 +425,7 @@ public class ReportingTaskResource extends ApplicationResource {
|
||||||
requestRevision,
|
requestRevision,
|
||||||
lookup -> {
|
lookup -> {
|
||||||
// authorize reporting task
|
// authorize reporting task
|
||||||
final ControllerServiceReferencingComponentAuthorizable authorizable = lookup.getReportingTask(id);
|
final ConfigurableComponentAuthorizable authorizable = lookup.getReportingTask(id);
|
||||||
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
authorizable.getAuthorizable().authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
|
||||||
|
|
||||||
// authorize any referenced services
|
// authorize any referenced services
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.nifi.action.details.FlowChangeMoveDetails;
|
||||||
import org.apache.nifi.action.details.FlowChangePurgeDetails;
|
import org.apache.nifi.action.details.FlowChangePurgeDetails;
|
||||||
import org.apache.nifi.action.details.MoveDetails;
|
import org.apache.nifi.action.details.MoveDetails;
|
||||||
import org.apache.nifi.action.details.PurgeDetails;
|
import org.apache.nifi.action.details.PurgeDetails;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -2011,6 +2012,11 @@ public final class DtoFactory {
|
||||||
return dto;
|
return dto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getUsageRestriction(final Class<?> cls) {
|
||||||
|
final Restricted restriction = cls.getAnnotation(Restricted.class);
|
||||||
|
return restriction == null ? null : restriction.value();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the capability description from the specified class.
|
* Gets the capability description from the specified class.
|
||||||
*/
|
*/
|
||||||
|
@ -2050,6 +2056,7 @@ public final class DtoFactory {
|
||||||
final DocumentedTypeDTO type = new DocumentedTypeDTO();
|
final DocumentedTypeDTO type = new DocumentedTypeDTO();
|
||||||
type.setType(cls.getName());
|
type.setType(cls.getName());
|
||||||
type.setDescription(getCapabilityDescription(cls));
|
type.setDescription(getCapabilityDescription(cls));
|
||||||
|
type.setUsageRestriction(getUsageRestriction(cls));
|
||||||
type.setTags(getTags(cls));
|
type.setTags(getTags(cls));
|
||||||
types.add(type);
|
types.add(type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -788,6 +788,7 @@ public class ControllerFacade implements Authorizable {
|
||||||
final List<Resource> resources = new ArrayList<>();
|
final List<Resource> resources = new ArrayList<>();
|
||||||
resources.add(ResourceFactory.getFlowResource());
|
resources.add(ResourceFactory.getFlowResource());
|
||||||
resources.add(ResourceFactory.getSystemResource());
|
resources.add(ResourceFactory.getSystemResource());
|
||||||
|
resources.add(ResourceFactory.getRestrictedComponentsResource());
|
||||||
resources.add(ResourceFactory.getControllerResource());
|
resources.add(ResourceFactory.getControllerResource());
|
||||||
resources.add(ResourceFactory.getCountersResource());
|
resources.add(ResourceFactory.getCountersResource());
|
||||||
resources.add(ResourceFactory.getProvenanceResource());
|
resources.add(ResourceFactory.getProvenanceResource());
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class AccessControlHelper {
|
||||||
private NiFiTestUser writeUser;
|
private NiFiTestUser writeUser;
|
||||||
private NiFiTestUser readWriteUser;
|
private NiFiTestUser readWriteUser;
|
||||||
private NiFiTestUser noneUser;
|
private NiFiTestUser noneUser;
|
||||||
|
private NiFiTestUser restrictedUser;
|
||||||
|
|
||||||
private static final String CONTEXT_PATH = "/nifi-api";
|
private static final String CONTEXT_PATH = "/nifi-api";
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ public class AccessControlHelper {
|
||||||
writeUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.WRITE_USER_DN);
|
writeUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.WRITE_USER_DN);
|
||||||
readWriteUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.READ_WRITE_USER_DN);
|
readWriteUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.READ_WRITE_USER_DN);
|
||||||
noneUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.NONE_USER_DN);
|
noneUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.NONE_USER_DN);
|
||||||
|
restrictedUser = new NiFiTestUser(server.getClient(), NiFiTestAuthorizer.RESTRICTED_USER_DN);
|
||||||
|
|
||||||
// populate the initial data flow
|
// populate the initial data flow
|
||||||
NiFiWebApiTest.populateFlow(server.getClient(), baseUrl, readWriteUser, READ_WRITE_CLIENT_ID);
|
NiFiWebApiTest.populateFlow(server.getClient(), baseUrl, readWriteUser, READ_WRITE_CLIENT_ID);
|
||||||
|
@ -99,6 +101,10 @@ public class AccessControlHelper {
|
||||||
return noneUser;
|
return noneUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public NiFiTestUser getRestrictedUser() {
|
||||||
|
return restrictedUser;
|
||||||
|
}
|
||||||
|
|
||||||
public void testGenericGetUri(final String uri) throws Exception {
|
public void testGenericGetUri(final String uri) throws Exception {
|
||||||
ClientResponse response;
|
ClientResponse response;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ package org.apache.nifi.integration.accesscontrol;
|
||||||
import com.sun.jersey.api.client.ClientResponse;
|
import com.sun.jersey.api.client.ClientResponse;
|
||||||
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
|
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
|
||||||
import org.apache.nifi.integration.util.NiFiTestUser;
|
import org.apache.nifi.integration.util.NiFiTestUser;
|
||||||
|
import org.apache.nifi.integration.util.RestrictedProcessor;
|
||||||
import org.apache.nifi.integration.util.SourceTestProcessor;
|
import org.apache.nifi.integration.util.SourceTestProcessor;
|
||||||
import org.apache.nifi.web.api.dto.ProcessorDTO;
|
import org.apache.nifi.web.api.dto.ProcessorDTO;
|
||||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||||
|
@ -399,6 +400,43 @@ public class ITProcessorAccessControl {
|
||||||
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
|
verifyDelete(helper.getNoneUser(), NONE_CLIENT_ID, 403);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests attempt to create a restricted processor.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCreateRestrictedProcessor() throws Exception {
|
||||||
|
String url = helper.getBaseUrl() + "/process-groups/root/processors";
|
||||||
|
|
||||||
|
// create the processor
|
||||||
|
ProcessorDTO processor = new ProcessorDTO();
|
||||||
|
processor.setName("restricted");
|
||||||
|
processor.setType(RestrictedProcessor.class.getName());
|
||||||
|
|
||||||
|
// create the revision
|
||||||
|
final RevisionDTO revision = new RevisionDTO();
|
||||||
|
revision.setClientId(READ_WRITE_CLIENT_ID);
|
||||||
|
revision.setVersion(0L);
|
||||||
|
|
||||||
|
// create the entity body
|
||||||
|
ProcessorEntity entity = new ProcessorEntity();
|
||||||
|
entity.setRevision(revision);
|
||||||
|
entity.setComponent(processor);
|
||||||
|
|
||||||
|
// perform the request as a user with read/write but no restricted access
|
||||||
|
ClientResponse response = helper.getReadWriteUser().testPost(url, entity);
|
||||||
|
|
||||||
|
// ensure the request is successful
|
||||||
|
assertEquals(403, response.getStatus());
|
||||||
|
|
||||||
|
// perform the request as a user with read/write and restricted access
|
||||||
|
response = helper.getRestrictedUser().testPost(url, entity);
|
||||||
|
|
||||||
|
// ensure the request is successful
|
||||||
|
assertEquals(201, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
private ProcessorEntity getRandomProcessor(final NiFiTestUser user) throws Exception {
|
private ProcessorEntity getRandomProcessor(final NiFiTestUser user) throws Exception {
|
||||||
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
|
final String url = helper.getBaseUrl() + "/flow/process-groups/root";
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ public class NiFiTestAuthorizer implements Authorizer {
|
||||||
public static final String READ_USER_DN = "read@nifi";
|
public static final String READ_USER_DN = "read@nifi";
|
||||||
public static final String WRITE_USER_DN = "write@nifi";
|
public static final String WRITE_USER_DN = "write@nifi";
|
||||||
public static final String READ_WRITE_USER_DN = "readwrite@nifi";
|
public static final String READ_WRITE_USER_DN = "readwrite@nifi";
|
||||||
|
public static final String RESTRICTED_USER_DN = "restricted@nifi";
|
||||||
|
|
||||||
public static final String TOKEN_USER = "user@nifi";
|
public static final String TOKEN_USER = "user@nifi";
|
||||||
|
|
||||||
|
@ -78,15 +79,24 @@ public class NiFiTestAuthorizer implements Authorizer {
|
||||||
return AuthorizationResult.approved();
|
return AuthorizationResult.approved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restricted component access
|
||||||
|
if (ResourceFactory.getRestrictedComponentsResource().getIdentifier().equals(request.getResource().getIdentifier())) {
|
||||||
|
if (RESTRICTED_USER_DN.equals(request.getIdentity())) {
|
||||||
|
return AuthorizationResult.approved();
|
||||||
|
} else {
|
||||||
|
return AuthorizationResult.denied();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// read access
|
// read access
|
||||||
if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
|
if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity()) || RESTRICTED_USER_DN.equals(request.getIdentity())) {
|
||||||
if (RequestAction.READ.equals(request.getAction())) {
|
if (RequestAction.READ.equals(request.getAction())) {
|
||||||
return AuthorizationResult.approved();
|
return AuthorizationResult.approved();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write access
|
// write access
|
||||||
if (WRITE_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
|
if (WRITE_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity()) || RESTRICTED_USER_DN.equals(request.getIdentity())) {
|
||||||
if (RequestAction.WRITE.equals(request.getAction())) {
|
if (RequestAction.WRITE.equals(request.getAction())) {
|
||||||
return AuthorizationResult.approved();
|
return AuthorizationResult.approved();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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.integration.util;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
|
import org.apache.nifi.processor.AbstractSessionFactoryProcessor;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||||
|
import org.apache.nifi.processor.ProcessorInitializationContext;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Restricted("")
|
||||||
|
public class RestrictedProcessor extends AbstractSessionFactoryProcessor {
|
||||||
|
|
||||||
|
public RestrictedProcessor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Relationship> getRelationships() {
|
||||||
|
final Set<Relationship> rels = new HashSet<>();
|
||||||
|
rels.add(new Relationship.Builder().name("success").build());
|
||||||
|
return rels;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory) throws ProcessException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init(final ProcessorInitializationContext context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -427,7 +427,13 @@ div.button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.button:hover {
|
div.button.disabled-button {
|
||||||
|
color: #a8a8a8 !important;
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.button:hover:not(.disabled-button) {
|
||||||
background-color: #004849;
|
background-color: #004849;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ div.policy-controls {
|
||||||
|
|
||||||
#policy-type-list {
|
#policy-type-list {
|
||||||
float: left;
|
float: left;
|
||||||
width: 190px;
|
width: 225px;
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
border-left: 1px solid transparent;
|
border-left: 1px solid transparent;
|
||||||
border-right: 1px solid transparent;
|
border-right: 1px solid transparent;
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
* hover: '#004849',
|
* hover: '#004849',
|
||||||
* text: '#ffffff'
|
* text: '#ffffff'
|
||||||
* },
|
* },
|
||||||
|
* disabled: isDisabledFunction,
|
||||||
* handler: {
|
* handler: {
|
||||||
* click: cancelHandler
|
* click: cancelHandler
|
||||||
* }
|
* }
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
* hover: '#C7D2D7',
|
* hover: '#C7D2D7',
|
||||||
* text: '#004849'
|
* text: '#004849'
|
||||||
* },
|
* },
|
||||||
|
* disabled: isDisabledFunction,
|
||||||
* handler: {
|
* handler: {
|
||||||
* click: applyHandler
|
* click: applyHandler
|
||||||
* }
|
* }
|
||||||
|
@ -101,27 +103,54 @@
|
||||||
var addButtons = function (dialog, buttonModel) {
|
var addButtons = function (dialog, buttonModel) {
|
||||||
if (isDefinedAndNotNull(buttonModel)) {
|
if (isDefinedAndNotNull(buttonModel)) {
|
||||||
var buttonWrapper = $('<div class="dialog-buttons"></div>');
|
var buttonWrapper = $('<div class="dialog-buttons"></div>');
|
||||||
var button;
|
|
||||||
$.each(buttonModel, function (i, buttonConfig) {
|
$.each(buttonModel, function (i, buttonConfig) {
|
||||||
var clazz = isDefinedAndNotNull(buttonConfig.clazz) ? buttonConfig.clazz : '';
|
var isDisabled = function () {
|
||||||
if (buttonConfig.color) {
|
return typeof buttonConfig.disabled === 'function' && buttonConfig.disabled.call() === true;
|
||||||
button = $('<div class="button ' + clazz + '" style="color:' + buttonConfig.color.text + '; background:' + buttonConfig.color.base + ';"><span>' + buttonConfig.buttonText + '</span></div>');
|
};
|
||||||
|
|
||||||
|
// create the button
|
||||||
|
var button = $('<div class="button"></div>').append($('<span></span>').text(buttonConfig.buttonText));
|
||||||
|
|
||||||
|
// add the class if specified
|
||||||
|
if (isDefinedAndNotNull(buttonConfig.clazz)) {
|
||||||
|
button.addClass(buttonConfig.clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the color if specified
|
||||||
|
if (isDefinedAndNotNull(buttonConfig.color)) {
|
||||||
|
button.css({
|
||||||
|
'background': buttonConfig.color.base,
|
||||||
|
'color': buttonConfig.color.text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the button should be disabled
|
||||||
|
if (isDisabled()) {
|
||||||
|
button.addClass('disabled-button');
|
||||||
|
} else {
|
||||||
|
// enable custom hover if specified
|
||||||
|
if (isDefinedAndNotNull(buttonConfig.color)) {
|
||||||
button.hover(function () {
|
button.hover(function () {
|
||||||
$(this).css("background-color", buttonConfig.color.hover);
|
$(this).css("background-color", buttonConfig.color.hover);
|
||||||
}, function () {
|
}, function () {
|
||||||
$(this).css("background-color", buttonConfig.color.base);
|
$(this).css("background-color", buttonConfig.color.base);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
button = $('<div class="button ' + clazz + '"><span>' + buttonConfig.buttonText + '</span></div>');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button.click(function () {
|
button.click(function () {
|
||||||
var handler = $(this).data('handler');
|
var handler = $(this).data('handler');
|
||||||
if (isDefinedAndNotNull(handler) && typeof handler.click === 'function') {
|
if (isDefinedAndNotNull(handler) && typeof handler.click === 'function') {
|
||||||
handler.click.call(dialog);
|
handler.click.call(dialog);
|
||||||
}
|
}
|
||||||
}).data('handler', buttonConfig.handler).appendTo(buttonWrapper);
|
|
||||||
});
|
});
|
||||||
buttonWrapper.appendTo(dialog);
|
}
|
||||||
|
|
||||||
|
// add the button to the wrapper
|
||||||
|
button.data('handler', buttonConfig.handler).appendTo(buttonWrapper);
|
||||||
|
});
|
||||||
|
|
||||||
|
// store the button model to refresh later
|
||||||
|
dialog.append(buttonWrapper).data('buttonModel', buttonModel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -258,6 +287,22 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refreshes the buttons with the existing model.
|
||||||
|
*/
|
||||||
|
refreshButtons: function () {
|
||||||
|
return this.each(function () {
|
||||||
|
var dialog = $(this);
|
||||||
|
var buttons = dialog.data('buttonModel');
|
||||||
|
|
||||||
|
// remove the current buttons
|
||||||
|
dialog.children('.dialog-buttons').remove();
|
||||||
|
|
||||||
|
// add the new buttons
|
||||||
|
addButtons(dialog, buttons);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the header text of the dialog.
|
* Sets the header text of the dialog.
|
||||||
*
|
*
|
||||||
|
|
|
@ -235,6 +235,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
}).fail(nf.Common.handleAjaxError);
|
}).fail(nf.Common.handleAjaxError);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the specified item is selectable.
|
||||||
|
*
|
||||||
|
* @param item process type
|
||||||
|
*/
|
||||||
|
var isSelectable = function (item) {
|
||||||
|
return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
|
||||||
|
};
|
||||||
|
|
||||||
function ProcessorComponent() {
|
function ProcessorComponent() {
|
||||||
|
|
||||||
this.icon = 'icon icon-processor';
|
this.icon = 'icon icon-processor';
|
||||||
|
@ -257,7 +266,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
init: function () {
|
init: function () {
|
||||||
// initialize the processor type table
|
// initialize the processor type table
|
||||||
var processorTypesColumns = [
|
var processorTypesColumns = [
|
||||||
{id: 'type', name: 'Type', field: 'label', sortable: true, resizable: true},
|
{id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: true, resizable: true},
|
||||||
{id: 'tags', name: 'Tags', field: 'tags', sortable: true, resizable: true}
|
{id: 'tags', name: 'Tags', field: 'tags', sortable: true, resizable: true}
|
||||||
];
|
];
|
||||||
var processorTypesOptions = {
|
var processorTypesOptions = {
|
||||||
|
@ -319,9 +328,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
$('#processor-type-name').text(processorType.label).ellipsis();
|
$('#processor-type-name').text(processorType.label).ellipsis();
|
||||||
$('#selected-processor-name').text(processorType.label);
|
$('#selected-processor-name').text(processorType.label);
|
||||||
$('#selected-processor-type').text(processorType.type);
|
$('#selected-processor-type').text(processorType.type);
|
||||||
|
|
||||||
|
// refresh the buttons based on the current selection
|
||||||
|
$('#new-processor-dialog').modal('refreshButtons');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
processorTypesGrid.onViewportChanged.subscribe(function (e, args) {
|
||||||
|
nf.Common.cleanUpTooltips($('#processor-types-table'), 'div.view-usage-restriction');
|
||||||
|
});
|
||||||
|
|
||||||
// wire up the dataview to the grid
|
// wire up the dataview to the grid
|
||||||
processorTypesData.onRowCountChanged.subscribe(function (e, args) {
|
processorTypesData.onRowCountChanged.subscribe(function (e, args) {
|
||||||
|
@ -338,7 +353,31 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
processorTypesData.syncGridSelection(processorTypesGrid, false);
|
processorTypesData.syncGridSelection(processorTypesGrid, false);
|
||||||
|
|
||||||
// hold onto an instance of the grid
|
// hold onto an instance of the grid
|
||||||
$('#processor-types-table').data('gridInstance', processorTypesGrid);
|
$('#processor-types-table').data('gridInstance', processorTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
|
||||||
|
var usageRestriction = $(this).find('div.view-usage-restriction');
|
||||||
|
if (usageRestriction.length && !usageRestriction.data('qtip')) {
|
||||||
|
var rowId = $(this).find('span.row-id').text();
|
||||||
|
|
||||||
|
// get the status item
|
||||||
|
var item = processorTypesData.getItemById(rowId);
|
||||||
|
|
||||||
|
// show the tooltip
|
||||||
|
if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
|
||||||
|
usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
|
||||||
|
content: item.usageRestriction,
|
||||||
|
position: {
|
||||||
|
container: $('#summary'),
|
||||||
|
at: 'bottom right',
|
||||||
|
my: 'top left',
|
||||||
|
adjust: {
|
||||||
|
x: 4,
|
||||||
|
y: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load the available processor types, this select is shown in the
|
// load the available processor types, this select is shown in the
|
||||||
// new processor dialog when a processor is dragged onto the screen
|
// new processor dialog when a processor is dragged onto the screen
|
||||||
|
@ -362,6 +401,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
label: nf.Common.substringAfterLast(type, '.'),
|
label: nf.Common.substringAfterLast(type, '.'),
|
||||||
type: type,
|
type: type,
|
||||||
description: nf.Common.escapeHtml(documentedType.description),
|
description: nf.Common.escapeHtml(documentedType.description),
|
||||||
|
usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
|
||||||
tags: documentedType.tags.join(', ')
|
tags: documentedType.tags.join(', ')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -497,6 +537,7 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
*/
|
*/
|
||||||
promptForProcessorType: function (pt) {
|
promptForProcessorType: function (pt) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
// handles adding the selected processor at the specified point
|
// handles adding the selected processor at the specified point
|
||||||
var addProcessor = function () {
|
var addProcessor = function () {
|
||||||
// get the type of processor currently selected
|
// get the type of processor currently selected
|
||||||
|
@ -525,10 +566,12 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
var gridDoubleClick = function (e, args) {
|
var gridDoubleClick = function (e, args) {
|
||||||
var processorType = grid.getDataItem(args.row);
|
var processorType = grid.getDataItem(args.row);
|
||||||
|
|
||||||
|
if (isSelectable(processorType)) {
|
||||||
$('#selected-processor-name').text(processorType.label);
|
$('#selected-processor-name').text(processorType.label);
|
||||||
$('#selected-processor-type').text(processorType.type);
|
$('#selected-processor-type').text(processorType.type);
|
||||||
|
|
||||||
addProcessor();
|
addProcessor();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// register a handler for double click events
|
// register a handler for double click events
|
||||||
|
@ -542,6 +585,17 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
hover: '#004849',
|
hover: '#004849',
|
||||||
text: '#ffffff'
|
text: '#ffffff'
|
||||||
},
|
},
|
||||||
|
disabled: function () {
|
||||||
|
var selected = grid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = grid.getDataItem(selected[0]);
|
||||||
|
return isSelectable(item) === false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
handler: {
|
handler: {
|
||||||
click: addProcessor
|
click: addProcessor
|
||||||
}
|
}
|
||||||
|
@ -576,7 +630,15 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
|
||||||
$('#processor-type-filter').focus().off('keyup').on('keyup', function (e) {
|
$('#processor-type-filter').focus().off('keyup').on('keyup', function (e) {
|
||||||
var code = e.keyCode ? e.keyCode : e.which;
|
var code = e.keyCode ? e.keyCode : e.which;
|
||||||
if (code === $.ui.keyCode.ENTER) {
|
if (code === $.ui.keyCode.ENTER) {
|
||||||
|
var selected = grid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = grid.getDataItem(selected[0]);
|
||||||
|
if (isSelectable(item)) {
|
||||||
addProcessor();
|
addProcessor();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
applyFilter();
|
applyFilter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,15 @@ nf.ControllerServices = (function () {
|
||||||
rowHeight: 24
|
rowHeight: 24
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the specified item is selectable.
|
||||||
|
*
|
||||||
|
* @param item controller service type
|
||||||
|
*/
|
||||||
|
var isSelectable = function (item) {
|
||||||
|
return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the text out of the filter field. If the filter field doesn't
|
* Get the text out of the filter field. If the filter field doesn't
|
||||||
* have any text it will contain the text 'filter list' so this method
|
* have any text it will contain the text 'filter list' so this method
|
||||||
|
@ -254,7 +263,7 @@ nf.ControllerServices = (function () {
|
||||||
var initNewControllerServiceDialog = function () {
|
var initNewControllerServiceDialog = function () {
|
||||||
// initialize the processor type table
|
// initialize the processor type table
|
||||||
var controllerServiceTypesColumns = [
|
var controllerServiceTypesColumns = [
|
||||||
{id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true},
|
{id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: false, resizable: true},
|
||||||
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
|
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -298,9 +307,15 @@ nf.ControllerServices = (function () {
|
||||||
$('#controller-service-type-name').text(controllerServiceType.label).ellipsis();
|
$('#controller-service-type-name').text(controllerServiceType.label).ellipsis();
|
||||||
$('#selected-controller-service-name').text(controllerServiceType.label);
|
$('#selected-controller-service-name').text(controllerServiceType.label);
|
||||||
$('#selected-controller-service-type').text(controllerServiceType.type);
|
$('#selected-controller-service-type').text(controllerServiceType.type);
|
||||||
|
|
||||||
|
// refresh the buttons based on the current selection
|
||||||
|
$('#new-controller-service-dialog').modal('refreshButtons');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
controllerServiceTypesGrid.onViewportChanged.subscribe(function (e, args) {
|
||||||
|
nf.Common.cleanUpTooltips($('#controller-service-types-table'), 'div.view-usage-restriction');
|
||||||
|
});
|
||||||
|
|
||||||
// wire up the dataview to the grid
|
// wire up the dataview to the grid
|
||||||
controllerServiceTypesData.onRowCountChanged.subscribe(function (e, args) {
|
controllerServiceTypesData.onRowCountChanged.subscribe(function (e, args) {
|
||||||
|
@ -317,7 +332,31 @@ nf.ControllerServices = (function () {
|
||||||
controllerServiceTypesData.syncGridSelection(controllerServiceTypesGrid, true);
|
controllerServiceTypesData.syncGridSelection(controllerServiceTypesGrid, true);
|
||||||
|
|
||||||
// hold onto an instance of the grid
|
// hold onto an instance of the grid
|
||||||
$('#controller-service-types-table').data('gridInstance', controllerServiceTypesGrid);
|
$('#controller-service-types-table').data('gridInstance', controllerServiceTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
|
||||||
|
var usageRestriction = $(this).find('div.view-usage-restriction');
|
||||||
|
if (usageRestriction.length && !usageRestriction.data('qtip')) {
|
||||||
|
var rowId = $(this).find('span.row-id').text();
|
||||||
|
|
||||||
|
// get the status item
|
||||||
|
var item = controllerServiceTypesData.getItemById(rowId);
|
||||||
|
|
||||||
|
// show the tooltip
|
||||||
|
if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
|
||||||
|
usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
|
||||||
|
content: item.usageRestriction,
|
||||||
|
position: {
|
||||||
|
container: $('#summary'),
|
||||||
|
at: 'bottom right',
|
||||||
|
my: 'top left',
|
||||||
|
adjust: {
|
||||||
|
x: 4,
|
||||||
|
y: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load the available controller services
|
// load the available controller services
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -339,6 +378,7 @@ nf.ControllerServices = (function () {
|
||||||
label: nf.Common.substringAfterLast(documentedType.type, '.'),
|
label: nf.Common.substringAfterLast(documentedType.type, '.'),
|
||||||
type: documentedType.type,
|
type: documentedType.type,
|
||||||
description: nf.Common.escapeHtml(documentedType.description),
|
description: nf.Common.escapeHtml(documentedType.description),
|
||||||
|
usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
|
||||||
tags: documentedType.tags.join(', ')
|
tags: documentedType.tags.join(', ')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -831,11 +871,22 @@ nf.ControllerServices = (function () {
|
||||||
* @param {jQuery} serviceTable
|
* @param {jQuery} serviceTable
|
||||||
*/
|
*/
|
||||||
promptNewControllerService: function (controllerServicesUri, serviceTable) {
|
promptNewControllerService: function (controllerServicesUri, serviceTable) {
|
||||||
|
// get the grid reference
|
||||||
|
var grid = $('#controller-service-types-table').data('gridInstance');
|
||||||
|
|
||||||
// update the keyhandler
|
// update the keyhandler
|
||||||
$('#controller-service-type-filter').off('keyup').on('keyup', function (e) {
|
$('#controller-service-type-filter').off('keyup').on('keyup', function (e) {
|
||||||
var code = e.keyCode ? e.keyCode : e.which;
|
var code = e.keyCode ? e.keyCode : e.which;
|
||||||
if (code === $.ui.keyCode.ENTER) {
|
if (code === $.ui.keyCode.ENTER) {
|
||||||
|
var selected = grid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = grid.getDataItem(selected[0]);
|
||||||
|
if (isSelectable(item)) {
|
||||||
addSelectedControllerService(controllerServicesUri, serviceTable);
|
addSelectedControllerService(controllerServicesUri, serviceTable);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
applyControllerServiceTypeFilter();
|
applyControllerServiceTypeFilter();
|
||||||
}
|
}
|
||||||
|
@ -849,6 +900,17 @@ nf.ControllerServices = (function () {
|
||||||
hover: '#004849',
|
hover: '#004849',
|
||||||
text: '#ffffff'
|
text: '#ffffff'
|
||||||
},
|
},
|
||||||
|
disabled: function () {
|
||||||
|
var selected = grid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = grid.getDataItem(selected[0]);
|
||||||
|
return isSelectable(item) === false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
handler: {
|
handler: {
|
||||||
click: function () {
|
click: function () {
|
||||||
addSelectedControllerService(controllerServicesUri, serviceTable);
|
addSelectedControllerService(controllerServicesUri, serviceTable);
|
||||||
|
@ -878,7 +940,10 @@ nf.ControllerServices = (function () {
|
||||||
// update the dbl click handler and subsrcibe
|
// update the dbl click handler and subsrcibe
|
||||||
dblClick = function(e, args) {
|
dblClick = function(e, args) {
|
||||||
var controllerServiceType = controllerServiceTypesGrid.getDataItem(args.row);
|
var controllerServiceType = controllerServiceTypesGrid.getDataItem(args.row);
|
||||||
|
|
||||||
|
if (isSelectable(controllerServiceType)) {
|
||||||
addControllerService(controllerServicesUri, serviceTable, controllerServiceType.type);
|
addControllerService(controllerServicesUri, serviceTable, controllerServiceType.type);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
controllerServiceTypesGrid.onDblClick.subscribe(dblClick);
|
controllerServiceTypesGrid.onDblClick.subscribe(dblClick);
|
||||||
|
|
||||||
|
|
|
@ -343,6 +343,7 @@ nf.PolicyManagement = (function () {
|
||||||
nf.Common.getPolicyTypeListing('flow'),
|
nf.Common.getPolicyTypeListing('flow'),
|
||||||
nf.Common.getPolicyTypeListing('controller'),
|
nf.Common.getPolicyTypeListing('controller'),
|
||||||
nf.Common.getPolicyTypeListing('provenance'),
|
nf.Common.getPolicyTypeListing('provenance'),
|
||||||
|
nf.Common.getPolicyTypeListing('restricted-components'),
|
||||||
nf.Common.getPolicyTypeListing('policies'),
|
nf.Common.getPolicyTypeListing('policies'),
|
||||||
nf.Common.getPolicyTypeListing('tenants'),
|
nf.Common.getPolicyTypeListing('tenants'),
|
||||||
nf.Common.getPolicyTypeListing('site-to-site'),
|
nf.Common.getPolicyTypeListing('site-to-site'),
|
||||||
|
@ -364,7 +365,7 @@ nf.PolicyManagement = (function () {
|
||||||
$('#controller-policy-target').hide();
|
$('#controller-policy-target').hide();
|
||||||
|
|
||||||
// record the action
|
// record the action
|
||||||
if (option.value === 'proxy') {
|
if (option.value === 'proxy' || option.value === 'restricted-components') {
|
||||||
$('#selected-policy-action').text('write');
|
$('#selected-policy-action').text('write');
|
||||||
} else {
|
} else {
|
||||||
$('#selected-policy-action').text('read');
|
$('#selected-policy-action').text('read');
|
||||||
|
@ -1398,7 +1399,7 @@ nf.PolicyManagement = (function () {
|
||||||
|
|
||||||
if (policyType === 'controller') {
|
if (policyType === 'controller') {
|
||||||
$('#selected-policy-action').text($('#controller-policy-target').combo('getSelectedOption').value);
|
$('#selected-policy-action').text($('#controller-policy-target').combo('getSelectedOption').value);
|
||||||
} else if (policyType === 'proxy') {
|
} else if (policyType === 'proxy' || policyType === 'restricted-components') {
|
||||||
$('#selected-policy-action').text('write');
|
$('#selected-policy-action').text('write');
|
||||||
} else {
|
} else {
|
||||||
$('#selected-policy-action').text('read');
|
$('#selected-policy-action').text('read');
|
||||||
|
|
|
@ -155,6 +155,15 @@ nf.Settings = (function () {
|
||||||
return matches;
|
return matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the specified item is selectable.
|
||||||
|
*
|
||||||
|
* @param item reporting task type
|
||||||
|
*/
|
||||||
|
var isSelectable = function (item) {
|
||||||
|
return nf.Common.isBlank(item.usageRestriction) || nf.Common.canAccessRestrictedComponents();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formatter for the name column.
|
* Formatter for the name column.
|
||||||
*
|
*
|
||||||
|
@ -406,7 +415,17 @@ nf.Settings = (function () {
|
||||||
$('#reporting-task-type-filter').on('keyup', function (e) {
|
$('#reporting-task-type-filter').on('keyup', function (e) {
|
||||||
var code = e.keyCode ? e.keyCode : e.which;
|
var code = e.keyCode ? e.keyCode : e.which;
|
||||||
if (code === $.ui.keyCode.ENTER) {
|
if (code === $.ui.keyCode.ENTER) {
|
||||||
|
// get the grid reference
|
||||||
|
var grid = $('#reporting-task-types-table').data('gridInstance');
|
||||||
|
var selected = grid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = grid.getDataItem(selected[0]);
|
||||||
|
if (isSelectable(item)) {
|
||||||
addSelectedReportingTask();
|
addSelectedReportingTask();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
applyReportingTaskTypeFilter();
|
applyReportingTaskTypeFilter();
|
||||||
}
|
}
|
||||||
|
@ -414,7 +433,7 @@ nf.Settings = (function () {
|
||||||
|
|
||||||
// initialize the processor type table
|
// initialize the processor type table
|
||||||
var reportingTaskTypesColumns = [
|
var reportingTaskTypesColumns = [
|
||||||
{id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true},
|
{id: 'type', name: 'Type', field: 'label', formatter: nf.Common.typeFormatter, sortable: false, resizable: true},
|
||||||
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
|
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -458,12 +477,21 @@ nf.Settings = (function () {
|
||||||
$('#reporting-task-type-name').text(reportingTaskType.label).ellipsis();
|
$('#reporting-task-type-name').text(reportingTaskType.label).ellipsis();
|
||||||
$('#selected-reporting-task-name').text(reportingTaskType.label);
|
$('#selected-reporting-task-name').text(reportingTaskType.label);
|
||||||
$('#selected-reporting-task-type').text(reportingTaskType.type);
|
$('#selected-reporting-task-type').text(reportingTaskType.type);
|
||||||
|
|
||||||
|
// refresh the buttons based on the current selection
|
||||||
|
$('#new-reporting-task-dialog').modal('refreshButtons');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
reportingTaskTypesGrid.onDblClick.subscribe(function (e, args) {
|
reportingTaskTypesGrid.onDblClick.subscribe(function (e, args) {
|
||||||
var reportingTaskType = reportingTaskTypesGrid.getDataItem(args.row);
|
var reportingTaskType = reportingTaskTypesGrid.getDataItem(args.row);
|
||||||
|
|
||||||
|
if (isSelectable(reportingTaskType)) {
|
||||||
addReportingTask(reportingTaskType.type);
|
addReportingTask(reportingTaskType.type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
reportingTaskTypesGrid.onViewportChanged.subscribe(function (e, args) {
|
||||||
|
nf.Common.cleanUpTooltips($('#reporting-task-types-table'), 'div.view-usage-restriction');
|
||||||
});
|
});
|
||||||
|
|
||||||
// wire up the dataview to the grid
|
// wire up the dataview to the grid
|
||||||
|
@ -481,7 +509,31 @@ nf.Settings = (function () {
|
||||||
reportingTaskTypesData.syncGridSelection(reportingTaskTypesGrid, true);
|
reportingTaskTypesData.syncGridSelection(reportingTaskTypesGrid, true);
|
||||||
|
|
||||||
// hold onto an instance of the grid
|
// hold onto an instance of the grid
|
||||||
$('#reporting-task-types-table').data('gridInstance', reportingTaskTypesGrid);
|
$('#reporting-task-types-table').data('gridInstance', reportingTaskTypesGrid).on('mouseenter', 'div.slick-cell', function (e) {
|
||||||
|
var usageRestriction = $(this).find('div.view-usage-restriction');
|
||||||
|
if (usageRestriction.length && !usageRestriction.data('qtip')) {
|
||||||
|
var rowId = $(this).find('span.row-id').text();
|
||||||
|
|
||||||
|
// get the status item
|
||||||
|
var item = reportingTaskTypesData.getItemById(rowId);
|
||||||
|
|
||||||
|
// show the tooltip
|
||||||
|
if (nf.Common.isDefinedAndNotNull(item.usageRestriction)) {
|
||||||
|
usageRestriction.qtip($.extend({}, nf.Common.config.tooltipConfig, {
|
||||||
|
content: item.usageRestriction,
|
||||||
|
position: {
|
||||||
|
container: $('#summary'),
|
||||||
|
at: 'bottom right',
|
||||||
|
my: 'top left',
|
||||||
|
adjust: {
|
||||||
|
x: 4,
|
||||||
|
y: 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// load the available reporting tasks
|
// load the available reporting tasks
|
||||||
$.ajax({
|
$.ajax({
|
||||||
|
@ -503,6 +555,7 @@ nf.Settings = (function () {
|
||||||
label: nf.Common.substringAfterLast(documentedType.type, '.'),
|
label: nf.Common.substringAfterLast(documentedType.type, '.'),
|
||||||
type: documentedType.type,
|
type: documentedType.type,
|
||||||
description: nf.Common.escapeHtml(documentedType.description),
|
description: nf.Common.escapeHtml(documentedType.description),
|
||||||
|
usageRestriction: nf.Common.escapeHtml(documentedType.usageRestriction),
|
||||||
tags: documentedType.tags.join(', ')
|
tags: documentedType.tags.join(', ')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -537,6 +590,17 @@ nf.Settings = (function () {
|
||||||
hover: '#004849',
|
hover: '#004849',
|
||||||
text: '#ffffff'
|
text: '#ffffff'
|
||||||
},
|
},
|
||||||
|
disabled: function () {
|
||||||
|
var selected = reportingTaskTypesGrid.getSelectedRows();
|
||||||
|
|
||||||
|
if (selected.length > 0) {
|
||||||
|
// grid configured with multi-select = false
|
||||||
|
var item = reportingTaskTypesGrid.getDataItem(selected[0]);
|
||||||
|
return isSelectable(item) === false;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
handler: {
|
handler: {
|
||||||
click: function () {
|
click: function () {
|
||||||
addSelectedReportingTask();
|
addSelectedReportingTask();
|
||||||
|
|
|
@ -90,6 +90,10 @@ nf.Common = (function () {
|
||||||
text: 'query provenance',
|
text: 'query provenance',
|
||||||
value: 'provenance',
|
value: 'provenance',
|
||||||
description: 'Allows users to submit a Provenance Search and request Event Lineage'
|
description: 'Allows users to submit a Provenance Search and request Event Lineage'
|
||||||
|
}, {
|
||||||
|
text: 'access restricted components',
|
||||||
|
value: 'restricted-components',
|
||||||
|
description: 'Allows users to create/modify restricted components assuming otherwise sufficient permissions'
|
||||||
}, {
|
}, {
|
||||||
text: 'access all policies',
|
text: 'access all policies',
|
||||||
value: 'policies',
|
value: 'policies',
|
||||||
|
@ -156,6 +160,32 @@ nf.Common = (function () {
|
||||||
*/
|
*/
|
||||||
currentUser: undefined,
|
currentUser: undefined,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats type of a component for a new instance dialog.
|
||||||
|
*
|
||||||
|
* @param row
|
||||||
|
* @param cell
|
||||||
|
* @param value
|
||||||
|
* @param columnDef
|
||||||
|
* @param dataContext
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
typeFormatter: function (row, cell, value, columnDef, dataContext) {
|
||||||
|
var markup = '';
|
||||||
|
|
||||||
|
// restriction
|
||||||
|
if (nf.Common.isBlank(dataContext.usageRestriction) === false) {
|
||||||
|
markup += '<div class="view-usage-restriction fa fa-shield"></div><span class="hidden row-id">' + nf.Common.escapeHtml(dataContext.id) + '</span>';
|
||||||
|
} else {
|
||||||
|
markup += '<div class="fa"></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// type
|
||||||
|
markup += value;
|
||||||
|
|
||||||
|
return markup;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current user.
|
* Sets the current user.
|
||||||
*
|
*
|
||||||
|
@ -271,6 +301,19 @@ nf.Common = (function () {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the current user can access restricted comopnents.
|
||||||
|
*
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
canAccessRestrictedComponents: function () {
|
||||||
|
if (nf.Common.isDefinedAndNotNull(nf.Common.currentUser)) {
|
||||||
|
return nf.Common.currentUser.restrictedComponentsPermissions.canWrite === true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the current user can access counters.
|
* Determines whether the current user can access counters.
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,20 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.hadoop;
|
package org.apache.nifi.processors.hadoop;
|
||||||
|
|
||||||
import java.io.IOException;
|
import com.google.common.collect.Lists;
|
||||||
import java.util.ArrayList;
|
import com.google.common.collect.Maps;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import org.apache.hadoop.fs.FileStatus;
|
import org.apache.hadoop.fs.FileStatus;
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
import org.apache.hadoop.fs.FileSystem;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -41,8 +34,15 @@ import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import java.io.IOException;
|
||||||
import com.google.common.collect.Maps;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@TriggerWhenEmpty
|
@TriggerWhenEmpty
|
||||||
@InputRequirement(InputRequirement.Requirement.INPUT_ALLOWED)
|
@InputRequirement(InputRequirement.Requirement.INPUT_ALLOWED)
|
||||||
|
@ -51,6 +51,7 @@ import com.google.common.collect.Maps;
|
||||||
+ "or a statically set file that is periodically removed. If this processor has an incoming connection, it"
|
+ "or a statically set file that is periodically removed. If this processor has an incoming connection, it"
|
||||||
+ "will ignore running on a periodic basis and instead rely on incoming FlowFiles to trigger a delete. "
|
+ "will ignore running on a periodic basis and instead rely on incoming FlowFiles to trigger a delete. "
|
||||||
+ "Optionally, you may specify use a wildcard character to match multiple files or directories.")
|
+ "Optionally, you may specify use a wildcard character to match multiple files or directories.")
|
||||||
|
@Restricted("Provides operator the ability to delete any file that NiFi has access to in HDFS or the local filesystem.")
|
||||||
public class DeleteHDFS extends AbstractHadoopProcessor {
|
public class DeleteHDFS extends AbstractHadoopProcessor {
|
||||||
public static final Relationship REL_SUCCESS = new Relationship.Builder()
|
public static final Relationship REL_SUCCESS = new Relationship.Builder()
|
||||||
.name("success")
|
.name("success")
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.hadoop.io.compress.CompressionCodecFactory;
|
||||||
import org.apache.hadoop.security.AccessControlException;
|
import org.apache.hadoop.security.AccessControlException;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
@ -59,6 +60,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
@WritesAttribute(attribute="hdfs.failure.reason", description="When a FlowFile is routed to 'failure', this attribute is added indicating why the file could "
|
@WritesAttribute(attribute="hdfs.failure.reason", description="When a FlowFile is routed to 'failure', this attribute is added indicating why the file could "
|
||||||
+ "not be fetched from HDFS")
|
+ "not be fetched from HDFS")
|
||||||
@SeeAlso({ListHDFS.class, GetHDFS.class, PutHDFS.class})
|
@SeeAlso({ListHDFS.class, GetHDFS.class, PutHDFS.class})
|
||||||
|
@Restricted("Provides operator the ability to retrieve any file that NiFi has access to in HDFS or the local filesystem.")
|
||||||
public class FetchHDFS extends AbstractHadoopProcessor {
|
public class FetchHDFS extends AbstractHadoopProcessor {
|
||||||
|
|
||||||
static final PropertyDescriptor FILENAME = new PropertyDescriptor.Builder()
|
static final PropertyDescriptor FILENAME = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -27,6 +27,7 @@ import org.apache.hadoop.io.compress.CompressionCodec;
|
||||||
import org.apache.hadoop.io.compress.CompressionCodecFactory;
|
import org.apache.hadoop.io.compress.CompressionCodecFactory;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
@ -73,6 +74,7 @@ import java.util.regex.Pattern;
|
||||||
+ "is set to /tmp, then files picked up from /tmp will have the path attribute set to \"./\". If the Recurse Subdirectories property is set to true and "
|
+ "is set to /tmp, then files picked up from /tmp will have the path attribute set to \"./\". If the Recurse Subdirectories property is set to true and "
|
||||||
+ "a file is picked up from /tmp/abc/1/2/3, then the path attribute will be set to \"abc/1/2/3\".") })
|
+ "a file is picked up from /tmp/abc/1/2/3, then the path attribute will be set to \"abc/1/2/3\".") })
|
||||||
@SeeAlso({PutHDFS.class, ListHDFS.class})
|
@SeeAlso({PutHDFS.class, ListHDFS.class})
|
||||||
|
@Restricted("Provides operator the ability to retrieve and delete any file that NiFi has access to in HDFS or the local filesystem.")
|
||||||
public class GetHDFS extends AbstractHadoopProcessor {
|
public class GetHDFS extends AbstractHadoopProcessor {
|
||||||
|
|
||||||
public static final String BUFFER_SIZE_KEY = "io.file.buffer.size";
|
public static final String BUFFER_SIZE_KEY = "io.file.buffer.size";
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
@ -75,6 +76,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
@WritesAttribute(attribute = "absolute.hdfs.path", description = "The absolute path to the file on HDFS is stored in this attribute.")
|
@WritesAttribute(attribute = "absolute.hdfs.path", description = "The absolute path to the file on HDFS is stored in this attribute.")
|
||||||
})
|
})
|
||||||
@SeeAlso(GetHDFS.class)
|
@SeeAlso(GetHDFS.class)
|
||||||
|
@Restricted("Provides operator the ability to write to any file that NiFi has access to in HDFS or the local filesystem.")
|
||||||
public class PutHDFS extends AbstractHadoopProcessor {
|
public class PutHDFS extends AbstractHadoopProcessor {
|
||||||
|
|
||||||
public static final String REPLACE_RESOLUTION = "replace";
|
public static final String REPLACE_RESOLUTION = "replace";
|
||||||
|
|
|
@ -16,25 +16,14 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.script;
|
package org.apache.nifi.processors.script;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.script.Bindings;
|
|
||||||
import javax.script.ScriptContext;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
import javax.script.SimpleBindings;
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.logging.ComponentLog;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.logging.ComponentLog;
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
import org.apache.nifi.processor.ProcessSessionFactory;
|
import org.apache.nifi.processor.ProcessSessionFactory;
|
||||||
|
@ -43,6 +32,19 @@ import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
import org.apache.nifi.util.StringUtils;
|
import org.apache.nifi.util.StringUtils;
|
||||||
|
|
||||||
|
import javax.script.Bindings;
|
||||||
|
import javax.script.ScriptContext;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import javax.script.SimpleBindings;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Tags({"script", "execute", "groovy", "python", "jython", "jruby", "ruby", "javascript", "js", "lua", "luaj"})
|
@Tags({"script", "execute", "groovy", "python", "jython", "jruby", "ruby", "javascript", "js", "lua", "luaj"})
|
||||||
@CapabilityDescription("Experimental - Executes a script given the flow file and a process session. The script is responsible for "
|
@CapabilityDescription("Experimental - Executes a script given the flow file and a process session. The script is responsible for "
|
||||||
+ "handling the incoming flow file (transfer to SUCCESS or remove, e.g.) as well as any flow files created by "
|
+ "handling the incoming flow file (transfer to SUCCESS or remove, e.g.) as well as any flow files created by "
|
||||||
|
@ -54,6 +56,7 @@ import org.apache.nifi.util.StringUtils;
|
||||||
supportsExpressionLanguage = true,
|
supportsExpressionLanguage = true,
|
||||||
description = "Updates a script engine property specified by the Dynamic Property's key with the value "
|
description = "Updates a script engine property specified by the Dynamic Property's key with the value "
|
||||||
+ "specified by the Dynamic Property's value")
|
+ "specified by the Dynamic Property's value")
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary code assuming all permissions that NiFi has.")
|
||||||
public class ExecuteScript extends AbstractScriptProcessor {
|
public class ExecuteScript extends AbstractScriptProcessor {
|
||||||
|
|
||||||
private String scriptToRun = null;
|
private String scriptToRun = null;
|
||||||
|
|
|
@ -16,24 +16,10 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.script;
|
package org.apache.nifi.processors.script;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import javax.script.Invocable;
|
|
||||||
import javax.script.ScriptEngine;
|
|
||||||
import javax.script.ScriptException;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -53,6 +39,20 @@ import org.apache.nifi.processor.Relationship;
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
|
import javax.script.Invocable;
|
||||||
|
import javax.script.ScriptEngine;
|
||||||
|
import javax.script.ScriptException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
@Tags({"script", "invoke", "groovy", "python", "jython", "jruby", "ruby", "javascript", "js", "lua", "luaj"})
|
@Tags({"script", "invoke", "groovy", "python", "jython", "jruby", "ruby", "javascript", "js", "lua", "luaj"})
|
||||||
@CapabilityDescription("Experimental - Invokes a script engine for a Processor defined in the given script. The script must define "
|
@CapabilityDescription("Experimental - Invokes a script engine for a Processor defined in the given script. The script must define "
|
||||||
+ "a valid class that implements the Processor interface, and it must set a variable 'processor' to an instance of "
|
+ "a valid class that implements the Processor interface, and it must set a variable 'processor' to an instance of "
|
||||||
|
@ -62,6 +62,7 @@ import org.apache.nifi.processor.util.StandardValidators;
|
||||||
@DynamicProperty(name = "A script engine property to update", value = "The value to set it to", supportsExpressionLanguage = true,
|
@DynamicProperty(name = "A script engine property to update", value = "The value to set it to", supportsExpressionLanguage = true,
|
||||||
description = "Updates a script engine property specified by the Dynamic Property's key with the value specified by the Dynamic Property's value")
|
description = "Updates a script engine property specified by the Dynamic Property's key with the value specified by the Dynamic Property's value")
|
||||||
@SeeAlso({ExecuteScript.class})
|
@SeeAlso({ExecuteScript.class})
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary code assuming all permissions that NiFi has.")
|
||||||
public class InvokeScriptedProcessor extends AbstractScriptProcessor {
|
public class InvokeScriptedProcessor extends AbstractScriptProcessor {
|
||||||
|
|
||||||
private final AtomicReference<Processor> processor = new AtomicReference<>();
|
private final AtomicReference<Processor> processor = new AtomicReference<>();
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
package org.apache.nifi.reporting;
|
package org.apache.nifi.reporting;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -58,6 +59,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
@Tags({"provenance", "lineage", "tracking", "site", "site to site"})
|
@Tags({"provenance", "lineage", "tracking", "site", "site to site"})
|
||||||
@CapabilityDescription("Publishes Provenance events using the Site To Site protocol.")
|
@CapabilityDescription("Publishes Provenance events using the Site To Site protocol.")
|
||||||
@Stateful(scopes = Scope.LOCAL, description = "Stores the Reporting Task's last event Id so that on restart the task knows where it left off.")
|
@Stateful(scopes = Scope.LOCAL, description = "Stores the Reporting Task's last event Id so that on restart the task knows where it left off.")
|
||||||
|
@Restricted("Provides operator the ability send sensitive details contained in Provenance events to any external system.")
|
||||||
public class SiteToSiteProvenanceReportingTask extends AbstractSiteToSiteReportingTask {
|
public class SiteToSiteProvenanceReportingTask extends AbstractSiteToSiteReportingTask {
|
||||||
|
|
||||||
static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
static final String TIMESTAMP_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
|
||||||
|
|
|
@ -16,6 +16,28 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnUnscheduled;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.components.Validator;
|
||||||
|
import org.apache.nifi.flowfile.FlowFile;
|
||||||
|
import org.apache.nifi.logging.ComponentLog;
|
||||||
|
import org.apache.nifi.processor.AbstractProcessor;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
import org.apache.nifi.processor.io.OutputStreamCallback;
|
||||||
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
import org.apache.nifi.processors.standard.util.ArgumentUtils;
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
@ -41,33 +63,13 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnUnscheduled;
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.components.Validator;
|
|
||||||
import org.apache.nifi.flowfile.FlowFile;
|
|
||||||
import org.apache.nifi.logging.ComponentLog;
|
|
||||||
import org.apache.nifi.processor.AbstractProcessor;
|
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
|
||||||
import org.apache.nifi.processor.Relationship;
|
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
|
||||||
import org.apache.nifi.processor.io.OutputStreamCallback;
|
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
|
||||||
import org.apache.nifi.processors.standard.util.ArgumentUtils;
|
|
||||||
|
|
||||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||||
@Tags({"command", "process", "source", "external", "invoke", "script"})
|
@Tags({"command", "process", "source", "external", "invoke", "script"})
|
||||||
@CapabilityDescription("Runs an operating system command specified by the user and writes the output of that command to a FlowFile. If the command is expected "
|
@CapabilityDescription("Runs an operating system command specified by the user and writes the output of that command to a FlowFile. If the command is expected "
|
||||||
+ "to be long-running, the Processor can output the partial data on a specified interval. When this option is used, the output is expected to be in textual "
|
+ "to be long-running, the Processor can output the partial data on a specified interval. When this option is used, the output is expected to be in textual "
|
||||||
+ "format, as it typically does not make sense to split binary data on arbitrary time-based intervals.")
|
+ "format, as it typically does not make sense to split binary data on arbitrary time-based intervals.")
|
||||||
@DynamicProperty(name = "An environment variable name", value = "An environment variable value", description = "These environment variables are passed to the process spawned by this Processor")
|
@DynamicProperty(name = "An environment variable name", value = "An environment variable value", description = "These environment variables are passed to the process spawned by this Processor")
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary code assuming all permissions that NiFi has.")
|
||||||
public class ExecuteProcess extends AbstractProcessor {
|
public class ExecuteProcess extends AbstractProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor COMMAND = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor COMMAND = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -16,28 +16,13 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.lang.ProcessBuilder.Redirect;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
import org.apache.nifi.annotation.behavior.DynamicProperty;
|
||||||
import org.apache.nifi.annotation.behavior.EventDriven;
|
import org.apache.nifi.annotation.behavior.EventDriven;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
@ -65,6 +50,22 @@ import org.apache.nifi.stream.io.BufferedInputStream;
|
||||||
import org.apache.nifi.stream.io.BufferedOutputStream;
|
import org.apache.nifi.stream.io.BufferedOutputStream;
|
||||||
import org.apache.nifi.stream.io.StreamUtils;
|
import org.apache.nifi.stream.io.StreamUtils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.lang.ProcessBuilder.Redirect;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* This processor executes an external command on the contents of a flow file, and creates a new flow file with the results of the command.
|
* This processor executes an external command on the contents of a flow file, and creates a new flow file with the results of the command.
|
||||||
|
@ -132,6 +133,7 @@ import org.apache.nifi.stream.io.StreamUtils;
|
||||||
@WritesAttribute(attribute = "execution.command.args", description = "The semi-colon delimited list of arguments"),
|
@WritesAttribute(attribute = "execution.command.args", description = "The semi-colon delimited list of arguments"),
|
||||||
@WritesAttribute(attribute = "execution.status", description = "The exit status code returned from executing the command"),
|
@WritesAttribute(attribute = "execution.status", description = "The exit status code returned from executing the command"),
|
||||||
@WritesAttribute(attribute = "execution.error", description = "Any error messages returned from executing the command")})
|
@WritesAttribute(attribute = "execution.error", description = "Any error messages returned from executing the command")})
|
||||||
|
@Restricted("Provides operator the ability to execute arbitrary code assuming all permissions that NiFi has.")
|
||||||
public class ExecuteStreamCommand extends AbstractProcessor {
|
public class ExecuteStreamCommand extends AbstractProcessor {
|
||||||
|
|
||||||
public static final Relationship ORIGINAL_RELATIONSHIP = new Relationship.Builder()
|
public static final Relationship ORIGINAL_RELATIONSHIP = new Relationship.Builder()
|
||||||
|
|
|
@ -17,24 +17,10 @@
|
||||||
|
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.file.CopyOption;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.StandardCopyOption;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
@ -52,11 +38,27 @@ import org.apache.nifi.processor.exception.ProcessException;
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
import org.apache.nifi.util.StopWatch;
|
import org.apache.nifi.util.StopWatch;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.CopyOption;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@InputRequirement(Requirement.INPUT_REQUIRED)
|
@InputRequirement(Requirement.INPUT_REQUIRED)
|
||||||
@Tags({"local", "files", "filesystem", "ingest", "ingress", "get", "source", "input"})
|
@Tags({"local", "files", "filesystem", "ingest", "ingress", "get", "source", "input"})
|
||||||
@CapabilityDescription("Reads the contents of a file from disk and streams it into the contents of an incoming FlowFile. Once this is done, the file is optionally moved elsewhere or deleted "
|
@CapabilityDescription("Reads the contents of a file from disk and streams it into the contents of an incoming FlowFile. Once this is done, the file is optionally moved elsewhere or deleted "
|
||||||
+ "to help keep the file system organized.")
|
+ "to help keep the file system organized.")
|
||||||
@SeeAlso({GetFile.class, PutFile.class, ListFile.class})
|
@SeeAlso({GetFile.class, PutFile.class, ListFile.class})
|
||||||
|
@Restricted("Provides operator the ability to read from and delete any file that NiFi has access to.")
|
||||||
public class FetchFile extends AbstractProcessor {
|
public class FetchFile extends AbstractProcessor {
|
||||||
static final AllowableValue COMPLETION_NONE = new AllowableValue("None", "None", "Leave the file as-is");
|
static final AllowableValue COMPLETION_NONE = new AllowableValue("None", "None", "Leave the file as-is");
|
||||||
static final AllowableValue COMPLETION_MOVE = new AllowableValue("Move File", "Move File", "Moves the file to the directory specified by the <Move Destination Directory> property");
|
static final AllowableValue COMPLETION_MOVE = new AllowableValue("Move File", "Move File", "Moves the file to the directory specified by the <Move Destination Directory> property");
|
||||||
|
|
|
@ -16,6 +16,29 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
|
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.flowfile.FlowFile;
|
||||||
|
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||||
|
import org.apache.nifi.logging.ComponentLog;
|
||||||
|
import org.apache.nifi.processor.AbstractProcessor;
|
||||||
|
import org.apache.nifi.processor.DataUnit;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
|
import org.apache.nifi.processor.ProcessorInitializationContext;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -48,27 +71,6 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.TriggerWhenEmpty;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.flowfile.FlowFile;
|
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
|
||||||
import org.apache.nifi.logging.ComponentLog;
|
|
||||||
import org.apache.nifi.processor.AbstractProcessor;
|
|
||||||
import org.apache.nifi.processor.DataUnit;
|
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
|
||||||
import org.apache.nifi.processor.ProcessorInitializationContext;
|
|
||||||
import org.apache.nifi.processor.Relationship;
|
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
|
||||||
|
|
||||||
@TriggerWhenEmpty
|
@TriggerWhenEmpty
|
||||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||||
|
@ -91,6 +93,7 @@ import org.apache.nifi.processor.util.StandardValidators;
|
||||||
@WritesAttribute(attribute = "absolute.path", description = "The full/absolute path from where a file was picked up. The current 'path' "
|
@WritesAttribute(attribute = "absolute.path", description = "The full/absolute path from where a file was picked up. The current 'path' "
|
||||||
+ "attribute is still populated, but may be a relative path")})
|
+ "attribute is still populated, but may be a relative path")})
|
||||||
@SeeAlso({PutFile.class, FetchFile.class})
|
@SeeAlso({PutFile.class, FetchFile.class})
|
||||||
|
@Restricted("Provides operator the ability to read from and delete any file that NiFi has access to.")
|
||||||
public class GetFile extends AbstractProcessor {
|
public class GetFile extends AbstractProcessor {
|
||||||
|
|
||||||
public static final PropertyDescriptor DIRECTORY = new PropertyDescriptor.Builder()
|
public static final PropertyDescriptor DIRECTORY = new PropertyDescriptor.Builder()
|
||||||
|
|
|
@ -17,6 +17,27 @@
|
||||||
|
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
|
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||||
|
import org.apache.nifi.components.AllowableValue;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.components.state.Scope;
|
||||||
|
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||||
|
import org.apache.nifi.processor.DataUnit;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessorInitializationContext;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
import org.apache.nifi.processors.standard.util.FileInfo;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -44,27 +65,6 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
|
||||||
import org.apache.nifi.components.AllowableValue;
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.components.state.Scope;
|
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
|
||||||
import org.apache.nifi.processor.DataUnit;
|
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
|
||||||
import org.apache.nifi.processor.ProcessorInitializationContext;
|
|
||||||
import org.apache.nifi.processor.Relationship;
|
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
|
||||||
import org.apache.nifi.processors.standard.util.FileInfo;
|
|
||||||
|
|
||||||
@TriggerSerially
|
@TriggerSerially
|
||||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||||
@Tags({"file", "get", "list", "ingest", "source", "filesystem"})
|
@Tags({"file", "get", "list", "ingest", "source", "filesystem"})
|
||||||
|
|
|
@ -16,6 +16,27 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
|
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
||||||
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
import org.apache.nifi.annotation.documentation.SeeAlso;
|
||||||
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.flowfile.FlowFile;
|
||||||
|
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||||
|
import org.apache.nifi.logging.ComponentLog;
|
||||||
|
import org.apache.nifi.processor.AbstractProcessor;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
|
import org.apache.nifi.processor.ProcessorInitializationContext;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
import org.apache.nifi.util.StopWatch;
|
||||||
|
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
@ -34,32 +55,13 @@ import java.util.Set;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.ReadsAttribute;
|
|
||||||
import org.apache.nifi.annotation.behavior.SupportsBatching;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
|
||||||
import org.apache.nifi.annotation.documentation.SeeAlso;
|
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.flowfile.FlowFile;
|
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
|
||||||
import org.apache.nifi.logging.ComponentLog;
|
|
||||||
import org.apache.nifi.processor.AbstractProcessor;
|
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
|
||||||
import org.apache.nifi.processor.ProcessorInitializationContext;
|
|
||||||
import org.apache.nifi.processor.Relationship;
|
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
|
||||||
import org.apache.nifi.util.StopWatch;
|
|
||||||
|
|
||||||
@SupportsBatching
|
@SupportsBatching
|
||||||
@InputRequirement(Requirement.INPUT_REQUIRED)
|
@InputRequirement(Requirement.INPUT_REQUIRED)
|
||||||
@Tags({"put", "local", "copy", "archive", "files", "filesystem"})
|
@Tags({"put", "local", "copy", "archive", "files", "filesystem"})
|
||||||
@CapabilityDescription("Writes the contents of a FlowFile to the local file system")
|
@CapabilityDescription("Writes the contents of a FlowFile to the local file system")
|
||||||
@SeeAlso({FetchFile.class, GetFile.class})
|
@SeeAlso({FetchFile.class, GetFile.class})
|
||||||
@ReadsAttribute(attribute = "filename", description = "The filename to use when writing the FlowFile to disk.")
|
@ReadsAttribute(attribute = "filename", description = "The filename to use when writing the FlowFile to disk.")
|
||||||
|
@Restricted("Provides operator the ability to write to any file that NiFi has access to.")
|
||||||
public class PutFile extends AbstractProcessor {
|
public class PutFile extends AbstractProcessor {
|
||||||
|
|
||||||
public static final String REPLACE_RESOLUTION = "replace";
|
public static final String REPLACE_RESOLUTION = "replace";
|
||||||
|
|
|
@ -16,6 +16,38 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.nifi.processors.standard;
|
package org.apache.nifi.processors.standard;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
||||||
|
import org.apache.nifi.annotation.behavior.Restricted;
|
||||||
|
import org.apache.nifi.annotation.behavior.Stateful;
|
||||||
|
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
||||||
|
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
||||||
|
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
||||||
|
import org.apache.nifi.annotation.documentation.Tags;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
||||||
|
import org.apache.nifi.annotation.lifecycle.OnStopped;
|
||||||
|
import org.apache.nifi.components.AllowableValue;
|
||||||
|
import org.apache.nifi.components.PropertyDescriptor;
|
||||||
|
import org.apache.nifi.components.ValidationContext;
|
||||||
|
import org.apache.nifi.components.ValidationResult;
|
||||||
|
import org.apache.nifi.components.state.Scope;
|
||||||
|
import org.apache.nifi.components.state.StateMap;
|
||||||
|
import org.apache.nifi.flowfile.FlowFile;
|
||||||
|
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
||||||
|
import org.apache.nifi.processor.AbstractProcessor;
|
||||||
|
import org.apache.nifi.processor.ProcessContext;
|
||||||
|
import org.apache.nifi.processor.ProcessSession;
|
||||||
|
import org.apache.nifi.processor.Relationship;
|
||||||
|
import org.apache.nifi.processor.exception.ProcessException;
|
||||||
|
import org.apache.nifi.processor.io.OutputStreamCallback;
|
||||||
|
import org.apache.nifi.processor.util.StandardValidators;
|
||||||
|
import org.apache.nifi.stream.io.ByteArrayOutputStream;
|
||||||
|
import org.apache.nifi.stream.io.NullOutputStream;
|
||||||
|
import org.apache.nifi.stream.io.StreamUtils;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -45,37 +77,6 @@ import java.util.zip.CRC32;
|
||||||
import java.util.zip.CheckedInputStream;
|
import java.util.zip.CheckedInputStream;
|
||||||
import java.util.zip.Checksum;
|
import java.util.zip.Checksum;
|
||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.InputRequirement.Requirement;
|
|
||||||
import org.apache.nifi.annotation.behavior.Stateful;
|
|
||||||
import org.apache.nifi.annotation.behavior.TriggerSerially;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttribute;
|
|
||||||
import org.apache.nifi.annotation.behavior.WritesAttributes;
|
|
||||||
import org.apache.nifi.annotation.documentation.CapabilityDescription;
|
|
||||||
import org.apache.nifi.annotation.documentation.Tags;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnScheduled;
|
|
||||||
import org.apache.nifi.annotation.lifecycle.OnStopped;
|
|
||||||
import org.apache.nifi.components.AllowableValue;
|
|
||||||
import org.apache.nifi.components.PropertyDescriptor;
|
|
||||||
import org.apache.nifi.components.ValidationContext;
|
|
||||||
import org.apache.nifi.components.ValidationResult;
|
|
||||||
import org.apache.nifi.components.state.Scope;
|
|
||||||
import org.apache.nifi.components.state.StateMap;
|
|
||||||
import org.apache.nifi.flowfile.FlowFile;
|
|
||||||
import org.apache.nifi.flowfile.attributes.CoreAttributes;
|
|
||||||
import org.apache.nifi.processor.AbstractProcessor;
|
|
||||||
import org.apache.nifi.processor.ProcessContext;
|
|
||||||
import org.apache.nifi.processor.ProcessSession;
|
|
||||||
import org.apache.nifi.processor.Relationship;
|
|
||||||
import org.apache.nifi.processor.exception.ProcessException;
|
|
||||||
import org.apache.nifi.processor.io.OutputStreamCallback;
|
|
||||||
import org.apache.nifi.processor.util.StandardValidators;
|
|
||||||
import org.apache.nifi.stream.io.ByteArrayOutputStream;
|
|
||||||
import org.apache.nifi.stream.io.NullOutputStream;
|
|
||||||
import org.apache.nifi.stream.io.StreamUtils;
|
|
||||||
|
|
||||||
// note: it is important that this Processor is not marked as @SupportsBatching because the session commits must complete before persisting state locally; otherwise, data loss may occur
|
// note: it is important that this Processor is not marked as @SupportsBatching because the session commits must complete before persisting state locally; otherwise, data loss may occur
|
||||||
@TriggerSerially
|
@TriggerSerially
|
||||||
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
@InputRequirement(Requirement.INPUT_FORBIDDEN)
|
||||||
|
@ -91,6 +92,7 @@ import org.apache.nifi.stream.io.StreamUtils;
|
||||||
@WritesAttributes({
|
@WritesAttributes({
|
||||||
@WritesAttribute(attribute = "tailfile.original.path", description = "Path of the original file the flow file comes from.")
|
@WritesAttribute(attribute = "tailfile.original.path", description = "Path of the original file the flow file comes from.")
|
||||||
})
|
})
|
||||||
|
@Restricted("Provides operator the ability to read from any file that NiFi has access to.")
|
||||||
public class TailFile extends AbstractProcessor {
|
public class TailFile extends AbstractProcessor {
|
||||||
|
|
||||||
static final String MAP_PREFIX = "file.";
|
static final String MAP_PREFIX = "file.";
|
||||||
|
|
Loading…
Reference in New Issue