This is an automated email from the ASF dual-hosted git repository. mcgilman pushed a commit to branch NIFI-15326 in repository https://gitbox.apache.org/repos/asf/nifi.git
commit 24cd6283be1d38c4c9eacdd25be15c0477d85650 Author: Matt Gilman <[email protected]> AuthorDate: Thu Dec 11 09:16:07 2025 -0500 NIFI-15326: Adding support of configuration step documentation. NIFI-15322: Adapting to new connector configuration step model. --- .../connectors/kafkas3/KafkaConnectionStep.java | 32 ++++++++ .../api/dto/ConfigurationStepConfigurationDTO.java | 13 +++ .../org/apache/nifi/audit/ConnectorAuditor.java | 94 ++++++++-------------- .../org/apache/nifi/web/NiFiServiceFacade.java | 5 +- .../apache/nifi/web/StandardNiFiServiceFacade.java | 8 +- .../org/apache/nifi/web/api/ConnectorResource.java | 5 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 29 ++++--- .../org/apache/nifi/web/api/dto/EntityFactory.java | 3 +- .../java/org/apache/nifi/web/dao/ConnectorDAO.java | 5 +- .../nifi/web/dao/impl/StandardConnectorDAO.java | 53 +++++------- .../web/dao/impl/StandardConnectorDAOTest.java | 27 +++---- 11 files changed, 137 insertions(+), 137 deletions(-) diff --git a/nifi-connectors/nifi-kafka-to-s3-bundle/nifi-kafka-to-s3-connector/src/main/java/org/apache/nifi/connectors/kafkas3/KafkaConnectionStep.java b/nifi-connectors/nifi-kafka-to-s3-bundle/nifi-kafka-to-s3-connector/src/main/java/org/apache/nifi/connectors/kafkas3/KafkaConnectionStep.java index 793b1e9be0d..22ae253a98f 100644 --- a/nifi-connectors/nifi-kafka-to-s3-bundle/nifi-kafka-to-s3-connector/src/main/java/org/apache/nifi/connectors/kafkas3/KafkaConnectionStep.java +++ b/nifi-connectors/nifi-kafka-to-s3-bundle/nifi-kafka-to-s3-connector/src/main/java/org/apache/nifi/connectors/kafkas3/KafkaConnectionStep.java @@ -29,6 +29,37 @@ import java.util.List; public class KafkaConnectionStep { public static final String STEP_NAME = "Kafka Connection"; + // Temporary documentation to verify the inline documentation feature in the UI. + // In practice, this content should probably be loaded from an external file. + private static final String KAFKA_CONNECTION_DOCUMENTATION = """ + # Kafka Connection Configuration + + This step configures the connection to your Apache Kafka cluster. + + ## Kafka Server Settings + + Enter the bootstrap servers for your Kafka cluster. You can specify multiple brokers + as a comma-separated list (e.g., `broker1:9092,broker2:9092,broker3:9092`). + + ### Security Configuration + + Select the appropriate security protocol based on your Kafka cluster configuration: + + | Protocol | Description | + |----------|-------------| + | PLAINTEXT | No encryption or authentication | + | SSL | TLS encryption without SASL authentication | + | SASL_PLAINTEXT | SASL authentication without encryption | + | SASL_SSL | Both SASL authentication and TLS encryption (recommended) | + + If using SASL authentication, provide your username and password credentials. + + ## Schema Registry (Optional) + + If your Kafka topics use Avro, Protobuf, or JSON Schema, configure the Schema Registry + URL to enable schema-based serialization and deserialization. + """; + public static final ConnectorPropertyDescriptor KAFKA_BROKERS = new ConnectorPropertyDescriptor.Builder() .name("Kafka Brokers") .description("A comma-separated list of Kafka brokers to connect to.") @@ -127,6 +158,7 @@ public class KafkaConnectionStep { public static final ConfigurationStep KAFKA_CONNECTION_STEP = new ConfigurationStep.Builder() .name(STEP_NAME) .description("Configure Kafka connection settings") + .documentation(KAFKA_CONNECTION_DOCUMENTATION) .propertyGroups(List.of( KAFKA_SERVER_GROUP, SCHEMA_REGISTRY_GROUP diff --git a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConfigurationStepConfigurationDTO.java b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConfigurationStepConfigurationDTO.java index 9dd55b524c1..94b0c7ff710 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConfigurationStepConfigurationDTO.java +++ b/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ConfigurationStepConfigurationDTO.java @@ -29,6 +29,7 @@ public class ConfigurationStepConfigurationDTO { private String configurationStepName; private String configurationStepDescription; + private String configurationStepDocumentation; private List<PropertyGroupConfigurationDTO> propertyGroupConfigurations; /** @@ -55,6 +56,18 @@ public class ConfigurationStepConfigurationDTO { this.configurationStepDescription = configurationStepDescription; } + /** + * @return the configuration step documentation in markdown + */ + @Schema(description = "Extended documentation or help text for the configuration step.") + public String getConfigurationStepDocumentation() { + return configurationStepDocumentation; + } + + public void setConfigurationStepDocumentation(final String configurationStepDocumentation) { + this.configurationStepDocumentation = configurationStepDocumentation; + } + /** * @return the property group configurations */ diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ConnectorAuditor.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ConnectorAuditor.java index 18785143dcf..e26e0d2aa3b 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ConnectorAuditor.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ConnectorAuditor.java @@ -24,13 +24,13 @@ import org.apache.nifi.action.component.details.FlowChangeExtensionDetails; import org.apache.nifi.action.details.ActionDetails; import org.apache.nifi.action.details.FlowChangeConfigureDetails; import org.apache.nifi.components.connector.AssetReference; -import org.apache.nifi.components.connector.ConfigurationStepConfiguration; import org.apache.nifi.components.connector.ConnectorConfiguration; import org.apache.nifi.components.connector.ConnectorNode; import org.apache.nifi.components.connector.ConnectorState; import org.apache.nifi.components.connector.ConnectorValueReference; -import org.apache.nifi.components.connector.PropertyGroupConfiguration; +import org.apache.nifi.components.connector.NamedStepConfiguration; import org.apache.nifi.components.connector.SecretReference; +import org.apache.nifi.components.connector.StepConfiguration; import org.apache.nifi.components.connector.StringLiteralValue; import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; import org.apache.nifi.web.api.dto.ConnectorValueReferenceDTO; @@ -224,17 +224,14 @@ public class ConnectorAuditor extends NiFiAuditor { final ConfigurationStepConfigurationDTO configurationStepConfiguration, final ConnectorDAO connectorDAO) throws Throwable { final ConnectorNode connector = connectorDAO.getConnector(connectorId); - // Capture the current property values before the update - final Map<String, Map<String, String>> previousValues = extractCurrentPropertyValues(connector, configurationStepName); + // Capture the current property values before the update (flat map: property name -> value) + final Map<String, String> previousValues = extractCurrentPropertyValues(connector, configurationStepName); proceedingJoinPoint.proceed(); if (isAuditable()) { - // Extract the new property values from the DTO - final Map<String, Map<String, String>> newValues = extractPropertyValuesFromDto(configurationStepConfiguration); - - // Generate audit actions for each changed property - final List<Action> actions = generateConfigurationChangeActions(connector, configurationStepName, previousValues, newValues); + // Generate audit actions for each changed property, using the DTO for group structure + final List<Action> actions = generateConfigurationChangeActions(connector, configurationStepName, previousValues, configurationStepConfiguration); if (!actions.isEmpty()) { saveActions(actions, logger); } @@ -246,23 +243,17 @@ public class ConnectorAuditor extends NiFiAuditor { * * @param connector the connector node * @param configurationStepName the name of the configuration step - * @return a map of property group name to property name to property value + * @return a map of property name to property value */ - private Map<String, Map<String, String>> extractCurrentPropertyValues(final ConnectorNode connector, final String configurationStepName) { - final Map<String, Map<String, String>> result = new HashMap<>(); + private Map<String, String> extractCurrentPropertyValues(final ConnectorNode connector, final String configurationStepName) { + final Map<String, String> result = new HashMap<>(); final ConnectorConfiguration configuration = connector.getWorkingFlowContext().getConfigurationContext().toConnectorConfiguration(); - for (final ConfigurationStepConfiguration stepConfig : configuration.getConfigurationStepConfigurations()) { - if (Objects.equals(stepConfig.stepName(), configurationStepName)) { - for (final PropertyGroupConfiguration groupConfig : stepConfig.propertyGroupConfigurations()) { - final String groupName = groupConfig.groupName(); - final Map<String, String> propertyValues = new HashMap<>(); - - for (final Map.Entry<String, ConnectorValueReference> entry : groupConfig.propertyValues().entrySet()) { - propertyValues.put(entry.getKey(), formatValueReference(entry.getValue())); - } - - result.put(groupName, propertyValues); + for (final NamedStepConfiguration namedStepConfig : configuration.getNamedStepConfigurations()) { + if (Objects.equals(namedStepConfig.stepName(), configurationStepName)) { + final StepConfiguration stepConfig = namedStepConfig.configuration(); + for (final Map.Entry<String, ConnectorValueReference> entry : stepConfig.getPropertyValues().entrySet()) { + result.put(entry.getKey(), formatValueReference(entry.getValue())); } break; } @@ -271,33 +262,6 @@ public class ConnectorAuditor extends NiFiAuditor { return result; } - /** - * Extracts property values from the configuration step DTO. - * - * @param configurationStepDto the configuration step DTO - * @return a map of property group name to property name to property value - */ - private Map<String, Map<String, String>> extractPropertyValuesFromDto(final ConfigurationStepConfigurationDTO configurationStepDto) { - final Map<String, Map<String, String>> result = new HashMap<>(); - - if (configurationStepDto.getPropertyGroupConfigurations() != null) { - for (final PropertyGroupConfigurationDTO groupDto : configurationStepDto.getPropertyGroupConfigurations()) { - final String groupName = groupDto.getPropertyGroupName(); - final Map<String, String> propertyValues = new HashMap<>(); - - if (groupDto.getPropertyValues() != null) { - for (final Map.Entry<String, ConnectorValueReferenceDTO> entry : groupDto.getPropertyValues().entrySet()) { - propertyValues.put(entry.getKey(), formatValueReferenceDto(entry.getValue())); - } - } - - result.put(groupName, propertyValues); - } - } - - return result; - } - /** * Formats a ConnectorValueReference as a string for audit logging. * @@ -340,33 +304,39 @@ public class ConnectorAuditor extends NiFiAuditor { } /** - * Generates audit actions for configuration changes by comparing previous and new values. + * Generates audit actions for configuration changes by comparing previous values with the new values from the DTO. * * @param connector the connector node * @param configurationStepName the configuration step name - * @param previousValues the previous property values - * @param newValues the new property values + * @param previousValues the previous property values (flat map: property name -> value) + * @param configurationStepDto the configuration step DTO containing new values with group structure * @return list of actions for changed properties */ private List<Action> generateConfigurationChangeActions(final ConnectorNode connector, final String configurationStepName, - final Map<String, Map<String, String>> previousValues, final Map<String, Map<String, String>> newValues) { + final Map<String, String> previousValues, final ConfigurationStepConfigurationDTO configurationStepDto) { final List<Action> actions = new ArrayList<>(); final Date timestamp = new Date(); final FlowChangeExtensionDetails connectorDetails = new FlowChangeExtensionDetails(); connectorDetails.setType(connector.getComponentType()); - // Iterate through all property groups in the new values - for (final Map.Entry<String, Map<String, String>> groupEntry : newValues.entrySet()) { - final String groupName = groupEntry.getKey(); - final Map<String, String> newGroupValues = groupEntry.getValue(); - final Map<String, String> previousGroupValues = previousValues.getOrDefault(groupName, new HashMap<>()); + if (configurationStepDto.getPropertyGroupConfigurations() == null) { + return actions; + } + + // Iterate through all property groups in the DTO to preserve group names for audit logging + for (final PropertyGroupConfigurationDTO groupDto : configurationStepDto.getPropertyGroupConfigurations()) { + final String groupName = groupDto.getPropertyGroupName(); + + if (groupDto.getPropertyValues() == null) { + continue; + } // Check each property in this group - for (final Map.Entry<String, String> propertyEntry : newGroupValues.entrySet()) { + for (final Map.Entry<String, ConnectorValueReferenceDTO> propertyEntry : groupDto.getPropertyValues().entrySet()) { final String propertyName = propertyEntry.getKey(); - final String newValue = propertyEntry.getValue(); - final String previousValue = previousGroupValues.get(propertyName); + final String newValue = formatValueReferenceDto(propertyEntry.getValue()); + final String previousValue = previousValues.get(propertyName); // Only create an action if the value changed if (!Objects.equals(previousValue, newValue)) { diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index f32a9924b73..aee15d1c45e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -82,9 +82,8 @@ import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; -import org.apache.nifi.web.api.dto.ConnectorDTO; import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; -import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; +import org.apache.nifi.web.api.dto.ConnectorDTO; import org.apache.nifi.web.api.dto.ResourceDTO; import org.apache.nifi.web.api.dto.SnippetDTO; import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO; @@ -221,7 +220,7 @@ public interface NiFiServiceFacade { void verifyCanVerifyConnectorConfigurationStep(String connectorId, String configurationStepName); - List<ConfigVerificationResultDTO> performConnectorConfigurationStepVerification(String connectorId, String configurationStepName, List<PropertyGroupConfigurationDTO> propertyGroupConfigurations); + List<ConfigVerificationResultDTO> performConnectorConfigurationStepVerification(String connectorId, String configurationStepName, ConfigurationStepConfigurationDTO configurationStepConfiguration); SearchResultsDTO searchConnector(String connectorId, String query); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index de1e068bdc2..df04e148d2b 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -286,7 +286,6 @@ import org.apache.nifi.web.api.dto.ProcessorConfigDTO; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.ProcessorRunStatusDetailsDTO; import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; -import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; import org.apache.nifi.web.api.dto.PropertyHistoryDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; @@ -3696,8 +3695,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public List<ConfigVerificationResultDTO> performConnectorConfigurationStepVerification(final String connectorId, - final String configurationStepName, final List<PropertyGroupConfigurationDTO> propertyGroupConfigurations) { - final List<ConfigVerificationResult> verificationResults = connectorDAO.verifyConfigurationStep(connectorId, configurationStepName, propertyGroupConfigurations); + final String configurationStepName, final ConfigurationStepConfigurationDTO configurationStepConfiguration) { + final List<ConfigVerificationResult> verificationResults = connectorDAO.verifyConfigurationStep(connectorId, configurationStepName, configurationStepConfiguration); return verificationResults.stream() .map(result -> dtoFactory.createConfigVerificationResultDto(result)) .collect(Collectors.toList()); @@ -3713,7 +3712,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { @Override public ConnectorPropertyAllowableValuesEntity getConnectorPropertyAllowableValues(final String connectorId, final String stepName, final String groupName, final String propertyName, final String filter) { - final List<AllowableValue> allowableValues = connectorDAO.fetchAllowableValues(connectorId, stepName, groupName, propertyName, filter); + // groupName is retained for REST API backward compatibility but is no longer used by the underlying API + final List<AllowableValue> allowableValues = connectorDAO.fetchAllowableValues(connectorId, stepName, propertyName, filter); final List<AllowableValueEntity> allowableValueEntities = allowableValues.stream() .map(av -> entityFactory.createAllowableValueEntity(dtoFactory.createAllowableValueDto(av), true)) diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java index 3c95ad6aa5d..ffc3fc264d8 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ConnectorResource.java @@ -56,7 +56,6 @@ import org.apache.nifi.web.api.dto.ConfigVerificationResultDTO; import org.apache.nifi.web.api.dto.BundleDTO; import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; import org.apache.nifi.web.api.dto.ConnectorDTO; -import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; import org.apache.nifi.web.api.dto.search.SearchResultsDTO; import org.apache.nifi.web.api.entity.ConfigurationStepEntity; import org.apache.nifi.web.api.entity.ConfigurationStepNamesEntity; @@ -1011,8 +1010,8 @@ public class ConnectorResource extends ApplicationResource { final Consumer<AsynchronousWebRequest<VerifyConnectorConfigStepRequestEntity, List<ConfigVerificationResultDTO>>> updateTask = asyncRequest -> { try { - final List<PropertyGroupConfigurationDTO> propertyGroupConfigurations = requestDto.getConfigurationStep().getPropertyGroupConfigurations(); - final List<ConfigVerificationResultDTO> results = serviceFacade.performConnectorConfigurationStepVerification(connectorId, configurationStepName, propertyGroupConfigurations); + final ConfigurationStepConfigurationDTO configurationStep = requestDto.getConfigurationStep(); + final List<ConfigVerificationResultDTO> results = serviceFacade.performConnectorConfigurationStepVerification(connectorId, configurationStepName, configurationStep); asyncRequest.markStepComplete(results); } catch (final Exception e) { logger.error("Failed to verify Connector Configuration Step", e); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index d3d5ee6da89..17e3c4ed55f 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -73,15 +73,15 @@ import org.apache.nifi.components.validation.ValidationStatus; import org.apache.nifi.connectable.Connectable; import org.apache.nifi.components.connector.AssetReference; import org.apache.nifi.components.connector.ConfigurationStep; -import org.apache.nifi.components.connector.ConfigurationStepConfiguration; import org.apache.nifi.components.connector.ConnectorConfiguration; import org.apache.nifi.components.connector.ConnectorNode; import org.apache.nifi.components.connector.ConnectorPropertyDescriptor; import org.apache.nifi.components.connector.ConnectorPropertyGroup; import org.apache.nifi.components.connector.ConnectorValueReference; import org.apache.nifi.components.connector.FrameworkFlowContext; -import org.apache.nifi.components.connector.PropertyGroupConfiguration; +import org.apache.nifi.components.connector.NamedStepConfiguration; import org.apache.nifi.components.connector.SecretReference; +import org.apache.nifi.components.connector.StepConfiguration; import org.apache.nifi.components.connector.StringLiteralValue; import org.apache.nifi.connectable.ConnectableType; import org.apache.nifi.connectable.Connection; @@ -5278,14 +5278,16 @@ public final class DtoFactory { final ConfigurationStepConfigurationDTO dto = new ConfigurationStepConfigurationDTO(); dto.setConfigurationStepName(step.getName()); dto.setConfigurationStepDescription(step.getDescription()); + dto.setConfigurationStepDocumentation(step.getDocumentation()); - // Get the current configuration values for this step - final ConfigurationStepConfiguration stepConfig = configuration.getConfigurationStepConfigurations().stream() + // Get the current configuration values for this step from the flat StepConfiguration + final StepConfiguration stepConfig = configuration.getNamedStepConfigurations().stream() .filter(c -> step.getName().equals(c.stepName())) + .map(NamedStepConfiguration::configuration) .findFirst() .orElse(null); - // Convert property groups from the schema, merging in current values + // Convert property groups from the schema, merging in current values from flat stepConfig final List<PropertyGroupConfigurationDTO> propertyGroupDtos = step.getPropertyGroups().stream() .map(propertyGroup -> createPropertyGroupConfigurationDtoFromGroup(propertyGroup, stepConfig)) .collect(Collectors.toList()); @@ -5293,7 +5295,7 @@ public final class DtoFactory { return dto; } - private PropertyGroupConfigurationDTO createPropertyGroupConfigurationDtoFromGroup(final ConnectorPropertyGroup propertyGroup, final ConfigurationStepConfiguration stepConfig) { + private PropertyGroupConfigurationDTO createPropertyGroupConfigurationDtoFromGroup(final ConnectorPropertyGroup propertyGroup, final StepConfiguration stepConfig) { if (propertyGroup == null) { return null; } @@ -5311,18 +5313,15 @@ public final class DtoFactory { } dto.setPropertyDescriptors(propertyDescriptorMap); - // Get the current property values for this group if they exist + // Get the current property values for this group's properties from flat stepConfig // Use LinkedHashMap to preserve the order from the connector final Map<String, ConnectorValueReferenceDTO> propertyValues = new LinkedHashMap<>(); if (stepConfig != null) { - final PropertyGroupConfiguration groupConfig = stepConfig.propertyGroupConfigurations().stream() - .filter(g -> propertyGroup.getName().equals(g.groupName())) - .findFirst() - .orElse(null); - - if (groupConfig != null) { - for (final Map.Entry<String, ConnectorValueReference> entry : groupConfig.propertyValues().entrySet()) { - propertyValues.put(entry.getKey(), createConnectorValueReferenceDto(entry.getValue())); + // For each property in this group, check if there's a value in the flat stepConfig + for (final ConnectorPropertyDescriptor propertyDescriptor : propertyGroup.getProperties()) { + final ConnectorValueReference valueRef = stepConfig.getPropertyValue(propertyDescriptor.getName()); + if (valueRef != null) { + propertyValues.put(propertyDescriptor.getName(), createConnectorValueReferenceDto(valueRef)); } } } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java index 5e6cacb6960..cd748204af9 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/EntityFactory.java @@ -913,8 +913,7 @@ public final class EntityFactory { } public ConnectorPropertyAllowableValuesEntity createConnectorPropertyAllowableValuesEntity( - final String configurationStepName, final String propertyGroupName, final String propertyName, - final List<AllowableValueEntity> allowableValues) { + final String configurationStepName, final String propertyGroupName, final String propertyName, final List<AllowableValueEntity> allowableValues) { final ConnectorPropertyAllowableValuesEntity entity = new ConnectorPropertyAllowableValuesEntity(); entity.setConfigurationStepName(configurationStepName); entity.setPropertyGroupName(propertyGroupName); diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectorDAO.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectorDAO.java index 3ae78f4966f..2a3ef150758 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectorDAO.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/ConnectorDAO.java @@ -21,7 +21,6 @@ import org.apache.nifi.components.AllowableValue; import org.apache.nifi.components.ConfigVerificationResult; import org.apache.nifi.components.connector.ConnectorNode; import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; -import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; import java.util.List; @@ -51,9 +50,9 @@ public interface ConnectorDAO { void verifyCanVerifyConfigurationStep(String id, String configurationStepName); - List<ConfigVerificationResult> verifyConfigurationStep(String id, String configurationStepName, List<PropertyGroupConfigurationDTO> propertyGroupConfigurations); + List<ConfigVerificationResult> verifyConfigurationStep(String id, String configurationStepName, ConfigurationStepConfigurationDTO configurationStepConfiguration); - List<AllowableValue> fetchAllowableValues(String id, String stepName, String groupName, String propertyName, String filter); + List<AllowableValue> fetchAllowableValues(String id, String stepName, String propertyName, String filter); } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectorDAO.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectorDAO.java index fd07e81eb5f..13de988b8b6 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectorDAO.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/dao/impl/StandardConnectorDAO.java @@ -24,21 +24,20 @@ import org.apache.nifi.components.connector.ConnectorNode; import org.apache.nifi.components.connector.ConnectorRepository; import org.apache.nifi.components.connector.ConnectorValueReference; import org.apache.nifi.components.connector.ConnectorValueType; -import org.apache.nifi.components.connector.PropertyGroupConfiguration; import org.apache.nifi.components.connector.SecretReference; +import org.apache.nifi.components.connector.StepConfiguration; import org.apache.nifi.components.connector.StringLiteralValue; -import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; -import org.apache.nifi.web.api.dto.ConnectorValueReferenceDTO; -import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; import org.apache.nifi.controller.FlowController; import org.apache.nifi.controller.flow.FlowManager; import org.apache.nifi.web.NiFiCoreException; import org.apache.nifi.web.ResourceNotFoundException; +import org.apache.nifi.web.api.dto.ConfigurationStepConfigurationDTO; +import org.apache.nifi.web.api.dto.ConnectorValueReferenceDTO; +import org.apache.nifi.web.api.dto.PropertyGroupConfigurationDTO; import org.apache.nifi.web.dao.ConnectorDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -121,30 +120,29 @@ public class StandardConnectorDAO implements ConnectorDAO { public void updateConnectorConfigurationStep(final String id, final String configurationStepName, final ConfigurationStepConfigurationDTO configurationStepDto) { final ConnectorNode connector = getConnector(id); - // Convert DTO to domain object - extract the property groups from the configuration step - final List<PropertyGroupConfiguration> propertyGroups = new ArrayList<>(); - if (configurationStepDto.getPropertyGroupConfigurations() != null) { - propertyGroups.addAll(configurationStepDto.getPropertyGroupConfigurations().stream() - .map(this::convertToPropertyGroupConfiguration) - .toList()); - } + // Convert DTO to domain object - flatten all property groups into a single StepConfiguration + final StepConfiguration stepConfiguration = convertToStepConfiguration(configurationStepDto); // Update the connector configuration through the repository try { - getConnectorRepository().configureConnector(connector, configurationStepName, propertyGroups); + getConnectorRepository().configureConnector(connector, configurationStepName, stepConfiguration); } catch (final Exception e) { throw new IllegalStateException("Failed to update connector configuration: " + e, e); } } - private PropertyGroupConfiguration convertToPropertyGroupConfiguration(final PropertyGroupConfigurationDTO dto) { + private StepConfiguration convertToStepConfiguration(final ConfigurationStepConfigurationDTO dto) { final Map<String, ConnectorValueReference> propertyValues = new HashMap<>(); - if (dto.getPropertyValues() != null) { - for (final Map.Entry<String, ConnectorValueReferenceDTO> entry : dto.getPropertyValues().entrySet()) { - propertyValues.put(entry.getKey(), convertToConnectorValueReference(entry.getValue())); + if (dto.getPropertyGroupConfigurations() != null) { + for (final PropertyGroupConfigurationDTO groupDto : dto.getPropertyGroupConfigurations()) { + if (groupDto.getPropertyValues() != null) { + for (final Map.Entry<String, ConnectorValueReferenceDTO> entry : groupDto.getPropertyValues().entrySet()) { + propertyValues.put(entry.getKey(), convertToConnectorValueReference(entry.getValue())); + } + } } } - return new PropertyGroupConfiguration(dto.getPropertyGroupName(), propertyValues); + return new StepConfiguration(propertyValues); } private ConnectorValueReference convertToConnectorValueReference(final ConnectorValueReferenceDTO dto) { @@ -176,26 +174,19 @@ public class StandardConnectorDAO implements ConnectorDAO { } @Override - public List<ConfigVerificationResult> verifyConfigurationStep(final String id, final String configurationStepName, final List<PropertyGroupConfigurationDTO> propertyGroupConfigurationDtos) { + public List<ConfigVerificationResult> verifyConfigurationStep(final String id, final String configurationStepName, final ConfigurationStepConfigurationDTO configurationStepDto) { final ConnectorNode connector = getConnector(id); - - final List<PropertyGroupConfiguration> propertyGroupConfigurations = new ArrayList<>(); - if (propertyGroupConfigurationDtos != null) { - for (final PropertyGroupConfigurationDTO dto : propertyGroupConfigurationDtos) { - propertyGroupConfigurations.add(convertToPropertyGroupConfiguration(dto)); - } - } - - return connector.verifyConfigurationStep(configurationStepName, propertyGroupConfigurations); + final StepConfiguration stepConfiguration = convertToStepConfiguration(configurationStepDto); + return connector.verifyConfigurationStep(configurationStepName, stepConfiguration); } @Override - public List<AllowableValue> fetchAllowableValues(final String id, final String stepName, final String groupName, final String propertyName, final String filter) { + public List<AllowableValue> fetchAllowableValues(final String id, final String stepName, final String propertyName, final String filter) { final ConnectorNode connector = getConnector(id); if (filter == null || filter.isEmpty()) { - return connector.fetchAllowableValues(stepName, groupName, propertyName); + return connector.fetchAllowableValues(stepName, propertyName); } else { - return connector.fetchAllowableValues(stepName, groupName, propertyName, filter); + return connector.fetchAllowableValues(stepName, propertyName, filter); } } } diff --git a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/StandardConnectorDAOTest.java b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/StandardConnectorDAOTest.java index e33d2aded8c..bb96b35271e 100644 --- a/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/StandardConnectorDAOTest.java +++ b/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/test/java/org/apache/nifi/web/dao/impl/StandardConnectorDAOTest.java @@ -55,7 +55,6 @@ class StandardConnectorDAOTest { private static final String CONNECTOR_ID = "test-connector-id"; private static final String STEP_NAME = "test-step"; - private static final String GROUP_NAME = "test-group"; private static final String PROPERTY_NAME = "test-property"; @BeforeEach @@ -159,13 +158,13 @@ class StandardConnectorDAOTest { new AllowableValue("value2", "Value 2", "Second value") ); when(connectorRepository.getConnector(CONNECTOR_ID)).thenReturn(connectorNode); - when(connectorNode.fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME)).thenReturn(expectedValues); + when(connectorNode.fetchAllowableValues(STEP_NAME, PROPERTY_NAME)).thenReturn(expectedValues); - final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, GROUP_NAME, PROPERTY_NAME, null); + final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, PROPERTY_NAME, null); assertEquals(expectedValues, result); - verify(connectorNode).fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME); - verify(connectorNode, never()).fetchAllowableValues(any(), any(), any(), any()); + verify(connectorNode).fetchAllowableValues(STEP_NAME, PROPERTY_NAME); + verify(connectorNode, never()).fetchAllowableValues(any(), any(), any()); } @Test @@ -174,13 +173,13 @@ class StandardConnectorDAOTest { new AllowableValue("value1", "Value 1", "First value") ); when(connectorRepository.getConnector(CONNECTOR_ID)).thenReturn(connectorNode); - when(connectorNode.fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME)).thenReturn(expectedValues); + when(connectorNode.fetchAllowableValues(STEP_NAME, PROPERTY_NAME)).thenReturn(expectedValues); - final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, GROUP_NAME, PROPERTY_NAME, ""); + final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, PROPERTY_NAME, ""); assertEquals(expectedValues, result); - verify(connectorNode).fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME); - verify(connectorNode, never()).fetchAllowableValues(any(), any(), any(), any()); + verify(connectorNode).fetchAllowableValues(STEP_NAME, PROPERTY_NAME); + verify(connectorNode, never()).fetchAllowableValues(any(), any(), any()); } @Test @@ -190,13 +189,13 @@ class StandardConnectorDAOTest { new AllowableValue("filtered-value", "Filtered Value", "Filtered result") ); when(connectorRepository.getConnector(CONNECTOR_ID)).thenReturn(connectorNode); - when(connectorNode.fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME, filter)).thenReturn(expectedValues); + when(connectorNode.fetchAllowableValues(STEP_NAME, PROPERTY_NAME, filter)).thenReturn(expectedValues); - final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, GROUP_NAME, PROPERTY_NAME, filter); + final List<AllowableValue> result = connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, PROPERTY_NAME, filter); assertEquals(expectedValues, result); - verify(connectorNode).fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME, filter); - verify(connectorNode, never()).fetchAllowableValues(STEP_NAME, GROUP_NAME, PROPERTY_NAME); + verify(connectorNode).fetchAllowableValues(STEP_NAME, PROPERTY_NAME, filter); + verify(connectorNode, never()).fetchAllowableValues(STEP_NAME, PROPERTY_NAME); } @Test @@ -204,7 +203,7 @@ class StandardConnectorDAOTest { when(connectorRepository.getConnector(CONNECTOR_ID)).thenReturn(null); assertThrows(ResourceNotFoundException.class, () -> - connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, GROUP_NAME, PROPERTY_NAME, null) + connectorDAO.fetchAllowableValues(CONNECTOR_ID, STEP_NAME, PROPERTY_NAME, null) ); verify(connectorRepository).getConnector(CONNECTOR_ID);
