This is an automated email from the ASF dual-hosted git repository.
markap14 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-api.git
The following commit(s) were added to refs/heads/main by this push:
new 9d6c8ba NIFI-16070: Add nifi-api support for migrateProperties to
Connectors. (#102)
9d6c8ba is described below
commit 9d6c8bae800685f9adbae88706871555a211c3c5
Author: Bob Paulin <[email protected]>
AuthorDate: Mon Jul 6 08:54:35 2026 -0500
NIFI-16070: Add nifi-api support for migrateProperties to Connectors. (#102)
* Create api with default implementation
---
.../nifi/components/connector/Connector.java | 18 +++
.../migration/ConnectorPropertyConfiguration.java | 80 +++++++++++
.../ConnectorStepPropertyConfiguration.java | 153 +++++++++++++++++++++
3 files changed, 251 insertions(+)
diff --git a/src/main/java/org/apache/nifi/components/connector/Connector.java
b/src/main/java/org/apache/nifi/components/connector/Connector.java
index 36d2998..c1f696a 100644
--- a/src/main/java/org/apache/nifi/components/connector/Connector.java
+++ b/src/main/java/org/apache/nifi/components/connector/Connector.java
@@ -22,6 +22,7 @@ import org.apache.nifi.components.DescribedValue;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.components.connector.components.FlowContext;
import org.apache.nifi.flow.VersionedExternalFlow;
+import org.apache.nifi.migration.ConnectorPropertyConfiguration;
import java.util.List;
import java.util.Map;
@@ -245,4 +246,21 @@ public interface Connector {
* @return a Future that will be completed when the draining is complete
*/
CompletableFuture<Void> drainFlowFiles(FlowContext flowContext);
+
+ /**
+ * Migrates an old property configuration to a new one, allowing
properties and {@link ConfigurationStep}s to be
+ * renamed, removed, or added while preserving values. Invoked whenever
the Connector is restored from a previous
+ * configuration (e.g., on restart) for the active and working
configurations independently.
+ *
+ * <p>
+ * Distinct from
+ * {@link
org.apache.nifi.components.connector.migration.MigratableConnector#migrateConfiguration(org.apache.nifi.components.connector.migration.ConnectorMigrationContext)},
+ * which copies configuration from a separate source flow; this method
evolves the persisted names of the
+ * Connector's own configuration.
+ * </p>
+ *
+ * @param config the current property configuration, scoped per
configuration step
+ */
+ default void migrateProperties(ConnectorPropertyConfiguration config) {
+ }
}
diff --git
a/src/main/java/org/apache/nifi/migration/ConnectorPropertyConfiguration.java
b/src/main/java/org/apache/nifi/migration/ConnectorPropertyConfiguration.java
new file mode 100644
index 0000000..db7720b
--- /dev/null
+++
b/src/main/java/org/apache/nifi/migration/ConnectorPropertyConfiguration.java
@@ -0,0 +1,80 @@
+/*
+ * 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.migration;
+
+import org.apache.nifi.components.connector.ConfigurationStep;
+
+import java.util.Set;
+
+/**
+ * Entry point for a {@link org.apache.nifi.components.connector.Connector} to
migrate its persisted property
+ * configuration on restore. Because a Connector's properties are organized
into named {@link ConfigurationStep}s,
+ * migration is scoped per step: this interface exposes step-level operations
directly and yields a
+ * {@link ConnectorStepPropertyConfiguration} for per-step property changes
via {@link #forStep(String)}.
+ *
+ * <p>
+ * <b>Implementation Note:</b> This API is experimental and subject to
change between minor releases.
+ * </p>
+ */
+public interface ConnectorPropertyConfiguration {
+
+ /**
+ * @return the names of all configuration steps currently known to this
configuration
+ */
+ Set<String> getStepNames();
+
+ /**
+ * @param stepName the name of the configuration step
+ * @return <code>true</code> if this configuration contains the given step
+ */
+ boolean hasStep(String stepName);
+
+ /**
+ * Renames an existing configuration step, preserving all of its
properties and their underlying value references.
+ *
+ * @param oldStepName the current step name
+ * @param newStepName the new step name
+ * @return <code>true</code> if the step was renamed; <code>false</code>
if no step exists with {@code oldStepName}
+ * @throws IllegalStateException if a step already exists with {@code
newStepName}
+ */
+ boolean renameStep(String oldStepName, String newStepName);
+
+ /**
+ * Removes the configuration step with the given name and all of its
properties, if it exists.
+ *
+ * @param stepName the name of the step to remove
+ * @return <code>true</code> if the step was removed; <code>false</code>
if the step did not exist
+ */
+ boolean removeStep(String stepName);
+
+ /**
+ * Returns a step-scoped view of this configuration. The view is usable
even when no step currently exists with the
+ * given name; the step is registered on the first property write.
Retrieval alone does not register a step.
+ *
+ * @param stepName the name of the configuration step
+ * @return a step-scoped configuration view
+ */
+ ConnectorStepPropertyConfiguration forStep(String stepName);
+
+ /**
+ * Convenience overload of {@link #forStep(String)} accepting a {@link
ConfigurationStep}.
+ */
+ default ConnectorStepPropertyConfiguration forStep(final ConfigurationStep
step) {
+ return forStep(step.getName());
+ }
+}
diff --git
a/src/main/java/org/apache/nifi/migration/ConnectorStepPropertyConfiguration.java
b/src/main/java/org/apache/nifi/migration/ConnectorStepPropertyConfiguration.java
new file mode 100644
index 0000000..f2f1bee
--- /dev/null
+++
b/src/main/java/org/apache/nifi/migration/ConnectorStepPropertyConfiguration.java
@@ -0,0 +1,153 @@
+/*
+ * 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.migration;
+
+import org.apache.nifi.components.connector.ConnectorPropertyDescriptor;
+import org.apache.nifi.components.connector.ConnectorValueReference;
+
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Step-scoped view of a {@link ConnectorPropertyConfiguration}. All
operations apply to the step returned by
+ * {@link #getStepName()}. Rename operations preserve the underlying {@link
ConnectorValueReference} subtype (e.g. a
+ * {@link org.apache.nifi.components.connector.SecretReference} stays a
+ * {@link org.apache.nifi.components.connector.SecretReference}); use
+ * {@link #setValueReference(String, ConnectorValueReference)} to change the
subtype.
+ *
+ * <p>
+ * <b>Implementation Note:</b> This API is experimental and subject to
change between minor releases.
+ * </p>
+ */
+public interface ConnectorStepPropertyConfiguration {
+
+ /**
+ * @return the name of the configuration step this view is scoped to
+ */
+ String getStepName();
+
+ /**
+ * Renames an existing property, preserving its underlying {@link
ConnectorValueReference}.
+ *
+ * @param propertyName the current property name
+ * @param newName the new property name
+ * @return <code>true</code> if the property was renamed;
<code>false</code> if it did not exist
+ */
+ boolean renameProperty(String propertyName, String newName);
+
+ /**
+ * Removes the property with the given name, if it exists. No-op otherwise.
+ *
+ * @param propertyName the property name
+ * @return <code>true</code> if the property was removed;
<code>false</code> if it did not exist
+ */
+ boolean removeProperty(String propertyName);
+
+ /**
+ * @param propertyName the property name
+ * @return <code>true</code> if this step has an entry for the property,
including when its value reference is null
+ */
+ boolean hasProperty(String propertyName);
+
+ /**
+ * @param propertyName the property name
+ * @return <code>true</code> if the property is set to a non-null value
+ */
+ boolean isPropertySet(String propertyName);
+
+ /**
+ * Convenience for {@code setValueReference(propertyName, new
StringLiteralValue(propertyValue))}.
+ */
+ void setProperty(String propertyName, String propertyValue);
+
+ /**
+ * Sets the given property to the given {@link ConnectorValueReference},
or removes it when {@code valueReference}
+ * is <code>null</code>.
+ */
+ void setValueReference(String propertyName, ConnectorValueReference
valueReference);
+
+ /**
+ * Returns the string value when the underlying reference is a
+ * {@link org.apache.nifi.components.connector.StringLiteralValue}. Empty
when the property is absent, its
+ * {@link org.apache.nifi.components.connector.StringLiteralValue} carries
a null value, or the reference is a
+ * different subtype (e.g. {@link
org.apache.nifi.components.connector.AssetReference} or
+ * {@link org.apache.nifi.components.connector.SecretReference}); use
{@link #getValueReference(String)} for the
+ * typed view.
+ */
+ Optional<String> getPropertyValue(String propertyName);
+
+ /**
+ * @return the underlying {@link ConnectorValueReference} regardless of
subtype, or empty when the property is
+ * absent or the reference is <code>null</code>
+ */
+ Optional<ConnectorValueReference> getValueReference(String propertyName);
+
+ /**
+ * @return the string-literal properties in this step; properties whose
values are of other subtypes are omitted
+ * (use {@link #getValueReferences()} for the full typed view)
+ */
+ Map<String, String> getProperties();
+
+ /**
+ * @return every property in this step keyed by name, exposing the
underlying {@link ConnectorValueReference}
+ */
+ Map<String, ConnectorValueReference> getValueReferences();
+
+ /**
+ * Convenience overload of {@link #hasProperty(String)} accepting a {@link
ConnectorPropertyDescriptor}.
+ */
+ default boolean hasProperty(final ConnectorPropertyDescriptor descriptor) {
+ return hasProperty(descriptor.getName());
+ }
+
+ /**
+ * Convenience overload of {@link #isPropertySet(String)} accepting a
{@link ConnectorPropertyDescriptor}.
+ */
+ default boolean isPropertySet(final ConnectorPropertyDescriptor
descriptor) {
+ return isPropertySet(descriptor.getName());
+ }
+
+ /**
+ * Convenience overload of {@link #setProperty(String, String)} accepting
a {@link ConnectorPropertyDescriptor}.
+ */
+ default void setProperty(final ConnectorPropertyDescriptor descriptor,
final String propertyValue) {
+ setProperty(descriptor.getName(), propertyValue);
+ }
+
+ /**
+ * Convenience overload of {@link #setValueReference(String,
ConnectorValueReference)} accepting a
+ * {@link ConnectorPropertyDescriptor}.
+ */
+ default void setValueReference(final ConnectorPropertyDescriptor
descriptor, final ConnectorValueReference valueReference) {
+ setValueReference(descriptor.getName(), valueReference);
+ }
+
+ /**
+ * Convenience overload of {@link #getPropertyValue(String)} accepting a
{@link ConnectorPropertyDescriptor}.
+ */
+ default Optional<String> getPropertyValue(final
ConnectorPropertyDescriptor descriptor) {
+ return getPropertyValue(descriptor.getName());
+ }
+
+ /**
+ * Convenience overload of {@link #getValueReference(String)} accepting a
{@link ConnectorPropertyDescriptor}.
+ */
+ default Optional<ConnectorValueReference> getValueReference(final
ConnectorPropertyDescriptor descriptor) {
+ return getValueReference(descriptor.getName());
+ }
+}