Fix K8s State change from Uninitialized to Passive only when pod deployment is succe... 42/126942/2
authorLathish <lathishbabu.ganesan@est.tech>
Wed, 2 Feb 2022 15:01:32 +0000 (20:31 +0530)
committerLathish <lathishbabu.ganesan@est.tech>
Fri, 4 Feb 2022 07:55:48 +0000 (13:25 +0530)
Issue-ID: POLICY-3874
Change-Id: Ib2ca3a5df8b15a0fa544fea8d0cbe794292d3d09
Signed-off-by: Lathish <lathishbabu.ganesan@est.tech>
participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java
participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandlerTest.java

index 3f2113d..a8a7462 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021 Nordix Foundation.
+ *  Copyright (C) 2021-2022 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,6 +27,10 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.Setter;
@@ -59,6 +63,8 @@ import org.springframework.stereotype.Component;
 public class ControlLoopElementHandler implements ControlLoopElementListener {
     private static final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
 
+    private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
+
     // Map of helm installation and the status of corresponding pods
     @Getter
     private static Map<String, Map<String, String>> podStatusMap = new ConcurrentHashMap<>();
@@ -145,13 +151,11 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
             chartMap.put(element.getId(), chartInfo);
 
             var config = CODER.convert(nodeTemplate.getProperties(), ThreadConfig.class);
-            checkPodStatus(chartInfo, config.uninitializedToPassiveTimeout, config.podStatusCheckInterval);
-
-            intermediaryApi.updateControlLoopElementState(controlLoopId, element.getId(),
-                    ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE,
-                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
+            checkPodStatus(controlLoopId, element.getId(), chartInfo, config.uninitializedToPassiveTimeout,
+                    config.podStatusCheckInterval);
 
-        } catch (ServiceException | CoderException | IOException e) {
+        } catch (ServiceException | CoderException | IOException | ExecutionException
+                | InterruptedException e) {
             LOGGER.warn("Installation of Helm chart failed", e);
         }
     }
@@ -160,10 +164,17 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
      * Invoke a new thread to check the status of deployed pods.
      * @param chart ChartInfo
      */
-    public void checkPodStatus(ChartInfo chart, int timeout, int podStatusCheckInterval) {
+    public void checkPodStatus(ToscaConceptIdentifier controlLoopId, UUID elementId,
+            ChartInfo chart, int timeout, int podStatusCheckInterval) throws ExecutionException, InterruptedException {
         // Invoke runnable thread to check pod status
-        var runnableThread = new Thread(new PodStatusValidator(chart, timeout, podStatusCheckInterval));
-        runnableThread.start();
+        Future<String> result = executor.submit(new PodStatusValidator(chart, timeout,
+                podStatusCheckInterval), "Done");
+        if (!result.get().isEmpty()) {
+            LOGGER.info("Pod Status Validator Completed: {}", result.isDone());
+            intermediaryApi.updateControlLoopElementState(controlLoopId, elementId,
+                ControlLoopOrderedState.PASSIVE, ControlLoopState.PASSIVE,
+                ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
+        }
     }
 
     /**
index d7f0970..805404b 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2021 Nordix Foundation.
+ *  Copyright (C) 2021-2022 Nordix Foundation.
  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -26,6 +26,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.when;
 
@@ -34,6 +35,9 @@ import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -83,6 +87,12 @@ class ControlLoopElementHandlerTest {
     @Mock
     private ParticipantIntermediaryApi participantIntermediaryApi;
 
+    @Mock
+    private ExecutorService executor;
+
+    @Mock
+    private Future<String> result;
+
     @BeforeAll
     static void init() throws CoderException {
         charts = CODER.decode(new File(CHART_INFO_YAML), ChartList.class).getCharts();
@@ -121,8 +131,9 @@ class ControlLoopElementHandlerTest {
     }
 
     @Test
-    void test_ControlLoopElementUpdate() throws PfModelException, IOException, ServiceException {
-        doNothing().when(controlLoopElementHandler).checkPodStatus(any(), anyInt(), anyInt());
+    void test_ControlLoopElementUpdate() throws PfModelException, IOException, ServiceException,
+            ExecutionException, InterruptedException {
+        doNothing().when(controlLoopElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt());
         UUID elementId1 = UUID.randomUUID();
         ControlLoopElement element = new ControlLoopElement();
         element.setId(elementId1);
@@ -156,8 +167,14 @@ class ControlLoopElementHandlerTest {
     }
 
     @Test
-    void test_checkPodStatus() {
+    void test_checkPodStatus() throws ExecutionException, InterruptedException {
+        doReturn(result).when(executor).submit(any(Runnable.class), any());
+        doReturn("Done").when(result).get();
+        doReturn(true).when(result).isDone();
         var chartInfo =  charts.get(0);
-        assertDoesNotThrow(() -> controlLoopElementHandler.checkPodStatus(chartInfo, 1, 1));
+        ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier();
+        ControlLoopElement element = new ControlLoopElement();
+        assertDoesNotThrow(() -> controlLoopElementHandler.checkPodStatus(controlLoopId, element.getId(), chartInfo,
+                1, 1));
     }
 }