/* * 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.processor; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.nifi.attribute.expression.language.PreparedQuery; import org.apache.nifi.attribute.expression.language.Query; import org.apache.nifi.attribute.expression.language.StandardPropertyValue; import org.apache.nifi.attribute.expression.language.Query.Range; import org.apache.nifi.components.PropertyDescriptor; import org.apache.nifi.components.PropertyValue; import org.apache.nifi.components.state.StateManager; import org.apache.nifi.connectable.Connection; import org.apache.nifi.controller.ControllerService; import org.apache.nifi.controller.ControllerServiceLookup; import org.apache.nifi.controller.ProcessorNode; import org.apache.nifi.controller.service.ControllerServiceProvider; import org.apache.nifi.encrypt.StringEncryptor; import org.apache.nifi.registry.VariableRegistry; import org.apache.nifi.util.Connectables; public class StandardProcessContext implements ProcessContext, ControllerServiceLookup { private final ProcessorNode procNode; private final ControllerServiceProvider controllerServiceProvider; private final Map<PropertyDescriptor, PreparedQuery> preparedQueries; private final StringEncryptor encryptor; private final StateManager stateManager; private final VariableRegistry variableRegistry; public StandardProcessContext(final ProcessorNode processorNode, final ControllerServiceProvider controllerServiceProvider, final StringEncryptor encryptor, final StateManager stateManager, final VariableRegistry variableRegistry) { this.procNode = processorNode; this.controllerServiceProvider = controllerServiceProvider; this.encryptor = encryptor; this.stateManager = stateManager; this.variableRegistry = variableRegistry; preparedQueries = new HashMap<>(); for (final Map.Entry<PropertyDescriptor, String> entry : procNode.getProperties().entrySet()) { final PropertyDescriptor desc = entry.getKey(); String value = entry.getValue(); if (value == null) { value = desc.getDefaultValue(); } if (value != null) { final PreparedQuery pq = Query.prepare(value); preparedQueries.put(desc, pq); } } } @Override public PropertyValue getProperty(final PropertyDescriptor descriptor) { return getProperty(descriptor.getName()); } /** * <p> * Returns the currently configured value for the property with the given name. * </p> */ @Override public PropertyValue getProperty(final String propertyName) { final Processor processor = procNode.getProcessor(); final PropertyDescriptor descriptor = processor.getPropertyDescriptor(propertyName); if (descriptor == null) { return null; } final String setPropertyValue = procNode.getProperty(descriptor); final String propValue = (setPropertyValue == null) ? descriptor.getDefaultValue() : setPropertyValue; return new StandardPropertyValue(propValue, this, preparedQueries.get(descriptor), variableRegistry); } @Override public PropertyValue newPropertyValue(final String rawValue) { return new StandardPropertyValue(rawValue, this, Query.prepare(rawValue), variableRegistry); } @Override public void yield() { procNode.yield(); } @Override public ControllerService getControllerService(final String serviceIdentifier) { return controllerServiceProvider.getControllerServiceForComponent(serviceIdentifier, procNode.getIdentifier()); } @Override public int getMaxConcurrentTasks() { return procNode.getMaxConcurrentTasks(); } @Override public String getAnnotationData() { return procNode.getAnnotationData(); } @Override public Map<PropertyDescriptor, String> getProperties() { return procNode.getProperties(); } @Override public String encrypt(final String unencrypted) { return encryptor.encrypt(unencrypted); } @Override public String decrypt(final String encrypted) { return encryptor.decrypt(encrypted); } @Override public Set<String> getControllerServiceIdentifiers(final Class<? extends ControllerService> serviceType) { if (!serviceType.isInterface()) { throw new IllegalArgumentException("ControllerServices may be referenced only via their interfaces; " + serviceType + " is not an interface"); } return controllerServiceProvider.getControllerServiceIdentifiers(serviceType, procNode.getProcessGroup().getIdentifier()); } @Override public boolean isControllerServiceEnabled(final ControllerService service) { return controllerServiceProvider.isControllerServiceEnabled(service); } @Override public boolean isControllerServiceEnabled(final String serviceIdentifier) { return controllerServiceProvider.isControllerServiceEnabled(serviceIdentifier); } @Override public boolean isControllerServiceEnabling(final String serviceIdentifier) { return controllerServiceProvider.isControllerServiceEnabling(serviceIdentifier); } @Override public ControllerServiceLookup getControllerServiceLookup() { return this; } @Override public Set<Relationship> getAvailableRelationships() { final Set<Relationship> set = new HashSet<>(); for (final Relationship relationship : procNode.getRelationships()) { final Collection<Connection> connections = procNode.getConnections(relationship); if (connections.isEmpty()) { set.add(relationship); } else { boolean available = true; for (final Connection connection : connections) { if (connection.getFlowFileQueue().isFull()) { available = false; } } if (available) { set.add(relationship); } } } return set; } @Override public String getControllerServiceName(final String serviceIdentifier) { return controllerServiceProvider.getControllerServiceName(serviceIdentifier); } @Override public boolean hasIncomingConnection() { return procNode.hasIncomingConnection(); } @Override public boolean hasNonLoopConnection() { return Connectables.hasNonLoopConnection(procNode); } @Override public boolean hasConnection(final Relationship relationship) { final Set<Connection> connections = procNode.getConnections(relationship); return connections != null && !connections.isEmpty(); } @Override public boolean isExpressionLanguagePresent(final PropertyDescriptor property) { if (property == null || !property.isExpressionLanguageSupported()) { return false; } final List<Range> elRanges = Query.extractExpressionRanges(getProperty(property).getValue()); return (elRanges != null && !elRanges.isEmpty()); } @Override public StateManager getStateManager() { return stateManager; } @Override public String getName() { return procNode.getName(); } }