ncover21 commented on code in PR #9825:
URL: https://github.com/apache/nifi/pull/9825#discussion_r2025274744


##########
nifi-extension-bundles/nifi-box-bundle/nifi-box-processors/src/main/java/org/apache/nifi/processors/box/UpdateBoxFileMetadataInstance.java:
##########
@@ -248,40 +207,110 @@ public void onTrigger(final ProcessContext context, 
final ProcessSession session
         }
     }
 
-    private void processRecord(Record record, RecordPath keyRecordPath, 
RecordPath valueRecordPath,
-                               Metadata metadata, Set<String> updatedKeys, 
List<String> errors) {
-        // Get the key from the record
-        final RecordPathResult keyPathResult = keyRecordPath.evaluate(record);
-        final List<FieldValue> keyValues = 
keyPathResult.getSelectedFields().toList();
+    private Map<String, Object> readDesiredState(final ProcessSession session,
+                                                 final FlowFile flowFile,
+                                                 final RecordReaderFactory 
recordReaderFactory) throws Exception {
+        final Map<String, Object> desiredState = new HashMap<>();
 
-        if (keyValues.isEmpty()) {
-            errors.add("Record is missing a key field");
-            return;
+        try (final InputStream inputStream = session.read(flowFile);
+             final RecordReader recordReader = 
recordReaderFactory.createRecordReader(flowFile, inputStream, getLogger())) {
+
+            final Record record = recordReader.nextRecord();
+            if (record != null) {
+                for (String fieldName : record.getSchema().getFieldNames()) {
+                    desiredState.put(fieldName, record.getValue(fieldName));
+                }
+            }
         }
 
-        final Object keyObj = keyValues.getFirst().getValue();
-        if (keyObj == null) {
-            errors.add("Record has a null key value");
-            return;
+        return desiredState;
+    }
+
+    Metadata getOrCreateMetadata(final BoxFile boxFile,
+                                 final String templateKey,
+                                 final String fileId) {
+        try {
+            final Metadata metadata = boxFile.getMetadata(templateKey);
+            getLogger().debug("Retrieved existing metadata for file {}", 
fileId);
+            return metadata;
+        } catch (final BoxAPIResponseException e) {
+            if (e.getResponseCode() == 404) {
+                getLogger().warn("No existing metadata found for file {} with 
template key {}.", fileId, templateKey);
+                throw e;
+            }
+            throw e;
         }
+    }
 
-        final String key = keyObj.toString();
+    private Set<String> updateMetadata(final Metadata metadata,
+                                       final Map<String, Object> desiredState) 
{
+        final Set<String> processedKeys = new HashSet<>();
+        final List<String> currentKeys = metadata.getPropertyPaths();
 
-        // Get the value from the record
-        final RecordPathResult valuePathResult = 
valueRecordPath.evaluate(record);
-        final List<FieldValue> valueValues = 
valuePathResult.getSelectedFields().toList();
+        // Remove fields not in desired state
+        for (final String propertyPath : currentKeys) {
+            final String fieldName = propertyPath.substring(1); // Remove 
leading '/'
 
-        if (valueValues.isEmpty()) {
-            errors.add("Record with key '" + key + "' is missing a value 
field");
-            return;
+            if (!desiredState.containsKey(fieldName)) {
+                metadata.remove(propertyPath);
+                processedKeys.add(fieldName);
+                getLogger().debug("Removing metadata field: {}", fieldName);
+            }
+        }
+
+        // Add or update fields
+        for (final Map.Entry<String, Object> entry : desiredState.entrySet()) {
+            final String fieldName = entry.getKey();
+            final Object value = entry.getValue();
+            final String propertyPath = "/" + fieldName;
+
+            if (updateField(metadata, propertyPath, value, 
currentKeys.contains(propertyPath))) {
+                processedKeys.add(fieldName);
+            }
+        }
+
+        return processedKeys;
+    }
+
+    private boolean updateField(final Metadata metadata,
+                                final String propertyPath,
+                                final Object value,
+                                final boolean exists) {
+        if (value == null) {
+            return false;
         }
 
-        final Object valueObj = valueValues.getFirst().getValue();
-        final String value = valueObj != null ? valueObj.toString() : null;
+        if (exists) {
+            final Object currentValue = metadata.getValue(propertyPath);
 
-        // Add the key-value pair to the metadata update
-        metadata.add("/" + key, value);
-        updatedKeys.add(key);
+            // Only update if values are different
+            if (Objects.equals(currentValue, value)) {
+                return false;
+            }
+
+            // Update
+            switch (value) {
+                case Number n -> metadata.replace(propertyPath, 
n.doubleValue());
+                case List<?> l -> metadata.replace(propertyPath, 
convertListToStringList(l));
+                default -> metadata.replace(propertyPath, value.toString());
+            }
+        } else {
+            // Add new field
+            switch (value) {
+                case Number n -> metadata.add(propertyPath, n.doubleValue());
+                case List<?> l -> metadata.add(propertyPath, 
convertListToStringList(l));
+                default -> metadata.add(propertyPath, value.toString());
+            }
+        }
+        return true;
+    }
+
+    private List<String> convertListToStringList(final List<?> list) {
+        // Box doesn't support null values in metadata lists, so we filter 
them out

Review Comment:
   Yeah, fails now



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to