Refactor failure handling in http-participant

In the case, a http-participant fails to deploy an element,
it should responds with UNDEPLOYED on a DEPLOY order.

Issue-ID: POLICY-4694
Change-Id: I97d2660c7b91e4407ff3fa2cc51557b6c96a3a9e
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
index f294d47..f5fb030 100644
--- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
@@ -39,6 +39,7 @@
 import org.onap.policy.clamp.acm.participant.http.main.webclient.AcHttpClient;
 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.common.utils.coder.Coder;
@@ -91,31 +92,37 @@
     @Override
     public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
             throws PfModelException {
-        var configRequest = getConfigRequest(properties);
-        var restResponseMap = invokeHttpClient(configRequest);
-        var failedResponseStatus = restResponseMap.values().stream()
-                .filter(response -> !HttpStatus.valueOf(response.getKey()).is2xxSuccessful())
-                .collect(Collectors.toList());
-        if (failedResponseStatus.isEmpty()) {
+        try {
+            var configRequest = getConfigRequest(properties);
+            var restResponseMap = invokeHttpClient(configRequest);
+            var failedResponseStatus = restResponseMap.values().stream()
+                    .filter(response -> !HttpStatus.valueOf(response.getKey()).is2xxSuccessful())
+                    .collect(Collectors.toList());
+            if (failedResponseStatus.isEmpty()) {
+                intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                        DeployState.DEPLOYED, null, "Deployed");
+            } else {
+                intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                        DeployState.UNDEPLOYED, null, "Error on Invoking the http request: " + failedResponseStatus);
+            }
+        } catch (AutomationCompositionException e) {
             intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
-                    DeployState.DEPLOYED, null, "Deployed");
-        } else {
-            throw new PfModelException(Status.BAD_REQUEST, "Error on Invoking the http request: {}",
-                    failedResponseStatus);
+                    DeployState.UNDEPLOYED, null, e.getMessage());
         }
     }
 
-    private ConfigRequest getConfigRequest(Map<String, Object> properties) throws PfModelException {
+    private ConfigRequest getConfigRequest(Map<String, Object> properties) throws AutomationCompositionException {
         try {
             var configRequest = CODER.convert(properties, ConfigRequest.class);
             var violations = Validation.buildDefaultValidatorFactory().getValidator().validate(configRequest);
             if (!violations.isEmpty()) {
                 LOGGER.error("Violations found in the config request parameters: {}", violations);
-                throw new PfModelException(Status.BAD_REQUEST, "Constraint violations in the config request");
+                throw new AutomationCompositionException(Status.BAD_REQUEST,
+                        "Constraint violations in the config request");
             }
             return configRequest;
         } catch (CoderException e) {
-            throw new PfModelException(Status.BAD_REQUEST, "Error extracting ConfigRequest ", e);
+            throw new AutomationCompositionException(Status.BAD_REQUEST, "Error extracting ConfigRequest ", e);
         }
     }
 
diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java
index c71d73f..a88f93a 100644
--- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java
+++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/webclient/AcHttpClient.java
@@ -38,6 +38,7 @@
 import org.springframework.stereotype.Component;
 import org.springframework.web.reactive.function.BodyInserters;
 import org.springframework.web.reactive.function.client.WebClient;
+import org.springframework.web.reactive.function.client.WebClientRequestException;
 import org.springframework.web.util.UriComponentsBuilder;
 import reactor.core.publisher.Mono;
 
@@ -88,9 +89,12 @@
                         new ImmutablePair<>(request.getExpectedResponse(), response));
 
             } catch (HttpWebClientException ex) {
-                LOGGER.error("Error occurred on the HTTP request ", ex);
+                LOGGER.error("Error occurred on the HTTP response ", ex);
                 responseMap.put(request.getRestRequestId(),
                         new ImmutablePair<>(ex.getStatusCode().value(), ex.getResponseBodyAsString()));
+            } catch (WebClientRequestException ex) {
+                LOGGER.error("Error occurred on the HTTP request ", ex);
+                responseMap.put(request.getRestRequestId(), new ImmutablePair<>(404, ex.getMessage()));
             }
         }
     }
diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
index e0d6c80..b0e05d7 100644
--- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
@@ -20,7 +20,6 @@
 
 package org.onap.policy.clamp.acm.participant.http.handler;
 
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyMap;
 import static org.mockito.Mockito.mock;
@@ -37,6 +36,7 @@
 import org.onap.policy.clamp.acm.participant.http.utils.ToscaUtils;
 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.models.base.PfModelException;
 
 class AcElementHandlerTest {
 
@@ -61,16 +61,35 @@
     }
 
     @Test
-    void testDeployError() throws IOException {
+    void testDeployConstraintViolations() throws IOException, PfModelException {
         var instanceId = commonTestData.getAutomationCompositionId();
         var element = commonTestData.getAutomationCompositionElement();
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
 
         try (var automationCompositionElementHandler =
                 new AutomationCompositionElementHandler(mock(AcHttpClient.class))) {
-            automationCompositionElementHandler.setIntermediaryApi(mock(ParticipantIntermediaryApi.class));
+            automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi);
             Map<String, Object> map = new HashMap<>();
-            assertThatThrownBy(() -> automationCompositionElementHandler.deploy(instanceId, element, map))
-                    .hasMessage("Constraint violations in the config request");
+            automationCompositionElementHandler.deploy(instanceId, element, map);
+            verify(participantIntermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                    DeployState.UNDEPLOYED, null, "Constraint violations in the config request");
+        }
+    }
+
+    @Test
+    void testDeployError() throws IOException, PfModelException {
+        var instanceId = commonTestData.getAutomationCompositionId();
+        var element = commonTestData.getAutomationCompositionElement();
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+
+        try (var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(mock(AcHttpClient.class))) {
+            automationCompositionElementHandler.setIntermediaryApi(participantIntermediaryApi);
+            Map<String, Object> map = new HashMap<>();
+            map.put("httpHeaders", 1);
+            automationCompositionElementHandler.deploy(instanceId, element, map);
+            verify(participantIntermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                    DeployState.UNDEPLOYED, null, "Error extracting ConfigRequest ");
         }
     }
 
@@ -91,6 +110,5 @@
             verify(participantIntermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
                     DeployState.DEPLOYED, null, "Deployed");
         }
-
     }
 }
diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java
index d8e0c9b..56170eb 100644
--- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java
+++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/webclient/AcHttpClientTest.java
@@ -47,7 +47,8 @@
 
     private static int mockServerPort;
 
-    private final String testMockUrl = "http://localhost";
+    private static final String MOCK_URL = "http://localhost";
+    private static final String WRONG_URL = "http://wrong-url";
 
     private static MockServerRest mockServer;
 
@@ -76,7 +77,7 @@
 
         var headers = commonTestData.getHeaders();
         var configRequest =
-                new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, List.of(configurationEntity), 10);
+                new ConfigRequest(MOCK_URL + ":" + mockServerPort, headers, List.of(configurationEntity), 10);
 
         var client = new AcHttpClient();
         assertDoesNotThrow(() -> client.run(configRequest, responseMap));
@@ -94,7 +95,24 @@
 
         var headers = commonTestData.getHeaders();
         var configRequest =
-                new ConfigRequest(testMockUrl + ":" + mockServerPort, headers, List.of(configurationEntity), 10);
+                new ConfigRequest(MOCK_URL + ":" + mockServerPort, headers, List.of(configurationEntity), 10);
+
+        var client = new AcHttpClient();
+        assertDoesNotThrow(() -> client.run(configRequest, responseMap));
+        assertThat(responseMap).hasSize(2).containsKey(commonTestData.restParamsWithGet().getRestRequestId());
+        var response = responseMap.get(commonTestData.restParamsWithInvalidPost().getRestRequestId());
+        assertThat(response.getKey()).isEqualTo(404);
+    }
+
+    @Test
+    void test_WrongUrl() {
+        // Add rest requests Invalid URL
+        var configurationEntity = commonTestData.getInvalidConfigurationEntity();
+        Map<ToscaConceptIdentifier, Pair<Integer, String>> responseMap = new HashMap<>();
+
+        var headers = commonTestData.getHeaders();
+        var configRequest =
+                new ConfigRequest(WRONG_URL + ":" + mockServerPort, headers, List.of(configurationEntity), 10);
 
         var client = new AcHttpClient();
         assertDoesNotThrow(() -> client.run(configRequest, responseMap));