blob: 9ffd80a652649728335cbb7d6c299c0d286e8473 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.controller;
import org.apache.nifi.parameter.ParameterLookup;
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.Authorizable;
import org.apache.nifi.authorization.resource.ComponentAuthorizable;
import org.apache.nifi.authorization.resource.RestrictedComponentsAuthorizableFactory;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.bundle.BundleCoordinate;
import org.apache.nifi.components.ConfigurableComponent;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.ValidationContext;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.components.validation.ValidationState;
import org.apache.nifi.components.validation.ValidationStatus;
import org.apache.nifi.parameter.ParameterContext;
import org.apache.nifi.parameter.ParameterUpdate;
import org.apache.nifi.registry.ComponentVariableRegistry;
import java.net.URL;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public interface ComponentNode extends ComponentAuthorizable {
@Override
public String getIdentifier();
public String getName();
public void setName(String name);
public String getAnnotationData();
public void setAnnotationData(String data);
public default void setProperties(Map<String, String> properties) {
setProperties(properties, false);
}
public void setProperties(Map<String, String> properties, boolean allowRemovalOfRequiredProperties);
void verifyCanUpdateProperties(final Map<String, String> properties);
/**
* @return the Set of names of all Parameters that are referenced by this component
*/
Set<String> getReferencedParameterNames();
boolean isReferencingParameter();
/**
* Notifies the Component that the value of a parameter has changed
* @param parameterUpdates a Map of Parameter name to a ParameterUpdate that describes how the Parameter changed
*/
void onParametersModified(Map<String, ParameterUpdate> parameterUpdates);
/**
* @return the Set of all attributes that are explicitly referenced by Expression Language used in the property values
*/
Set<String> getReferencedAttributeNames();
/**
* <p>
* Pause triggering asynchronous validation to occur when the component is updated. Often times, it is necessary
* to update several aspects of a component, such as the properties and annotation data, at once. When this occurs,
* we don't want to trigger validation for each update, so we can follow the pattern:
* </p>
*
* <pre>
* <code>
* componentNode.pauseValidationTrigger();
* try {
* componentNode.setProperties(properties);
* componentNode.setAnnotationData(annotationData);
* } finally {
* componentNode.resumeValidationTrigger();
* }
* </code>
* </pre>
*
* <p>
* When calling this method, it is imperative that {@link #resumeValidationTrigger()} is always called within a {@code finally} block to
* ensure that validation occurs.
* </p>
*/
void pauseValidationTrigger();
/**
* Resume triggering asynchronous validation to occur when the component is updated. This method is to be used in conjunction
* with {@link #pauseValidationTrigger()} as illustrated in its documentation. When this method is called, if the component's Validation Status
* is {@link ValidationStatus#VALIDATING}, component validation will immediately be triggered asynchronously.
*/
void resumeValidationTrigger();
Map<PropertyDescriptor, String> getRawPropertyValues();
Map<PropertyDescriptor, String> getEffectivePropertyValues();
PropertyConfiguration getProperty(PropertyDescriptor property);
String getEffectivePropertyValue(PropertyDescriptor property);
String getRawPropertyValue(PropertyDescriptor property);
Map<PropertyDescriptor, PropertyConfiguration> getProperties();
void reload(Set<URL> additionalUrls) throws Exception;
void refreshProperties();
Set<URL> getAdditionalClasspathResources(List<PropertyDescriptor> propertyDescriptors);
BundleCoordinate getBundleCoordinate();
ConfigurableComponent getComponent();
TerminationAwareLogger getLogger();
boolean isExtensionMissing();
void setExtensionMissing(boolean extensionMissing);
void verifyCanUpdateBundle(BundleCoordinate bundleCoordinate) throws IllegalStateException;
void reloadAdditionalResourcesIfNecessary();
void resetValidationState();
/**
* @return the any validation errors for this connectable
*/
Collection<ValidationResult> getValidationErrors();
/**
* @return the type of the component. I.e., the class name of the implementation
*/
String getComponentType();
/**
* @return the class of the underlying
*/
Class<?> getComponentClass();
/**
* @return the Canonical Class Name of the component
*/
String getCanonicalClassName();
/**
* @return whether or not the underlying implementation has any restrictions
*/
boolean isRestricted();
/**
* @return whether or not the underlying implementation is deprecated
*/
boolean isDeprecated();
/**
* Indicates whether or not validation should be run on the component, based on its current state.
*
* @return <code>true</code> if the component needs validation, <code>false</code> otherwise
*/
boolean isValidationNecessary();
/**
* @return the variable registry for this component
*/
ComponentVariableRegistry getVariableRegistry();
/**
* Returns the processor's current Validation Status
*
* @return the processor's current Validation Status
*/
public abstract ValidationStatus getValidationStatus();
/**
* Returns the processor's Validation Status, waiting up to the given amount of time for the Validation to complete
* if it is currently in the process of validating. If the processor is currently in the process of validation and
* the validation logic does not complete in the given amount of time, or if the thread is interrupted, then a Validation Status
* of {@link ValidationStatus#VALIDATING VALIDATING} will be returned.
*
* @param timeout the max amount of time to wait
* @param unit the time unit
* @return the ValidationStatus
*/
public abstract ValidationStatus getValidationStatus(long timeout, TimeUnit unit);
/**
* Validates the component against the current configuration
*/
ValidationStatus performValidation();
/**
* Validates the component against the given ValidationContext
* @param validationContext the validation context to validate against
* @return the ValidationState that is the result of validating against the given context
*/
ValidationState performValidation(ValidationContext validationContext);
/**
* Performs validation against the given set of properties, annotation data, and parameters
* @param properties the processor configuration
* @param annotationData the annotation data
* @param parameterContext the set of parameters
* @return the validation state that results from validating against the given values
*/
ValidationState performValidation(Map<PropertyDescriptor, PropertyConfiguration> properties, String annotationData, ParameterContext parameterContext);
/**
* Returns a {@link List} of all {@link PropertyDescriptor}s that this
* component supports.
*
* @return PropertyDescriptor objects this component currently supports
*/
List<PropertyDescriptor> getPropertyDescriptors();
/**
* @param name to lookup the descriptor
* @return the PropertyDescriptor with the given name, if it exists;
* otherwise, returns <code>null</code>
*/
PropertyDescriptor getPropertyDescriptor(String name);
@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 Set<Authorizable> restrictedComponentsAuthorizables = RestrictedComponentsAuthorizableFactory.getRestrictedComponentsAuthorizable(getComponentClass());
for (final Authorizable restrictedComponentsAuthorizable : restrictedComponentsAuthorizables) {
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 Set<Authorizable> restrictedComponentsAuthorizables = RestrictedComponentsAuthorizableFactory.getRestrictedComponentsAuthorizable(getComponentClass());
for (final Authorizable restrictedComponentsAuthorizable : restrictedComponentsAuthorizables) {
restrictedComponentsAuthorizable.authorize(authorizer, RequestAction.WRITE, user, resourceContext);
}
}
// defer to the base authorization check
ComponentAuthorizable.super.authorize(authorizer, action, user, resourceContext);
}
ParameterLookup getParameterLookup();
}