From a542f19d421229508c4408583e552c4c0eba84f1 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Tue, 9 Apr 2024 09:39:16 +0200 Subject: Listing distributions (/services/{distributionId}/distribution/) fails with ClassCastException - attempt to format AuditEvent timestamp when it's of long type - do not update gem package in docker builds since newer versions are incompatible with ruby 2.7.6 Issue-ID: SDC-4682 Signed-off-by: Fiete Ostkamp Change-Id: I6ff3ac6bfa3ce7985c69df3eb79f9711b753800f --- .gitignore | 4 ++ catalog-be/sdc-backend-init/Dockerfile | 3 +- catalog-be/src/main/docker/backend/Dockerfile | 3 +- .../impl/DistributionMonitoringBusinessLogic.java | 42 +++++++++---- .../be/info/DistributionStatusListResponse.java | 10 ++-- .../DistributionStatusOfServiceListResponce.java | 11 ++-- .../DistributionMonitoringBusinessLogicTest.java | 70 +++++++++++++++------- catalog-fe/sdc-frontend/Dockerfile | 3 +- .../artifacts/Dockerfile | 3 +- utils/webseal-simulator/sdc-simulator/Dockerfile | 3 +- 10 files changed, 100 insertions(+), 52 deletions(-) diff --git a/.gitignore b/.gitignore index fce6bc9439..18c83d48dc 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,10 @@ *.ipr *.iws +# VSCode IDE +#------------------------------------------------------------ +.vscode/ + # Logs #------------------------------------------------------------ *.log diff --git a/catalog-be/sdc-backend-init/Dockerfile b/catalog-be/sdc-backend-init/Dockerfile index 4013733259..81a2a615bf 100644 --- a/catalog-be/sdc-backend-init/Dockerfile +++ b/catalog-be/sdc-backend-init/Dockerfile @@ -1,4 +1,4 @@ -FROM onap/integration-python:8.0.0 +FROM onap/integration-python:9.0.0 USER root @@ -22,7 +22,6 @@ RUN apk update && \ python -m pip install --upgrade pip \ pip install 'pycurl==7.44.1' && \ set -ex && \ - gem update --system --no-document && \ gem install --no-update-sources public_suffix:4.0.7 multipart-post:2.2.0 etc:1.3.0 bundler:2.3.26 chef:13.8.5 berkshelf:6.3.1 io-console:0.4.6 webrick --no-document && \ apk del .build-dependencies && \ gem cleanup diff --git a/catalog-be/src/main/docker/backend/Dockerfile b/catalog-be/src/main/docker/backend/Dockerfile index 5ac5350e66..9d9d7f3e0a 100644 --- a/catalog-be/src/main/docker/backend/Dockerfile +++ b/catalog-be/src/main/docker/backend/Dockerfile @@ -1,4 +1,4 @@ -FROM onap/integration-java11:12.0.0 +FROM onap/integration-java11:10.0.0 USER root ARG JETTY_FOLDER=/app/jetty @@ -13,7 +13,6 @@ RUN set -ex && \ ruby-dev \ libffi-dev \ libxml2-dev && \ - gem update --system --no-document && \ gem install --no-update-sources public_suffix:4.0.7 multipart-post:2.2.0 etc:1.3.0 bundler:2.3.26 chef:13.8.5 berkshelf:6.3.1 io-console:0.4.6 webrick --no-document && \ gem cleanup && \ apk update diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java index f3334e6177..77bd9f3396 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java @@ -20,12 +20,16 @@ package org.openecomp.sdc.be.components.impl; import fj.data.Either; +import java.time.Instant; +import java.time.ZoneOffset; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; import org.apache.http.HttpStatus; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; @@ -44,6 +48,7 @@ import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; import org.openecomp.sdc.be.resources.data.auditing.DistributionStatusEvent; import org.openecomp.sdc.common.datastructure.AuditingFieldsKey; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; @@ -52,11 +57,11 @@ import org.springframework.stereotype.Component; @Component("distributionMonitoringBusinessLogic") public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { + private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName()); private static final String DEPLOYED = "Deployed"; private static final String ERROR = "Error"; private static final String DISTRIBUTED = "Distributed"; private static final String IN_PROGRESS = "In Progress"; - private static final Logger log = Logger.getLogger(ArtifactsBusinessLogic.class.getName()); private final AuditCassandraDao cassandraDao; @Autowired @@ -77,13 +82,11 @@ public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { log.debug("not found distribution statuses for did {} status is {} ", did, distributionStatus.right().value()); return Either.right(componentsUtils.getResponseFormat(distributionStatus.right().value(), did)); } - List distribStatusInfoList = new ArrayList<>(); - List distributionStatusEventList = distributionStatus.left().value(); - if (distributionStatusEventList != null) { - for (AuditingGenericEvent distributionStatusEvent : distributionStatusEventList) { - distribStatusInfoList.add(new DistributionStatusInfo(distributionStatusEvent)); - } - } + List distribStatusInfoList = distributionStatus.left().value().stream() + .filter(Objects::nonNull) + .map(DistributionStatusInfo::new) + .collect(Collectors.toList()); + DistributionStatusListResponse distributionStatusListResponse = new DistributionStatusListResponse(); distributionStatusListResponse.setDistributionStatusList(distribStatusInfoList); log.trace("list statuses for did {} is {} ", did, distribStatusInfoList); @@ -98,11 +101,9 @@ public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { log.debug("failed to find service distribution statuses. error: {}", status); return Either.right(componentsUtils.getResponseFormat(status.right().value(), serviceUuid)); } - List distribStatusInfoList; List distributionStatusEventList = status.left().value(); - distribStatusInfoList = handleAuditingDaoResponse(distributionStatusEventList); - DistributionStatusOfServiceListResponce distributionStatusListResponse = new DistributionStatusOfServiceListResponce(); - distributionStatusListResponse.setDistributionStatusOfServiceList(distribStatusInfoList); + List distributionStatusInfoList = handleAuditingDaoResponse(distributionStatusEventList); + DistributionStatusOfServiceListResponce distributionStatusListResponse = new DistributionStatusOfServiceListResponce(distributionStatusInfoList); return Either.left(distributionStatusListResponse); } @@ -140,7 +141,7 @@ public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { Map fields = resAuditingGenericEvent.getFields(); if (fields != null) { Optional.ofNullable(fields.get(AuditingFieldsKey.AUDIT_TIMESTAMP.getDisplayName())) - .ifPresent(timestamp -> distributionStatusOfServiceInfo.setTimestamp((String) timestamp)); + .ifPresent(timestamp -> distributionStatusOfServiceInfo.setTimestamp(formatTimestamp(timestamp))); } } if (!isResult) { @@ -165,6 +166,21 @@ public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { return reslist; } + private String formatTimestamp(Object timestamp) { + if(timestamp instanceof String) { + return (String) timestamp; + } else if (timestamp instanceof Long) { + try { + return Instant.ofEpochMilli((Long) timestamp).atOffset(ZoneOffset.UTC).toString(); + } catch (Exception e) { + log.warn(EcompLoggerErrorCode.DATA_ERROR, "sdc-be", "Failed to format timestamp: {}. Returning without formatting", timestamp, e); + return String.valueOf(timestamp); + } + } else { + return String.valueOf(timestamp); + } + } + private String getStatusFromAuditEvent(AuditingGenericEvent auditingGenericEvent) { String status = ""; Object requestStatus = auditingGenericEvent.getFields().get(AuditingFieldsKey.AUDIT_STATUS.getDisplayName()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java index acd0c47e38..6f716cbeae 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java @@ -20,11 +20,13 @@ package org.openecomp.sdc.be.info; import java.util.List; -import lombok.Getter; -import lombok.Setter; -@Getter -@Setter +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor public class DistributionStatusListResponse { private List distributionStatusList; diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java index b5e97585f0..81b56819e0 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java @@ -20,11 +20,14 @@ package org.openecomp.sdc.be.info; import java.util.List; -import lombok.Getter; -import lombok.Setter; -@Getter -@Setter +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.AllArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor public class DistributionStatusOfServiceListResponce { private List distributionStatusOfServiceList; diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogicTest.java index 7b111ba52f..4681a4d01b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogicTest.java @@ -36,6 +36,7 @@ import org.openecomp.sdc.be.info.DistributionStatusListResponse; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; import org.openecomp.sdc.be.resources.data.auditing.DistributionStatusEvent; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKey; import org.openecomp.sdc.exception.ResponseFormat; import java.util.ArrayList; @@ -49,21 +50,16 @@ import static org.mockito.Mockito.when; public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMock { - private String uId; + private String userId; private User user; - private String ditributionId; + private String distributionId; private String serviceId; private DistributionMonitoringBusinessLogic businessLogic; - @Mock - private AuditCassandraDao cassandraDao; - - @Mock - private UserValidations userValidations; - - @Mock - private ComponentsUtils componentsUtils; + @Mock private AuditCassandraDao cassandraDao; + @Mock private UserValidations userValidations; + @Mock private ComponentsUtils componentsUtils; @Before public void setUp() { @@ -75,20 +71,20 @@ public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMo businessLogic.setComponentsUtils(componentsUtils); user = new User(); - uId = "userId"; - ditributionId = "did"; + userId = "userId"; + distributionId = "did"; serviceId = "serviceId"; - when(userValidations.validateUserExists(Mockito.eq(uId))) + when(userValidations.validateUserExists(Mockito.eq(userId))) .thenReturn(user); } @Test public void testGetListOfDistribution_givenInvalidDistributionId_thenReturnsError() { - when(cassandraDao.getListOfDistributionStatuses(ditributionId)) + when(cassandraDao.getListOfDistributionStatuses(distributionId)) .thenReturn(Either.right(ActionStatus.DISTRIBUTION_NOT_FOUND)); - assertTrue(businessLogic.getListOfDistributionStatus(ditributionId, uId).isRight()); + assertTrue(businessLogic.getListOfDistributionStatus(distributionId, userId).isRight()); } @Test @@ -98,10 +94,10 @@ public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMo DistributionStatusEvent event = new DistributionStatusEvent(); distributionEvents.add(event); - when(cassandraDao.getListOfDistributionStatuses(ditributionId)) + when(cassandraDao.getListOfDistributionStatuses(distributionId)) .thenReturn(Either.left(distributionEvents)); - Either result = businessLogic.getListOfDistributionStatus(ditributionId, uId); + Either result = businessLogic.getListOfDistributionStatus(distributionId, userId); assertTrue(result.isLeft()); assertEquals(1, result.left().value().getDistributionStatusList().size()); @@ -112,7 +108,7 @@ public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMo when(cassandraDao.getServiceDistributionStatusesList(serviceId)) .thenReturn(Either.right(ActionStatus.DISTRIBUTION_NOT_FOUND)); - assertTrue(businessLogic.getListOfDistributionServiceStatus(serviceId, uId).isRight()); + assertTrue(businessLogic.getListOfDistributionServiceStatus(serviceId, userId).isRight()); } @Test @@ -128,13 +124,45 @@ public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMo event1Fields.put("DID", "event1"); event1Fields.put("ACTION", "DRequest"); event1Fields.put("STATUS", "200"); - event1Fields.put("MODIFIER", uId); + event1Fields.put("MODIFIER", userId); + + event2Fields.put("DID", "event2"); + event2Fields.put("ACTION", "DNotify"); + event2Fields.put("STATUS", "200"); + event2Fields.put("MODIFIER", userId); + + event1.setFields(event1Fields); + event2.setFields(event2Fields); + + serviceEvents.add(event1); + serviceEvents.add(event2); + + when(cassandraDao.getServiceDistributionStatusesList(serviceId)) + .thenReturn(Either.left(serviceEvents)); + + assertTrue(businessLogic.getListOfDistributionServiceStatus(serviceId, userId).isLeft()); + } + + @Test + public void testGetDistributionServiceStatus_givenLongTimeStamp_thenReturnsSuccessful() { + + Map event1Fields = new HashMap<>(); + event1Fields.put("DID", "event1"); + event1Fields.put("ACTION", "DRequest"); + event1Fields.put("STATUS", "200"); + event1Fields.put("MODIFIER", userId); + event1Fields.put(AuditingFieldsKey.AUDIT_TIMESTAMP.getDisplayName(), "2024-04-05 07:29:10.735 UTC"); + Map event2Fields = new HashMap<>(); event2Fields.put("DID", "event2"); event2Fields.put("ACTION", "DNotify"); event2Fields.put("STATUS", "200"); - event2Fields.put("MODIFIER", uId); + event2Fields.put("MODIFIER", userId); + event1Fields.put(AuditingFieldsKey.AUDIT_TIMESTAMP.getDisplayName(), 1712645750L); + List serviceEvents = new ArrayList<>(); + AuditingGenericEvent event1 = new AuditingGenericEvent(); + AuditingGenericEvent event2 = new AuditingGenericEvent(); event1.setFields(event1Fields); event2.setFields(event2Fields); @@ -144,6 +172,6 @@ public class DistributionMonitoringBusinessLogicTest extends BaseBusinessLogicMo when(cassandraDao.getServiceDistributionStatusesList(serviceId)) .thenReturn(Either.left(serviceEvents)); - assertTrue(businessLogic.getListOfDistributionServiceStatus(serviceId, uId).isLeft()); + assertTrue(businessLogic.getListOfDistributionServiceStatus(serviceId, userId).isLeft()); } } \ No newline at end of file diff --git a/catalog-fe/sdc-frontend/Dockerfile b/catalog-fe/sdc-frontend/Dockerfile index cf75c7a1fe..a6d2894484 100644 --- a/catalog-fe/sdc-frontend/Dockerfile +++ b/catalog-fe/sdc-frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM onap/integration-java11:12.0.0 +FROM onap/integration-java11:10.0.0 USER root ARG JETTY_FOLDER=/app/jetty @@ -13,7 +13,6 @@ RUN set -ex && \ ruby-dev \ libffi-dev \ libxml2-dev && \ - gem update --system --no-document && \ gem install --no-update-sources public_suffix:4.0.7 multipart-post:2.2.0 etc:1.3.0 bundler:2.3.26 chef:13.8.5 berkshelf:6.3.1 io-console:0.4.6 webrick --no-document && \ gem cleanup && \ apk update diff --git a/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/Dockerfile b/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/Dockerfile index 8ccdcc52e8..9fb9c4ee53 100644 --- a/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/Dockerfile +++ b/openecomp-be/dist/sdc-onboard-backend-docker/artifacts/Dockerfile @@ -1,4 +1,4 @@ -FROM onap/integration-java11:12.0.0 +FROM onap/integration-java11:10.0.0 USER root ARG JETTY_FOLDER=/app/jetty @@ -14,7 +14,6 @@ RUN set -ex && \ libffi-dev \ libxml2-dev \ libressl-dev && \ - gem update --system --no-document && \ gem install --no-update-sources public_suffix:4.0.7 multipart-post:2.2.0 etc:1.3.0 bundler:2.3.26 chef:13.8.5 berkshelf:6.3.1 io-console:0.4.6 webrick --no-document && \ gem cleanup && \ apk update diff --git a/utils/webseal-simulator/sdc-simulator/Dockerfile b/utils/webseal-simulator/sdc-simulator/Dockerfile index 6b7b9d1957..c3758e1cbd 100644 --- a/utils/webseal-simulator/sdc-simulator/Dockerfile +++ b/utils/webseal-simulator/sdc-simulator/Dockerfile @@ -1,4 +1,4 @@ -FROM onap/integration-java11:12.0.0 +FROM onap/integration-java11:10.0.0 USER root ARG JETTY_FOLDER=/app/jetty @@ -13,7 +13,6 @@ RUN set -ex && \ ruby-dev \ libffi-dev \ libxml2-dev && \ - gem update --system --no-document && \ gem install --no-update-sources public_suffix:4.0.7 multipart-post:2.2.0 etc:1.3.0 bundler:2.3.26 chef:13.8.5 berkshelf:6.3.1 io-console:0.4.6 webrick --no-document && \ gem cleanup && \ apk update -- cgit 1.2.3-korg