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());
+    }
+}

Reply via email to