@@ -135,87 +135,20 @@ public void copyAttachments(AttachmentCopyEventContext context) throws IOExcepti
135135
136136 List <String > objectIds = context .getObjectIds ();
137137
138- // copy validation: Check for invalid secondary properties before copying
139- List <String > validObjectIds = new ArrayList <>(objectIds );
138+ // Pre-copy validation: Check for invalid secondary properties before copying
140139 List <Map <String , String >> copyFailures = new ArrayList <>();
141-
142- if (!customPropertiesInSDM .isEmpty ()) {
143- // Fetch valid secondary properties from SDM
144- List <String > secondaryTypes =
145- sdmService .getSecondaryTypes (repositoryId , sdmCredentials , isSystemUser );
146- List <String > validSecondaryProperties =
147- sdmService .getValidSecondaryProperties (
148- secondaryTypes , sdmCredentials , repositoryId , isSystemUser );
149-
150- logger .debug (
151- "Copy validation - checking {} attachments against {} valid secondary properties" ,
152- objectIds .size (),
153- validSecondaryProperties .size ());
154-
155- validObjectIds = new ArrayList <>();
156- for (String objectId : objectIds ) {
157- try {
158- JSONObject sdmMetadata = sdmService .getObject (objectId , sdmCredentials , isSystemUser );
159- if (sdmMetadata != null && sdmMetadata .has ("succinctProperties" )) {
160- JSONObject succinctProperties = sdmMetadata .getJSONObject ("succinctProperties" );
161- Set <String > sdmResponseProperties = new HashSet <>(succinctProperties .keySet ());
162-
163- List <String > invalidProperties = new ArrayList <>();
164- for (String targetSdmProperty : customPropertiesInSDM ) {
165- if (sdmResponseProperties .contains (targetSdmProperty )
166- && !validSecondaryProperties .contains (targetSdmProperty )) {
167- invalidProperties .add (targetSdmProperty );
168- logger .warn (
169- "Copy validation - Attachment {} has invalid secondary property '{}'"
170- + " (present in SDM response but not in valid secondary properties list)" ,
171- objectId ,
172- targetSdmProperty );
173- }
174- }
175-
176- if (!invalidProperties .isEmpty ()) {
177- Map <String , String > failure = new HashMap <>();
178- failure .put (OBJECT_ID_KEY , objectId );
179- failure .put (
180- FAILURE_REASON_KEY ,
181- SDMUtils .getErrorMessage ("INVALID_SECONDARY_PROPERTIES_FOR_COPY_PREFIX" )
182- + String .join (", " , invalidProperties )
183- + SDMUtils .getErrorMessage ("INVALID_SECONDARY_PROPERTIES_FOR_COPY_SUFFIX" ));
184- copyFailures .add (failure );
185- logger .warn (
186- "Copy validation - Skipping attachment {} due to {} invalid secondary properties: {}" ,
187- objectId ,
188- invalidProperties .size (),
189- invalidProperties );
190- } else {
191- validObjectIds .add (objectId );
192- }
193- } else {
194- validObjectIds .add (objectId );
195- }
196- } catch (IOException e ) {
197- logger .error (
198- "Copy validation - Failed to fetch metadata for attachment {}: {}" ,
199- objectId ,
200- e .getMessage ());
201- validObjectIds .add (objectId );
202- }
203- }
204- }
140+ List <String > validObjectIds =
141+ validateObjectIdsForCopy (
142+ objectIds ,
143+ customPropertiesInSDM ,
144+ repositoryId ,
145+ sdmCredentials ,
146+ isSystemUser ,
147+ copyFailures );
205148
206149 // Show warning if there are attachments with invalid secondary properties
207150 if (!copyFailures .isEmpty ()) {
208- StringBuilder warningMessage =
209- new StringBuilder (SDMUtils .getErrorMessage ("FAILED_TO_COPY_ATTACHMENTS_PREFIX" ));
210- for (Map <String , String > failure : copyFailures ) {
211- warningMessage
212- .append ("- ObjectId: " )
213- .append (failure .get (OBJECT_ID_KEY ))
214- .append (", Reason: " )
215- .append (failure .get (FAILURE_REASON_KEY ))
216- .append ("\n " );
217- }
218- context .getMessages ().warn (warningMessage .toString ());
151+ buildAndWarnCopyFailures (copyFailures , context );
219152 }
220153
221154 if (validObjectIds .isEmpty ()) {
@@ -268,6 +201,139 @@ public void copyAttachments(AttachmentCopyEventContext context) throws IOExcepti
268201 logger .debug ("END: Copy attachments event" );
269202 }
270203
204+ /**
205+ * Validates object IDs for copy by checking for invalid secondary properties. Attachments with
206+ * invalid properties are excluded and added to the failures list.
207+ */
208+ private List <String > validateObjectIdsForCopy (
209+ List <String > objectIds ,
210+ Set <String > customPropertiesInSDM ,
211+ String repositoryId ,
212+ SDMCredentials sdmCredentials ,
213+ Boolean isSystemUser ,
214+ List <Map <String , String >> copyFailures )
215+ throws IOException {
216+ if (customPropertiesInSDM .isEmpty ()) {
217+ return new ArrayList <>(objectIds );
218+ }
219+
220+ List <String > secondaryTypes =
221+ sdmService .getSecondaryTypes (repositoryId , sdmCredentials , isSystemUser );
222+ List <String > validSecondaryProperties =
223+ sdmService .getValidSecondaryProperties (
224+ secondaryTypes , sdmCredentials , repositoryId , isSystemUser );
225+
226+ logger .debug (
227+ "Copy validation - checking {} attachments against {} valid secondary properties" ,
228+ objectIds .size (),
229+ validSecondaryProperties .size ());
230+
231+ List <String > validObjectIds = new ArrayList <>();
232+ for (String objectId : objectIds ) {
233+ validateSingleObjectForCopy (
234+ objectId ,
235+ customPropertiesInSDM ,
236+ validSecondaryProperties ,
237+ sdmCredentials ,
238+ isSystemUser ,
239+ validObjectIds ,
240+ copyFailures );
241+ }
242+ return validObjectIds ;
243+ }
244+
245+ /**
246+ * Validates a single attachment for copy by checking its secondary properties against the valid
247+ * list. Adds to validObjectIds if valid, or to copyFailures if invalid.
248+ */
249+ private void validateSingleObjectForCopy (
250+ String objectId ,
251+ Set <String > customPropertiesInSDM ,
252+ List <String > validSecondaryProperties ,
253+ SDMCredentials sdmCredentials ,
254+ Boolean isSystemUser ,
255+ List <String > validObjectIds ,
256+ List <Map <String , String >> copyFailures ) {
257+ try {
258+ JSONObject sdmMetadata = sdmService .getObject (objectId , sdmCredentials , isSystemUser );
259+ if (sdmMetadata == null || !sdmMetadata .has ("succinctProperties" )) {
260+ validObjectIds .add (objectId );
261+ return ;
262+ }
263+
264+ JSONObject succinctProperties = sdmMetadata .getJSONObject ("succinctProperties" );
265+ Set <String > sdmResponseProperties = new HashSet <>(succinctProperties .keySet ());
266+
267+ List <String > invalidProperties =
268+ findInvalidSecondaryProperties (
269+ customPropertiesInSDM , sdmResponseProperties , validSecondaryProperties , objectId );
270+
271+ if (invalidProperties .isEmpty ()) {
272+ validObjectIds .add (objectId );
273+ } else {
274+ Map <String , String > failure = new HashMap <>();
275+ failure .put (OBJECT_ID_KEY , objectId );
276+ failure .put (
277+ FAILURE_REASON_KEY ,
278+ SDMUtils .getErrorMessage ("INVALID_SECONDARY_PROPERTIES_FOR_COPY_PREFIX" )
279+ + String .join (", " , invalidProperties )
280+ + SDMUtils .getErrorMessage ("INVALID_SECONDARY_PROPERTIES_FOR_COPY_SUFFIX" ));
281+ copyFailures .add (failure );
282+ logger .warn (
283+ "Copy validation - Skipping attachment {} due to {} invalid secondary properties: {}" ,
284+ objectId ,
285+ invalidProperties .size (),
286+ invalidProperties );
287+ }
288+ } catch (IOException e ) {
289+ logger .error (
290+ "Copy validation - Failed to fetch metadata for attachment {}: {}" ,
291+ objectId ,
292+ e .getMessage ());
293+ validObjectIds .add (objectId );
294+ }
295+ }
296+
297+ /**
298+ * Finds secondary properties that are present in the SDM response but not in the valid properties
299+ * list.
300+ */
301+ private List <String > findInvalidSecondaryProperties (
302+ Set <String > customPropertiesInSDM ,
303+ Set <String > sdmResponseProperties ,
304+ List <String > validSecondaryProperties ,
305+ String objectId ) {
306+ List <String > invalidProperties = new ArrayList <>();
307+ for (String targetSdmProperty : customPropertiesInSDM ) {
308+ if (sdmResponseProperties .contains (targetSdmProperty )
309+ && !validSecondaryProperties .contains (targetSdmProperty )) {
310+ invalidProperties .add (targetSdmProperty );
311+ logger .warn (
312+ "Copy validation - Attachment {} has invalid secondary property '{}'"
313+ + " (present in SDM response but not in valid secondary properties list)" ,
314+ objectId ,
315+ targetSdmProperty );
316+ }
317+ }
318+ return invalidProperties ;
319+ }
320+
321+ /** Builds and emits a warning message for copy failures. */
322+ private void buildAndWarnCopyFailures (
323+ List <Map <String , String >> copyFailures , AttachmentCopyEventContext context ) {
324+ StringBuilder warningMessage =
325+ new StringBuilder (SDMUtils .getErrorMessage ("FAILED_TO_COPY_ATTACHMENTS_PREFIX" ));
326+ for (Map <String , String > failure : copyFailures ) {
327+ warningMessage
328+ .append ("- ObjectId: " )
329+ .append (failure .get (OBJECT_ID_KEY ))
330+ .append (", Reason: " )
331+ .append (failure .get (FAILURE_REASON_KEY ))
332+ .append ("\n " );
333+ }
334+ context .getMessages ().warn (warningMessage .toString ());
335+ }
336+
271337 /**
272338 * Moves attachments from source entity to target entity in SDM. Executes moves in parallel,
273339 * updates database records, and cleans up source metadata. If any step fails, the operation is
0 commit comments