From f1dc7620477e26db40a91c43ded1dbfa8fe3ccc0 Mon Sep 17 00:00:00 2001 From: ed852m Date: Thu, 14 Mar 2019 11:18:48 +0000 Subject: [PATCH] Handle unexpected HTTP return codes Issue-ID: AAI-2263 Change-Id: I2510b7a2630918ffe17efbbf813c3e43b0b44d34 Signed-off-by: ed852m --- .../modelloader/entity/model/ModelArtifact.java | 97 +++++++++++++++------- .../entity/model/TestModelArtifactHandler.java | 45 ++++++++++ 2 files changed, 110 insertions(+), 32 deletions(-) diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java index 6974625..7c9b4c2 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java @@ -31,13 +31,11 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; - import org.onap.aai.modelloader.config.ModelLoaderConfig; +import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.restclient.client.OperationResult; - import org.w3c.dom.Node; @@ -90,20 +88,32 @@ public class ModelArtifact extends AbstractModelArtifact { /** * Test whether the specified resource (URL) can be requested successfully - * + * * @param aaiClient * @param distId * @param xmlResourceUrl * @return true if a request to GET this resource as XML media is successful (status OK) */ private boolean xmlResourceCanBeFetched(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { - OperationResult getResponse = aaiClient.getResource(xmlResourceUrl, distId, MediaType.APPLICATION_XML_TYPE); + OperationResult getResponse = getResourceModel(aaiClient, distId, xmlResourceUrl); return getResponse != null && getResponse.getResultCode() == Response.Status.OK.getStatusCode(); } + /** + * Test whether the specified resource (URL) can be requested successfully + * + * @param aaiClient + * @param distId + * @param xmlResourceUrl + * @return OperationResult the result of the operation + */ + private OperationResult getResourceModel(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { + return aaiClient.getResource(xmlResourceUrl, distId, MediaType.APPLICATION_XML_TYPE); + } + /** * PUT the specified XML resource - * + * * @param aaiClient * @param distId * @param resourceUrl @@ -118,42 +128,67 @@ public class ModelArtifact extends AbstractModelArtifact { @Override public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, - List completedArtifacts) { + List completedArtifacts) { if (config.useGizmo()) { return pushToGizmo(aaiClient, config, distId); } return pushToResources(aaiClient, config, distId, completedArtifacts); } - + private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List completedArtifacts) { - boolean success; + boolean success = false; // See whether the model is already present String resourceUrl = getModelUrl(config); + OperationResult result = getResourceModel(aaiClient, distId, resourceUrl); - if (xmlResourceCanBeFetched(aaiClient, distId, resourceUrl)) { - logInfoMsg(getType().toString() + " " + getModelInvariantId() + " already exists. Skipping ingestion."); - success = pushModelVersion(aaiClient, config, distId, completedArtifacts); + if (result != null) { + if (result.getResultCode() == Response.Status.OK.getStatusCode()) { + success = updateExistingModel(aaiClient, config, distId, completedArtifacts); + } else if (result.getResultCode() == Response.Status.NOT_FOUND.getStatusCode()) { + success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); + } else { + logModelUpdateFailure( + "Response code " + result.getResultCode() + " invalid for getting resource model"); + } } else { - // Assume that the model does not exist and attempt the PUT - success = putXmlResource(aaiClient, distId, resourceUrl, getPayload()); - if (success) { - completedArtifacts.add(this); + logModelUpdateFailure("Null response from RestClient"); + } - // Record state to remember that this is the first version of the model (just added). - firstVersionOfModel = true; + return success; + } - logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " successfully ingested."); - } else { - logErrorMsg( - FAILURE_MSG_PREFIX + getType().toString() + " " + getUniqueIdentifier() + ROLLBACK_MSG_SUFFIX); - } + private boolean createNewModel(AaiRestClient aaiClient, String distId, List completedArtifacts, + String resourceUrl) { + boolean success; + // Assume that the model does not exist and attempt the PUT + success = putXmlResource(aaiClient, distId, resourceUrl, getPayload()); + if (success) { + completedArtifacts.add(this); + + // Record state to remember that this is the first version of the model (just added). + firstVersionOfModel = true; + + logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); + } else { + logModelUpdateFailure("Error creating model. Skipping ingestion."); } + return success; + } + + private void logModelUpdateFailure(String message) { + logErrorMsg(FAILURE_MSG_PREFIX + getType() + " " + getUniqueIdentifier() + " " + message + ROLLBACK_MSG_SUFFIX); + } + private boolean updateExistingModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, + List completedArtifacts) { + boolean success; + logInfoMsg(getType() + " " + getModelInvariantId() + " already exists. Skipping ingestion."); + success = pushModelVersion(aaiClient, config, distId, completedArtifacts); return success; - } + } /** * @param aaiClient @@ -165,7 +200,7 @@ public class ModelArtifact extends AbstractModelArtifact { private boolean pushModelVersion(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List completedArtifacts) { if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(config))) { - logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion."); + logInfoMsg(getType() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion."); return true; } @@ -175,14 +210,12 @@ public class ModelArtifact extends AbstractModelArtifact { success = putXmlResource(aaiClient, distId, getModelVerUrl(config), nodeToString(getModelVer())); if (success) { completedArtifacts.add(this); - logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " successfully ingested."); + logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); } else { - logErrorMsg( - FAILURE_MSG_PREFIX + getType().toString() + " " + getUniqueIdentifier() + ROLLBACK_MSG_SUFFIX); + logModelUpdateFailure("Error pushing model"); } } catch (TransformerException e) { - logErrorMsg(FAILURE_MSG_PREFIX + getType().toString() + " " + getUniqueIdentifier() + ": " + e.getMessage() - + ROLLBACK_MSG_SUFFIX); + logModelUpdateFailure(e.getMessage()); success = false; } @@ -192,12 +225,12 @@ public class ModelArtifact extends AbstractModelArtifact { @Override public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) { - // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if + // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if // the model is partially loaded. if (config.useGizmo()) { return; } - + String url = getModelVerUrl(config); if (firstVersionOfModel) { // If this was the first version of the model which was added, we want to remove the entire diff --git a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java index 2a951a8..b7a8cf2 100644 --- a/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java +++ b/src/test/java/org/onap/aai/modelloader/entity/model/TestModelArtifactHandler.java @@ -120,5 +120,50 @@ public class TestModelArtifactHandler { assertThat(pushed, is(true)); handler.rollback(artifacts, "", aaiClient); } + + @Test + public void testPushNewModelsBadRequest() { + when(config.getAaiBaseUrl()).thenReturn(""); + when(config.getAaiModelUrl(any())).thenReturn(""); + when(config.getAaiNamedQueryUrl(any())).thenReturn(""); + + OperationResult getResult = mock(OperationResult.class); + when(aaiClient.getResource(any(), any(), any())).thenReturn(getResult); + when(getResult.getResultCode()).thenReturn(Response.Status.NOT_FOUND.getStatusCode()); + + OperationResult putResult = mock(OperationResult.class); + when(aaiClient.putResource(any(), any(), any(), any())).thenReturn(putResult); + when(putResult.getResultCode()).thenReturn(Response.Status.BAD_REQUEST.getStatusCode()); + + checkRollback(Collections.singletonList(new ModelArtifact())); + } + + @Test + public void testBadRequestResourceModelResult() { + when(config.getAaiBaseUrl()).thenReturn(""); + when(config.getAaiModelUrl(any())).thenReturn(""); + + OperationResult operationResult = mock(OperationResult.class); + when(aaiClient.getResource(any(), any(), any())).thenReturn(operationResult); + when(operationResult.getResultCode()).thenReturn(Response.Status.BAD_REQUEST.getStatusCode()); + + checkRollback(Collections.singletonList(new ModelArtifact())); + } + + @Test + public void testNullResourceModelResult() { + when(config.getAaiBaseUrl()).thenReturn(""); + when(config.getAaiModelUrl(any())).thenReturn(""); + when(aaiClient.getResource(any(), any(), any())).thenReturn(null); + + checkRollback(Collections.singletonList(new ModelArtifact())); + } + + private void checkRollback(List artifacts) { + ModelArtifactHandler handler = new ModelArtifactHandler(config); + boolean pushed = handler.pushArtifacts(artifacts, "", Collections.emptyList(), aaiClient); + assertThat(pushed, is(false)); + handler.rollback(artifacts, "", aaiClient); + } } -- 2.16.6