Adding support for registration of kubernetes 16/133016/1
authorwaqas.ikram <waqas.ikram@est.tech>
Wed, 25 Jan 2023 11:47:41 +0000 (11:47 +0000)
committerwaqas.ikram <waqas.ikram@est.tech>
Wed, 25 Jan 2023 11:48:27 +0000 (11:48 +0000)
clusters and fixing code smells

Change-Id: I2d10c263e255ca8644539de9c47c9a4fed04997f
Issue-ID: SO-4050
Signed-off-by: waqas.ikram <waqas.ikram@est.tech>
13 files changed:
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-application/src/main/java/org/onap/so/cnfm/lcm/app/DefaultToShortClassNameBeanNameGenerator.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileNotFoundException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileUploadException.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcClientConfigurationProvider.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/extclients/sdc/SdcCsarPackageParser.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/JobExecutorService.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProvider.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProviderImpl.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/WorkflowQueryService.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/tasks/CreateAsTask.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/utils/PropertiesToYamlConverter.java
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/main/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigController.java [new file with mode: 0644]
so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/test/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigControllerTest.java [new file with mode: 0644]

index dbf5e02..2683b03 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.onap.so.cnfm.lcm.app;
 
+import static org.slf4j.LoggerFactory.getLogger;
+import org.slf4j.Logger;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.context.annotation.AnnotationBeanNameGenerator;
 import org.springframework.util.ClassUtils;
@@ -28,9 +30,14 @@ import org.springframework.util.ClassUtils;
  *
  */
 public class DefaultToShortClassNameBeanNameGenerator extends AnnotationBeanNameGenerator {
+    private static final Logger logger = getLogger(DefaultToShortClassNameBeanNameGenerator.class);
 
     @Override
     protected String buildDefaultBeanName(final BeanDefinition definition) {
-        return ClassUtils.getShortName(definition.getBeanClassName());
+        if (definition.getBeanClassName() != null) {
+            return ClassUtils.getShortName(definition.getBeanClassName());
+        }
+        logger.warn("Bean class name is not specified...");
+        return null;
     }
 }
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileNotFoundException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileNotFoundException.java
new file mode 100644 (file)
index 0000000..24eb8b1
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.bpmn.flows.exceptions;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class KubeConfigFileNotFoundException extends Exception {
+
+    private static final long serialVersionUID = -7347276762841623563L;
+
+    public KubeConfigFileNotFoundException(final String message) {
+        super(message);
+    }
+
+    public KubeConfigFileNotFoundException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileUploadException.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/exceptions/KubeConfigFileUploadException.java
new file mode 100644 (file)
index 0000000..caee609
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.bpmn.flows.exceptions;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public class KubeConfigFileUploadException extends RuntimeException {
+
+    private static final long serialVersionUID = -7347276762841623563L;
+
+    public KubeConfigFileUploadException(final String message) {
+        super(message);
+    }
+
+    public KubeConfigFileUploadException(final String message, final Throwable cause) {
+        super(message, cause);
+    }
+
+}
index 4ae1d43..dd47bad 100644 (file)
@@ -24,8 +24,6 @@ import java.security.GeneralSecurityException;
 import org.apache.commons.codec.binary.Base64;
 import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.BasicAuthConfigException;
 import org.onap.so.utils.CryptoUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Configuration;
 
@@ -36,8 +34,6 @@ import org.springframework.context.annotation.Configuration;
 @Configuration
 public class SdcClientConfigurationProvider {
 
-    private static final Logger logger = LoggerFactory.getLogger(SdcClientConfigurationProvider.class);
-
     @Value("${sdc.username:mso}")
     private String sdcUsername;
 
@@ -52,20 +48,14 @@ public class SdcClientConfigurationProvider {
 
     private static String basicAuth = null;
 
-
-    public String getBasicAuth() {
+    public synchronized String getBasicAuth() {
         if (basicAuth == null) {
-            synchronized (this) {
-                if (basicAuth == null) {
-                    try {
-                        final String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey);
-                        final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
-                        basicAuth = "Basic " + new String(encodedAuth);
-                    } catch (final GeneralSecurityException exception) {
-                        logger.error("Unable to process basic auth information", exception);
-                        throw new BasicAuthConfigException("Unable to process basic auth information", exception);
-                    }
-                }
+            try {
+                final String auth = sdcUsername + ":" + CryptoUtils.decrypt(sdcPassword, sdcKey);
+                final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
+                basicAuth = "Basic " + new String(encodedAuth);
+            } catch (final GeneralSecurityException exception) {
+                throw new BasicAuthConfigException("Unable to process basic auth information", exception);
             }
         }
         return basicAuth;
index 0ade7bf..c06d42f 100644 (file)
@@ -82,7 +82,7 @@ public class SdcCsarPackageParser {
                 final String type = childElement(child, "type").getAsString();
                 if ("tosca.nodes.asd".equals(type)) {
                     final JsonObject properties = child(child, "properties");
-                    logger.debug("properties: {}", properties.toString());
+                    logger.debug("properties: {}", properties);
                     final Map<String, Object> propertiesValues = new HashMap<>();
                     propertiesValues.put(DESCRIPTOR_ID_PARAM_NAME,
                             getStringValue(properties, DESCRIPTOR_ID_PARAM_NAME));
@@ -134,9 +134,9 @@ public class SdcCsarPackageParser {
     private List<String> getLifecycleParameters(final JsonObject artifactsProperties) {
         final JsonArray lcParameters = childElement(artifactsProperties, "lifecycle_parameters").getAsJsonArray();
         final List<String> lifecycleParameters = new ArrayList<>();
-        if(lcParameters != null) {
+        if (lcParameters != null) {
             final Iterator<JsonElement> it = lcParameters.iterator();
-            while(it.hasNext()){
+            while (it.hasNext()) {
                 lifecycleParameters.add(it.next().getAsString());
             }
         }
index c4bd210..0f6e8d0 100644 (file)
@@ -39,6 +39,7 @@ import java.time.LocalDateTime;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.onap.so.cnfm.lcm.bpmn.flows.GsonProvider;
@@ -61,7 +62,6 @@ import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
-import com.google.common.collect.ImmutableSet;
 import com.google.gson.Gson;
 
 /**
@@ -73,8 +73,7 @@ public class JobExecutorService {
 
     private static final Logger logger = getLogger(JobExecutorService.class);
 
-    private static final ImmutableSet<JobStatusEnum> JOB_FINISHED_STATES =
-            ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR);
+    private static final Set<JobStatusEnum> JOB_FINISHED_STATES = Set.of(FINISHED, ERROR, FINISHED_WITH_ERROR);
 
     private static final int SLEEP_TIME_IN_SECONDS = 5;
 
@@ -103,7 +102,7 @@ public class JobExecutorService {
                 .status(JobStatusEnum.STARTING);
         databaseServiceProvider.addJob(newJob);
 
-        logger.info("New job created in database :\n{}", newJob);
+        logger.info("New job created in database for CreateAs:\n{}", newJob);
 
         workflowExecutorService.executeWorkflow(newJob.getJobId(), CREATE_AS_WORKFLOW_NAME,
                 getVariables(newJob.getJobId(), createAsRequest));
@@ -130,8 +129,8 @@ public class JobExecutorService {
                 throw new AsRequestProcessingException(message, errorDetails);
             }
 
-            final String message = "Received unexpected Job Status: " + finalJobStatus
-                    + " Failed to Create AS for request: \n" + createAsRequest;
+            final String message = "Create AS request failed. Received unexpected Job Status: " + finalJobStatus
+                    + " Create As request: \n" + createAsRequest;
             logger.error(message);
             throw new AsRequestProcessingException(message);
         }
@@ -151,7 +150,7 @@ public class JobExecutorService {
         final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.INSTANTIATE)
                 .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
         databaseServiceProvider.addJob(newJob);
-        logger.info("New job created in database :\n{}", newJob);
+        logger.info("New job created in database for InstantiateAs :\n{}", newJob);
 
         final LocalDateTime currentDateTime = LocalDateTime.now();
         final AsLcmOpOcc newAsLcmOpOcc = new AsLcmOpOcc().id(asInstanceId).operation(AsLcmOpType.INSTANTIATE)
@@ -164,8 +163,7 @@ public class JobExecutorService {
         workflowExecutorService.executeWorkflow(newJob.getJobId(), INSTANTIATE_AS_WORKFLOW_NAME,
                 getVariables(asInstanceId, newJob.getJobId(), newAsLcmOpOcc.getId(), instantiateAsRequest));
 
-        final ImmutableSet<JobStatusEnum> jobFinishedStates =
-                ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+        final Set<JobStatusEnum> jobFinishedStates = Set.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
         final ImmutablePair<String, JobStatusEnum> immutablePair =
                 waitForJobToFinish(newJob.getJobId(), jobFinishedStates);
 
@@ -181,8 +179,8 @@ public class JobExecutorService {
             return newAsLcmOpOcc.getId();
         }
 
-        final String message = "Received unexpected Job Status: " + finalJobStatus
-                + " Failed to instantiate AS for request: \n" + instantiateAsRequest;
+        final String message = "Instantiate AS request failed. Received unexpected Job Status: " + finalJobStatus
+                + " Instantiate AS request: \n" + instantiateAsRequest;
         logger.error(message);
         throw new AsRequestProcessingException(message);
     }
@@ -193,7 +191,7 @@ public class JobExecutorService {
         final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.TERMINATE)
                 .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
         databaseServiceProvider.addJob(newJob);
-        logger.info("New job created in database :\n{}", newJob);
+        logger.info("New job created in database for TerminateAs :\n{}", newJob);
 
         final LocalDateTime currentDateTime = LocalDateTime.now();
         final AsLcmOpOcc newAsLcmOpOcc = new AsLcmOpOcc().id(asInstanceId).operation(AsLcmOpType.TERMINATE)
@@ -206,8 +204,7 @@ public class JobExecutorService {
         workflowExecutorService.executeWorkflow(newJob.getJobId(), TERMINATE_AS_WORKFLOW_NAME,
                 getVariables(asInstanceId, newJob.getJobId(), newAsLcmOpOcc.getId(), terminateAsRequest));
 
-        final ImmutableSet<JobStatusEnum> jobFinishedStates =
-                ImmutableSet.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
+        final Set<JobStatusEnum> jobFinishedStates = Set.of(FINISHED, ERROR, FINISHED_WITH_ERROR, IN_PROGRESS);
         final ImmutablePair<String, JobStatusEnum> immutablePair =
                 waitForJobToFinish(newJob.getJobId(), jobFinishedStates);
 
@@ -225,8 +222,8 @@ public class JobExecutorService {
             return newAsLcmOpOcc.getId();
         }
 
-        final String message = "Received unexpected Job Status: " + finalJobStatus + " Failed to Terminate AS with id: "
-                + asInstanceId + " for request: \n" + terminateAsRequest;
+        final String message = "Terminate AS request failed. Received unexpected Job Status: " + finalJobStatus
+                + " id: " + asInstanceId + " Terminate AS request: \n" + terminateAsRequest;
         logger.error(message);
         throw new AsRequestProcessingException(message);
     }
@@ -235,7 +232,7 @@ public class JobExecutorService {
         final Job newJob = new Job().startTime(LocalDateTime.now()).jobType("AS").jobAction(JobAction.DELETE)
                 .resourceId(asInstanceId).status(JobStatusEnum.STARTING);
         databaseServiceProvider.addJob(newJob);
-        logger.info("New job created in database :\n{}", newJob);
+        logger.info("New job created in database for DeleteAs :\n{}", newJob);
 
         workflowExecutorService.executeWorkflow(newJob.getJobId(), DELETE_AS_WORKFLOW_NAME,
                 getVariables(asInstanceId, newJob.getJobId()));
@@ -264,8 +261,8 @@ public class JobExecutorService {
                 throw new AsRequestProcessingException(message, errorDetails);
             }
 
-            final String message = "Received unexpected Job Status: " + finalJobStatus
-                    + " Failed to Delete AS with id: " + asInstanceId;
+            final String message = "Delete AS request failed. Received unexpected Job Status: " + finalJobStatus
+                    + " Delete AS with id: " + asInstanceId;
             logger.error(message);
             throw new AsRequestProcessingException(message);
         }
@@ -286,12 +283,12 @@ public class JobExecutorService {
     }
 
     private ImmutablePair<String, JobStatusEnum> waitForJobToFinish(final String jobId,
-            final ImmutableSet<JobStatusEnum> jobFinishedStates) {
+            final Set<JobStatusEnum> jobFinishedStates) {
         try {
             final long startTimeInMillis = System.currentTimeMillis();
             final long timeOutTime = startTimeInMillis + TimeUnit.SECONDS.toMillis(timeOutInSeconds);
 
-            logger.info("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime).toString(), jobId);
+            logger.info("Will wait till {} for {} job to finish", Instant.ofEpochMilli(timeOutTime), jobId);
             JobStatusEnum currentJobStatus = null;
             while (timeOutTime > System.currentTimeMillis()) {
 
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProvider.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProvider.java
new file mode 100644 (file)
index 0000000..87e0c29
--- /dev/null
@@ -0,0 +1,39 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.bpmn.flows.service;
+
+import java.nio.file.Path;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.KubeConfigFileNotFoundException;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+public interface KubConfigProvider {
+
+    Path getKubeConfigFile(final String cloudOwner, final String cloudRegion, final String tenantId)
+            throws KubeConfigFileNotFoundException;
+
+    void addKubeConfigFile(final MultipartFile file, final String cloudOwner, final String cloudRegion,
+            final String tenantId);
+
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProviderImpl.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-bpmn-flows/src/main/java/org/onap/so/cnfm/lcm/bpmn/flows/service/KubConfigProviderImpl.java
new file mode 100644 (file)
index 0000000..9f42038
--- /dev/null
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.bpmn.flows.service;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Arrays;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.KubeConfigFileNotFoundException;
+import org.onap.so.cnfm.lcm.bpmn.flows.exceptions.KubeConfigFileUploadException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ *
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ *
+ */
+@Service
+public class KubConfigProviderImpl implements KubConfigProvider {
+    private static final Logger logger = LoggerFactory.getLogger(KubConfigProviderImpl.class);
+
+    private final Path kubeConfigsDirPath;
+
+    @Autowired
+    public KubConfigProviderImpl(@Value("${cnfm.kube-configs-dir:/app/kube-configs}") final String kubeConfigsDir) {
+        this.kubeConfigsDirPath = Paths.get(kubeConfigsDir).toAbsolutePath().normalize();
+    }
+
+    @Override
+    public Path getKubeConfigFile(final String cloudOwner, final String cloudRegion, final String tenantId)
+            throws KubeConfigFileNotFoundException {
+        final String filename = getFilename(cloudOwner, cloudRegion, tenantId);
+        final Path targetLocation = this.kubeConfigsDirPath.resolve(filename);
+        logger.debug("Looking for kube-config file at location {}", targetLocation);
+
+        if (Files.exists(targetLocation)) {
+            logger.debug("Found kube-config file at location {}", targetLocation);
+            if (Files.isReadable(targetLocation)) {
+                return targetLocation;
+            }
+            throw new KubeConfigFileNotFoundException("kube-config file at " + targetLocation + " is not readable");
+        }
+
+        throw new KubeConfigFileNotFoundException("Unable to find kube-config file at " + targetLocation);
+    }
+
+    @Override
+    public void addKubeConfigFile(final MultipartFile file, final String cloudOwner, final String cloudRegion,
+            final String tenantId) {
+        final String filename = getFilename(cloudOwner, cloudRegion, tenantId);
+        final Path targetLocation = this.kubeConfigsDirPath.resolve(filename);
+
+        try (final InputStream inputStream = file.getInputStream()) {
+            logger.debug("Storing kube-config to location {} ", targetLocation);
+            Files.copy(inputStream, targetLocation, StandardCopyOption.REPLACE_EXISTING);
+        } catch (final IOException ex) {
+            throw new KubeConfigFileUploadException(
+                    "Could not store kube-config file " + filename + " to location " + targetLocation, ex);
+        }
+
+    }
+
+    private String getFilename(final String cloudOwner, final String cloudRegion, final String tenantId) {
+        return String.join("-", Arrays.asList(cloudOwner, cloudRegion, tenantId));
+    }
+
+}
index b6dbd77..f017e08 100644 (file)
@@ -43,6 +43,9 @@ public class WorkflowQueryService {
 
     private static final Logger logger = getLogger(WorkflowQueryService.class);
 
+    private static final String PROCESS_INSTANCE_ID_NOT_FOUND_ERROR_MESSAGE =
+            "Unable to find {} variable using processInstanceId: {}";
+
     private final HistoryService camundaHistoryService;
 
     @Autowired
@@ -71,11 +74,10 @@ public class WorkflowQueryService {
                         historicVariableInstance.getValue() != null ? variableValue.getClass() : null, variableValue);
             }
         } catch (final ProcessEngineException processEngineException) {
-            logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_AS_RESPONSE_PARAM_NAME,
-                    processInstanceId, processEngineException);
+            logger.error(PROCESS_INSTANCE_ID_NOT_FOUND_ERROR_MESSAGE, CREATE_AS_RESPONSE_PARAM_NAME, processInstanceId,
+                    processEngineException);
         }
-        logger.error("Unable to find {} variable using processInstanceId: {}", CREATE_AS_RESPONSE_PARAM_NAME,
-                processInstanceId);
+        logger.error(PROCESS_INSTANCE_ID_NOT_FOUND_ERROR_MESSAGE, CREATE_AS_RESPONSE_PARAM_NAME, processInstanceId);
         return Optional.empty();
 
     }
@@ -96,8 +98,8 @@ public class WorkflowQueryService {
             }
             logger.error("Unable to retrieve HistoricVariableInstance value was null");
         } catch (final ProcessEngineException processEngineException) {
-            logger.error("Unable to find {} variable using processInstanceId: {}",
-                    AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, processInstanceId, processEngineException);
+            logger.error(PROCESS_INSTANCE_ID_NOT_FOUND_ERROR_MESSAGE, AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
+                    processInstanceId, processEngineException);
         }
         return Optional.empty();
     }
index 85af369..6e2b489 100644 (file)
@@ -79,7 +79,6 @@ public class CreateAsTask extends AbstractServiceTask {
     private final SdcPackageProvider sdcPackageProvider;
     private final SdcCsarPackageParser sdcParser;
 
-
     @Autowired
     public CreateAsTask(final DatabaseServiceProvider databaseServiceProvider,
             final AaiServiceProvider aaiServiceProvider, final SdcPackageProvider sdcPackageProvider,
@@ -154,11 +153,8 @@ public class CreateAsTask extends AbstractServiceTask {
         execution.setVariable(DOES_AS_INSTANCE_EXISTS_PARAM_NAME, exists);
 
         if (exists) {
-            final Optional<AsInst> optional =
-                    databaseServiceProvider.getAsInstByName(createAsRequest.getAsInstanceName());
-            final AsInst asInst = optional.get();
-            execution.setVariable(AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME,
-                    new ErrorDetails().detail("As Instance already exists in database : " + asInst.toString()));
+            execution.setVariable(AS_WORKFLOW_PROCESSING_EXCEPTION_PARAM_NAME, new ErrorDetails()
+                    .detail("As Instance already exists in database for : " + createAsRequest.getAsInstanceName()));
         }
 
         logger.info("Finished executing doesAsInstanceExistsInDb  ...");
index 4cc1f8a..b675c38 100644 (file)
@@ -49,7 +49,6 @@ public class PropertiesToYamlConverter {
                 final Map<String, Object> subMap = new TreeMap<>();
                 local.put(currentKey, subMap);
                 local = subMap;
-                continue;
             } else {
                 local = (Map<String, Object>) local.get(currentKey);
             }
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/main/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigController.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/main/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigController.java
new file mode 100644 (file)
index 0000000..e3c0aaf
--- /dev/null
@@ -0,0 +1,73 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.rest;
+
+import static org.onap.so.cnfm.lcm.Constants.BASE_URL;
+import static org.slf4j.LoggerFactory.getLogger;
+import javax.ws.rs.core.MediaType;
+import org.onap.so.cnfm.lcm.bpmn.flows.service.KubConfigProvider;
+import org.slf4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author Sagar Shetty (sagar.shetty@est.tech)
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@Controller
+@RequestMapping(value = BASE_URL)
+public class CloudKubeConfigController {
+
+    private static final Logger logger = getLogger(CloudKubeConfigController.class);
+    private final KubConfigProvider kubConfigProvider;
+
+    @Autowired
+    public CloudKubeConfigController(final KubConfigProvider kubConfigProvider) {
+        this.kubConfigProvider = kubConfigProvider;
+    }
+
+    @PutMapping(value = "/kube-config/cloudOwner/{cloudOwner}/cloudRegion/{cloudRegion}/tenantId/{tenantId}/upload",
+            produces = {MediaType.APPLICATION_JSON},
+            consumes = {MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_OCTET_STREAM})
+    public ResponseEntity<String> uploadKubeConfig(
+            @PathVariable(name = "cloudOwner", required = true) final String cloudOwner,
+            @PathVariable(name = "cloudRegion", required = true) final String cloudRegion,
+            @PathVariable(name = "tenantId", required = true) final String tenantId,
+            @RequestParam(name = "file", required = true) final MultipartFile file) {
+        try {
+            kubConfigProvider.addKubeConfigFile(file, cloudOwner, cloudRegion, tenantId);
+            logger.info(
+                    "Successfully retrieved kube-config file for cloud Owner: {}, " + "cloud region: {}, tenant Id: {}",
+                    cloudOwner, cloudRegion, tenantId);
+            return ResponseEntity.accepted().build();
+        } catch (final Exception e) {
+            logger.error("Error while saving kube-config file due to: {} for cloud Owner: {}, "
+                    + "cloud region: {}, tenant Id: {}", e.getMessage(), cloudOwner, cloudRegion, tenantId);
+            return ResponseEntity.unprocessableEntity().body(e.getMessage());
+        }
+
+    }
+}
diff --git a/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/test/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigControllerTest.java b/so-cnfm/so-cnfm-lcm/so-cnfm-lcm-service/src/test/java/org/onap/so/cnfm/lcm/rest/CloudKubeConfigControllerTest.java
new file mode 100644 (file)
index 0000000..3157f84
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+package org.onap.so.cnfm.lcm.rest;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.cnfm.lcm.bpmn.flows.service.KubConfigProvider;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author Sagar Shetty (sagar.shetty@est.tech)
+ * @author Waqas Ikram (waqas.ikram@est.tech)
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class CloudKubeConfigControllerTest {
+
+    @Mock
+    private KubConfigProvider objUnderTest;
+
+    @InjectMocks
+    private CloudKubeConfigController controller;
+
+    @Test
+    public void uploadKubeConfigTest() throws Exception {
+        final MultipartFile file = Mockito.mock(MultipartFile.class);
+        final ResponseEntity<String> response = controller.uploadKubeConfig("owner", "athlone", "1234", file);
+        assertEquals(202, response.getStatusCode().value());
+        Mockito.verify(objUnderTest, Mockito.times(1)).addKubeConfigFile(file, "owner", "athlone", "1234");
+    }
+
+}