Add api for CNFO upgrade 24/126924/8
authorGrzegorz Wielgosinski <g.wielgosins@samsung.com>
Wed, 2 Feb 2022 08:56:32 +0000 (09:56 +0100)
committerGrzegorz Wielgosinski <g.wielgosins@samsung.com>
Wed, 23 Feb 2022 15:27:24 +0000 (16:27 +0100)
Issue-ID: SO-3845
Signed-off-by: Grzegorz Wielgosinski <g.wielgosins@samsung.com>
Change-Id: I8038742f15b1cc848c5f95186946c66bf0311479

so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/client/MulticloudClient.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/MulticloudInstanceRequest.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/upgrade/InstanceUpgradeRequest.java [new file with mode: 0644]
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/rest/CnfAdapterRest.java
so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeService.java [new file with mode: 0644]
so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeServiceTest.java [new file with mode: 0644]

index 762f192..605806b 100644 (file)
@@ -1,8 +1,30 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * Modifications Copyright (C) 2021 Orange.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
 package org.onap.so.adapters.cnf.client;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.onap.so.adapters.cnf.MulticloudConfiguration;
+import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
 import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheck;
 import org.onap.so.adapters.cnf.model.healthcheck.K8sRbInstanceHealthCheckSimple;
 import org.onap.so.adapters.cnf.model.statuscheck.K8sRbInstanceStatus;
@@ -39,6 +61,18 @@ public class MulticloudClient {
         this.objectMapper = new ObjectMapper();
     }
 
+    public String upgradeInstance(String instanceId, MulticloudInstanceRequest upgradeRequest) throws BadResponseException {
+        MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration);
+        multicloudApiUrl.setInstanceId(instanceId);
+        String endpoint = multicloudApiUrl.apiUrl() + "/upgrade";
+        ResponseEntity<String> result = restTemplate.exchange(endpoint, POST, getHttpEntity(upgradeRequest), String.class);
+        checkResponseStatusCode(result);
+        log.info("upgradeInstance response status: {}", result.getStatusCode());
+        String body = result.getBody();
+        log.debug("upgradeInstance response body: {}", body);
+        return body;
+    }
+
     public K8sRbInstanceStatus getInstanceStatus(String instanceId) throws BadResponseException {
         MulticloudApiUrl multicloudApiUrl = new MulticloudApiUrl(multicloudConfiguration);
         multicloudApiUrl.setInstanceId(instanceId);
@@ -105,14 +139,25 @@ public class MulticloudClient {
         }
     }
 
-    private HttpEntity<?> getHttpEntity() {
+    private HttpEntity<Void> getHttpEntity() {
+        HttpHeaders headers = getHttpHeaders();
+
+        return new HttpEntity<>(headers);
+    }
+
+    private HttpHeaders getHttpHeaders() {
         HttpHeaders headers = new HttpHeaders();
         List<MediaType> acceptableMediaTypes = new ArrayList<>();
         acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
         headers.setAccept(acceptableMediaTypes);
         headers.setContentType(MediaType.APPLICATION_JSON);
+        return headers;
+    }
 
-        return new HttpEntity<>(headers);
+    private <T> HttpEntity<T> getHttpEntity(T body) {
+        HttpHeaders headers = getHttpHeaders();
+
+        return new HttpEntity<>(body, headers);
     }
 
     private void checkResponseStatusCode(ResponseEntity<String> result) throws BadResponseException {
index 20af63e..fa58cfd 100644 (file)
@@ -84,4 +84,16 @@ public class MulticloudInstanceRequest {
         this.releaseName = releaseName;
     }
 
+    @Override
+    public String toString() {
+        return "MulticloudInstanceRequest{" +
+                "cloudRegion='" + cloudRegion + '\'' +
+                ", rbName='" + rbName + '\'' +
+                ", rbVersion='" + rbVersion + '\'' +
+                ", profileName='" + profileName + '\'' +
+                ", labels=" + labels +
+                ", overrideValues=" + overrideValues +
+                ", releaseName='" + releaseName + '\'' +
+                '}';
+    }
 }
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/upgrade/InstanceUpgradeRequest.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/model/upgrade/InstanceUpgradeRequest.java
new file mode 100644 (file)
index 0000000..a4a9ebf
--- /dev/null
@@ -0,0 +1,158 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * Modifications Copyright (C) 2021 Orange.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.adapters.cnf.model.upgrade;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.util.Map;
+import java.util.Objects;
+
+@JsonInclude(JsonInclude.Include.NON_NULL)
+@JsonIgnoreProperties(value = "true")
+public class InstanceUpgradeRequest {
+
+    @JsonProperty("modelInvariantId")
+    private String modelInvariantId;
+
+    @JsonProperty("modelCustomizationId")
+    private String modelCustomizationId;
+
+    @JsonProperty("k8sRBProfileName")
+    private String k8sRBProfileName;
+
+    @JsonProperty("k8sRBInstanceStatusCheck")
+    private boolean k8sRBInstanceStatusCheck;
+
+    @JsonProperty("cloudRegionId")
+    private String cloudRegionId;
+
+    @JsonProperty("vfModuleUUID")
+    private String vfModuleUUID;
+
+    @JsonProperty("labels")
+    private Map<String, String> labels;
+
+    @JsonProperty("override-values")
+    private Map<String, String> overrideValues;
+
+
+    public String getModelInvariantId() {
+        return modelInvariantId;
+    }
+
+    public void setModelInvariantId(String modelInvariantId) {
+        this.modelInvariantId = modelInvariantId;
+    }
+
+    public String getModelCustomizationId() {
+        return modelCustomizationId;
+    }
+
+    public void setModelCustomizationId(String modelCustomizationId) {
+        this.modelCustomizationId = modelCustomizationId;
+    }
+
+    public String getK8sRBProfileName() {
+        return k8sRBProfileName;
+    }
+
+    public void setK8sRBProfileName(String k8sRBProfileName) {
+        this.k8sRBProfileName = k8sRBProfileName;
+    }
+
+    public boolean isK8sRBInstanceStatusCheck() {
+        return k8sRBInstanceStatusCheck;
+    }
+
+    public void setK8sRBInstanceStatusCheck(boolean k8sRBInstanceStatusCheck) {
+        this.k8sRBInstanceStatusCheck = k8sRBInstanceStatusCheck;
+    }
+
+    public String getCloudRegionId() {
+        return cloudRegionId;
+    }
+
+    public void setCloudRegionId(String cloudRegionId) {
+        this.cloudRegionId = cloudRegionId;
+    }
+
+    public String getVfModuleUUID() {
+        return vfModuleUUID;
+    }
+
+    public void setVfModuleUUID(String vfModuleUUID) {
+        this.vfModuleUUID = vfModuleUUID;
+    }
+
+    public Map<String, String> getLabels() {
+        return labels;
+    }
+
+    public void setLabels(Map<String, String> labels) {
+        this.labels = labels;
+    }
+
+    public Map<String, String> getOverrideValues() {
+        return overrideValues;
+    }
+
+    public void setOverrideValues(Map<String, String> overrideValues) {
+        this.overrideValues = overrideValues;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        InstanceUpgradeRequest that = (InstanceUpgradeRequest) o;
+        return k8sRBInstanceStatusCheck == that.k8sRBInstanceStatusCheck &&
+                Objects.equals(modelInvariantId, that.modelInvariantId) &&
+                Objects.equals(modelCustomizationId, that.modelCustomizationId) &&
+                Objects.equals(k8sRBProfileName, that.k8sRBProfileName) &&
+                Objects.equals(cloudRegionId, that.cloudRegionId) &&
+                Objects.equals(vfModuleUUID, that.vfModuleUUID) &&
+                Objects.equals(labels, that.labels) &&
+                Objects.equals(overrideValues, that.overrideValues);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(modelInvariantId, modelCustomizationId, k8sRBProfileName, k8sRBInstanceStatusCheck, cloudRegionId, vfModuleUUID, labels, overrideValues);
+    }
+
+    @Override
+    public String toString() {
+        return "InstanceUpgradeRequest{" +
+                "modelInvariantId='" + modelInvariantId + '\'' +
+                ", modelCustomizationId='" + modelCustomizationId + '\'' +
+                ", k8sRBProfileName='" + k8sRBProfileName + '\'' +
+                ", k8sRBInstanceStatusCheck=" + k8sRBInstanceStatusCheck +
+                ", cloudRegionId='" + cloudRegionId + '\'' +
+                ", vfModuleUUID='" + vfModuleUUID + '\'' +
+                ", labels=" + labels +
+                ", overrideValues=" + overrideValues +
+                '}';
+    }
+
+}
index ee8a362..bc85dc4 100644 (file)
@@ -54,10 +54,12 @@ import org.onap.so.adapters.cnf.model.aai.AaiCallbackResponse;
 import org.onap.so.adapters.cnf.model.healthcheck.HealthCheckResponse;
 import org.onap.so.adapters.cnf.model.instantiation.AaiRequest;
 import org.onap.so.adapters.cnf.model.statuscheck.StatusCheckResponse;
+import org.onap.so.adapters.cnf.model.upgrade.InstanceUpgradeRequest;
 import org.onap.so.adapters.cnf.service.CnfAdapterService;
 import org.onap.so.adapters.cnf.service.aai.AaiService;
 import org.onap.so.adapters.cnf.service.healthcheck.HealthCheckService;
 import org.onap.so.adapters.cnf.service.statuscheck.SimpleStatusCheckService;
+import org.onap.so.adapters.cnf.service.upgrade.InstanceUpgradeService;
 import org.onap.so.client.exception.BadResponseException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -83,6 +85,7 @@ public class CnfAdapterRest {
     private final CloseableHttpClient httpClient = HttpClients.createDefault();
     private final SimpleStatusCheckService simpleStatusCheckService;
     private final HealthCheckService healthCheckService;
+    private final InstanceUpgradeService instanceUpgradeService;
     private final CnfAdapterService cnfAdapterService;
     private final SoCallbackClient callbackClient;
     private final AaiService aaiService;
@@ -91,18 +94,30 @@ public class CnfAdapterRest {
     @Autowired
     public CnfAdapterRest(SimpleStatusCheckService simpleStatusCheckService,
                           HealthCheckService healthCheckService,
+                          InstanceUpgradeService instanceUpgradeService,
                           CnfAdapterService cnfAdapterService,
                           SoCallbackClient callbackClient,
                           AaiService aaiService,
                           MulticloudConfiguration multicloudConfiguration) {
         this.simpleStatusCheckService = simpleStatusCheckService;
         this.healthCheckService = healthCheckService;
+        this.instanceUpgradeService = instanceUpgradeService;
         this.cnfAdapterService = cnfAdapterService;
         this.aaiService = aaiService;
         this.callbackClient = callbackClient;
         this.uri = multicloudConfiguration.getMulticloudUrl();
     }
 
+    @ResponseBody
+    @RequestMapping(value = {"/api/cnf-adapter/v1/instance/{instanceID}/upgrade"}, method = RequestMethod.POST,
+            produces = "application/json", consumes = "application/json")
+    public String upgrade(@PathVariable("instanceID") String instanceId,
+                          @RequestBody InstanceUpgradeRequest upgradeRequest) throws BadResponseException {
+        logger.info("upgrade called for instance {}.", instanceId);
+        return instanceUpgradeService.upgradeInstance(instanceId, upgradeRequest);
+    }
+
+
     @ResponseBody
     @RequestMapping(value = {"/api/cnf-adapter/v1/healthcheck"}, method = RequestMethod.POST,
             produces = "application/json")
diff --git a/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeService.java b/so-cnf-adapter-application/src/main/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeService.java
new file mode 100644 (file)
index 0000000..2fd26fb
--- /dev/null
@@ -0,0 +1,60 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * Modifications Copyright (C) 2021 Orange.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.adapters.cnf.service.upgrade;
+
+import org.onap.so.adapters.cnf.client.MulticloudClient;
+import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
+import org.onap.so.adapters.cnf.model.upgrade.InstanceUpgradeRequest;
+import org.onap.so.client.exception.BadResponseException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+
+@Service
+public class InstanceUpgradeService {
+
+    private static final Logger logger = LoggerFactory.getLogger(InstanceUpgradeService.class);
+
+    private final MulticloudClient instanceApi;
+
+    public InstanceUpgradeService(MulticloudClient multicloudClient) {
+        this.instanceApi = multicloudClient;
+    }
+
+    public String upgradeInstance(String instanceId, InstanceUpgradeRequest upgradeRequest) throws BadResponseException {
+        logger.debug("UpgradeService upgradeInstance for instanceId: {}- START", instanceId);
+        MulticloudInstanceRequest multicloudInstanceRequest = new MulticloudInstanceRequest();
+        if (upgradeRequest.getK8sRBProfileName() != null) {
+            multicloudInstanceRequest.setRbName(upgradeRequest.getModelInvariantId());
+            multicloudInstanceRequest.setRbVersion(upgradeRequest.getModelCustomizationId());
+            multicloudInstanceRequest.setProfileName(upgradeRequest.getK8sRBProfileName());
+            multicloudInstanceRequest.setCloudRegion(upgradeRequest.getCloudRegionId());
+            multicloudInstanceRequest.setLabels(upgradeRequest.getLabels());
+            multicloudInstanceRequest.setOverrideValues(upgradeRequest.getOverrideValues());
+        } else {
+            throw new NullPointerException("k8sProfileName should not be null");
+        }
+        logger.info("Upgrade request: {}", multicloudInstanceRequest);
+        logger.debug("UpgradeService upgradeInstance- END");
+        return instanceApi.upgradeInstance(instanceId, multicloudInstanceRequest);
+    }
+}
diff --git a/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeServiceTest.java b/so-cnf-adapter-application/src/test/java/org/onap/so/adapters/cnf/service/upgrade/InstanceUpgradeServiceTest.java
new file mode 100644 (file)
index 0000000..74d258d
--- /dev/null
@@ -0,0 +1,111 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Huawei Technologies Co., Ltd. All rights reserved.
+ * Modifications Copyright (C) 2021 Samsung Technologies Co.
+ * Modifications Copyright (C) 2021 Orange.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.adapters.cnf.service.upgrade;
+
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.adapters.cnf.client.MulticloudClient;
+import org.onap.so.adapters.cnf.model.MulticloudInstanceRequest;
+import org.onap.so.adapters.cnf.model.upgrade.InstanceUpgradeRequest;
+import org.onap.so.client.exception.BadResponseException;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@SpringBootTest
+@RunWith(MockitoJUnitRunner.class)
+public class InstanceUpgradeServiceTest {
+
+    @InjectMocks
+    private InstanceUpgradeService tested;
+
+    @Mock
+    MulticloudClient instanceApi;
+
+    @Captor
+    ArgumentCaptor<MulticloudInstanceRequest> multicloudInstanceRequestCaptor;
+
+
+    @Test
+    public void shouldUpgradeInstanceSuccessfully() throws BadResponseException {
+        // given
+        String instanceId = "instanceId";
+        InstanceUpgradeRequest upgradeRequest = mock(InstanceUpgradeRequest.class);
+        String k8sRBProfileName = "k8sRBProfileName";
+        String modelInvariantId = "modelInvariantId";
+        String modelCustomizationId = "modelCustomizationId";
+        String cloudRegionId = "cloudRegionId";
+        Map<String, String> labels = mock(Map.class);
+        Map<String, String> overrideValues = mock(Map.class);
+        String response = "response";
+
+        // when
+        when(upgradeRequest.getK8sRBProfileName()).thenReturn(k8sRBProfileName);
+        when(upgradeRequest.getModelInvariantId()).thenReturn(modelInvariantId);
+        when(upgradeRequest.getModelCustomizationId()).thenReturn(modelCustomizationId);
+        when(upgradeRequest.getCloudRegionId()).thenReturn(cloudRegionId);
+        when(upgradeRequest.getLabels()).thenReturn(labels);
+        when(upgradeRequest.getOverrideValues()).thenReturn(overrideValues);
+        when(instanceApi.upgradeInstance(eq(instanceId), any(MulticloudInstanceRequest.class))).thenReturn(response);
+
+        // than
+        String actual = tested.upgradeInstance(instanceId, upgradeRequest);
+
+        assertEquals(actual, response);
+        verify(instanceApi).upgradeInstance(eq(instanceId), multicloudInstanceRequestCaptor.capture());
+        MulticloudInstanceRequest requestCaptureValue = multicloudInstanceRequestCaptor.getValue();
+        assertEquals(requestCaptureValue.getRbName(), modelInvariantId);
+        assertEquals(requestCaptureValue.getRbVersion(), modelCustomizationId);
+        assertEquals(requestCaptureValue.getProfileName(), k8sRBProfileName);
+        assertEquals(requestCaptureValue.getLabels(), labels);
+        assertEquals(requestCaptureValue.getOverrideValues(), overrideValues);
+    }
+
+    @Test(expected = RuntimeException.class)
+    public void shouldThrowRuntimeExceptionWhenProfileNameIsNull() throws BadResponseException {
+        // given
+        String instanceId = "instanceId";
+        InstanceUpgradeRequest upgradeRequest = mock(InstanceUpgradeRequest.class);
+
+        // when
+        when(upgradeRequest.getK8sRBProfileName()).thenReturn(null);
+
+        // than
+
+        tested.upgradeInstance(instanceId, upgradeRequest);
+    }
+
+}
\ No newline at end of file