Explorar o código

添加deployment状态查询

raledong %!s(int64=7) %!d(string=hai) anos
pai
achega
33e5448a27

+ 15 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/DeploymentApi.java

@@ -1,6 +1,7 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
 import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
+import nju.seec.SEECdemo.logic.api.k8s.model.DeploymentStatus;
 
 /**
  * author: rale
@@ -53,4 +54,18 @@ public interface DeploymentApi {
      */
     boolean exists(String namespace, String name);
 
+    /**
+     * 根据命名空间和名称查找Deployment
+     * @param namespace
+     * @param name
+     * @return 如果Deployment不存在,则返回null
+     */
+    Deployment get(String namespace, String name);
+
+    /**
+     * 查询deployment的状态
+     * @return 如果该deployment不存在,则返回null
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    DeploymentStatus getStatus(String namespace, String name);
 }

+ 17 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/WatchApi.java

@@ -0,0 +1,17 @@
+package nju.seec.SEECdemo.logic.api.k8s;
+
+/**
+ * author: rale
+ * createdAt: 1/13/19
+ */
+public interface WatchApi {
+
+    /**
+     * 会监听deployment的状态
+     * 超时时间十分钟
+     */
+    void watchDeployment();
+
+    void watchPod();
+
+}

+ 2 - 3
src/main/java/nju/seec/SEECdemo/logic/api/k8s/exception/K8sApiException.java

@@ -7,12 +7,11 @@ import java.util.HashMap;
 import java.util.Map;
 
 @Data
-@NoArgsConstructor
 public class K8sApiException extends RuntimeException{
 
-    private int code;
+    private final int code;
 
-    private String description;
+    private final String description;
 
     public static final Map<Integer, String> codeMap = new HashMap<>();
 

+ 29 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/DeploymentApiImpl.java

@@ -8,6 +8,7 @@ import io.kubernetes.client.models.*;
 import nju.seec.SEECdemo.logic.api.k8s.DeploymentApi;
 import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
+import nju.seec.SEECdemo.logic.api.k8s.model.DeploymentStatus;
 import nju.seec.SEECdemo.util.LoggerUtil;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -139,6 +140,34 @@ public class DeploymentApiImpl implements DeploymentApi{
         return false;
     }
 
+    @Override
+    public Deployment get(String namespace, String name) {
+        try{
+            V1Deployment v1Deployment = appsV1Api.readNamespacedDeployment(
+                    name,
+                    namespace,
+                    PRETTY_FORMAT,
+                    true,
+                    true);
+            return v1Deployment == null ? null : new Deployment(v1Deployment);
+        } catch (ApiException e) {
+            if (e.getCode() != K8sApiException.NOT_FOUND) {
+                LoggerUtil.error(logger, e, "查询Deployment异常,namespace={}, name={}", namespace, name);
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "查询Deployment异常, namespace={}, name={}", namespace, name);
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        }
+        return null;
+    }
+
+    @Override
+    public DeploymentStatus getStatus(String namespace, String name) {
+        Deployment deployment = this.get(namespace, name);
+        return deployment == null ? null : deployment.getStatus();
+    }
+
     private void deleteDeployment(String namespace, String name) throws ApiException{
         V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
                 .withApiVersion(Deployment.API_VERSION)

+ 3 - 3
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/LogApiImpl.java

@@ -35,8 +35,8 @@ public class LogApiImpl implements LogApi{
         PodLogs logs = new PodLogs();
         InputStream inputStream = logs.streamNamespacedPodLog(pod);
 
-        byte[] data = ByteStreams.toByteArray(inputStream);
-        System.out.print(data.length);
-//        ByteStreams.copy(inputStream, System.out);
+//        byte[] data = ByteStreams.toByteArray(inputStream);
+//        System.out.print(data.length);
+        ByteStreams.copy(inputStream, System.out);
     }
 }

+ 75 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/WatchApiImpl.java

@@ -0,0 +1,75 @@
+package nju.seec.SEECdemo.logic.api.k8s.impl;
+
+import com.google.common.reflect.TypeToken;
+import io.kubernetes.client.ApiClient;
+import io.kubernetes.client.ApiException;
+import io.kubernetes.client.apis.AppsV1Api;
+import io.kubernetes.client.apis.CoreV1Api;
+import io.kubernetes.client.models.V1Deployment;
+import io.kubernetes.client.models.V1Pod;
+import io.kubernetes.client.util.Watch;
+import nju.seec.SEECdemo.logic.api.k8s.WatchApi;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+
+import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
+
+/**
+ * author: rale
+ * createdAt: 1/13/19
+ */
+@Service
+public class WatchApiImpl implements WatchApi{
+
+    private ApiClient watchApiClient;
+
+    private AppsV1Api watchAppsV1Api;
+
+    @Autowired
+    public WatchApiImpl(ApiClient watchApiClient, AppsV1Api watchAppsV1Api) {
+        this.watchApiClient = watchApiClient;
+        this.watchAppsV1Api = watchAppsV1Api;
+    }
+    @Override
+//    @Async("taskExecutor")
+    public void watchDeployment() {
+        try {
+            Watch<V1Deployment> watch = Watch.createWatch(
+                    watchApiClient,
+                    watchAppsV1Api.listNamespacedDeploymentCall(
+                            "demo2",
+                            PRETTY_FORMAT,
+                            null,
+                            null,
+                            null,
+                            "demo.seec.nju.cn/app=test",
+                            null,
+                            null,
+                            null,
+                            true,
+                            null,
+                            null ),
+                    new TypeToken<Watch.Response<V1Deployment>>(){}.getType()
+
+            );
+            watch.forEach(response -> {
+                System.out.printf("%s pod : %s %s%n", response.type, response.object.getMetadata().getName(), response.object.getStatus());
+                try {
+                    watch.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            });
+        } catch (ApiException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void watchPod() {
+
+    }
+}

+ 4 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Container.java

@@ -45,6 +45,8 @@ public class Container {
     /* 环境变量 */
     private Map<String, String> env = new HashMap<>();
 
+    /* 探测容器是否就绪 */
+    private Probe readinessProbe;
 
     public Container(V1Container v1Container) {
         this.name = v1Container.getName();
@@ -56,11 +58,13 @@ public class Container {
             this.env = v1Container.getEnv().stream().collect(Collectors.toMap(V1EnvVar::getName, V1EnvVar::getValue));
         }
     }
+
     public V1Container toV1Container(){
         return new V1ContainerBuilder()
                 .withName(name)
                 .withImage(image)
                 .withImagePullPolicy(IMAGE_PULL_POLICY)
+                .withReadinessProbe(readinessProbe == null ? null : readinessProbe.toV1Probe())
                 .withArgs(args)
                 .withCommand(command)
                 .withPorts(ports.stream().map(ContainerPort::toV1ContainerPort).collect(Collectors.toList()))

+ 12 - 6
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/CpuQuantity.java

@@ -2,19 +2,20 @@ package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.Quantity;
 import lombok.Data;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 
 /**
  * CPU配额数量,默认单位为m,即CPU时间
  */
-@Data
-@NoArgsConstructor
+@Getter
 public class CpuQuantity {
 
-    private Quantity quantity;
+    private final Quantity quantity;
 
-    private Unit unit = Unit.Mi;
+    private final Unit unit;
 
+    private static final Unit DEFAULT_UNIT = Unit.Mi;
     //Cpu=0
     public static final CpuQuantity EMPTY = new CpuQuantity(0);
     //Cpu的默认分配额度
@@ -36,17 +37,21 @@ public class CpuQuantity {
     }
 
 
+
     public CpuQuantity(int quantity){
-        this.quantity = Quantity.fromString(quantity + unit.getCode());
+        this.quantity = Quantity.fromString(quantity + DEFAULT_UNIT.getCode());
+        this.unit = DEFAULT_UNIT;
     }
 
     public CpuQuantity(long quantity) {
-        this.quantity = Quantity.fromString(quantity + unit.getCode());
+        this.quantity = Quantity.fromString(quantity + DEFAULT_UNIT.getCode());
+        this.unit = DEFAULT_UNIT;
     }
 
 
     public CpuQuantity(Quantity quantity) {
         this.quantity = quantity;
+        this.unit = DEFAULT_UNIT;
     }
 
     public Quantity toQuantity(){
@@ -65,4 +70,5 @@ public class CpuQuantity {
         }
     }
 
+
 }

+ 13 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Deployment.java

@@ -3,7 +3,9 @@ package nju.seec.SEECdemo.logic.api.k8s.model;
 import io.kubernetes.client.models.*;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import lombok.Setter;
 import org.hibernate.validator.constraints.Range;
+import org.springframework.data.annotation.ReadOnlyProperty;
 
 import javax.validation.constraints.NotEmpty;
 import java.util.*;
@@ -24,6 +26,7 @@ public class Deployment {
     @NotEmpty
     private String name;
 
+    @NotEmpty
     private String namespace;
 
     private List<Container> containers = new ArrayList<>();
@@ -37,12 +40,22 @@ public class Deployment {
 
     private Map<String, String> annotations = new HashMap<>();
 
+    @ReadOnlyProperty
+    private DeploymentStatus status;
+
     public Deployment(V1Deployment v1Deployment) {
         this.name = v1Deployment.getMetadata().getName();
         this.namespace = v1Deployment.getMetadata().getNamespace();
         this.containers = v1Deployment.getSpec().getTemplate().getSpec().getContainers()
                 .stream().map(Container::new).collect(Collectors.toList());
+        this.imagePullSecrets = v1Deployment.getSpec().getTemplate().getSpec().getImagePullSecrets()
+                .stream().map(V1LocalObjectReference::getName).collect(Collectors.toList());
+        this.replicas = v1Deployment.getSpec().getReplicas();
+        this.labels = v1Deployment.getMetadata().getLabels();
+        this.annotations = v1Deployment.getMetadata().getAnnotations();
+        this.status = new DeploymentStatus(v1Deployment.getStatus());
     }
+
     public V1Deployment toV1Deployment(){
         return new V1DeploymentBuilder()
                 .withApiVersion(API_VERSION)

+ 27 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/DeploymentStatus.java

@@ -0,0 +1,27 @@
+package nju.seec.SEECdemo.logic.api.k8s.model;
+
+import io.kubernetes.client.models.V1DeploymentStatus;
+import lombok.Data;
+
+/**
+ * author: rale
+ * createdAt: 1/16/19
+ */
+@Data
+public class DeploymentStatus {
+
+    private int availableReplicas;
+
+    private int readyReplicas;
+
+    private int unavailableReplicas;
+
+    private int updatedReplicas;
+
+    public DeploymentStatus(V1DeploymentStatus deploymentStatus) {
+        this.availableReplicas = deploymentStatus.getAvailableReplicas();
+        this.readyReplicas = deploymentStatus.getReadyReplicas();
+        this.unavailableReplicas = deploymentStatus.getUnavailableReplicas();
+        this.updatedReplicas = deploymentStatus.getUpdatedReplicas();
+    }
+}

+ 53 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/HttpGetAction.java

@@ -0,0 +1,53 @@
+package nju.seec.SEECdemo.logic.api.k8s.model;
+
+import io.kubernetes.client.custom.IntOrString;
+import io.kubernetes.client.models.V1HTTPGetAction;
+import io.kubernetes.client.models.V1HTTPGetActionBuilder;
+import io.kubernetes.client.models.V1HTTPHeader;
+import io.kubernetes.client.models.V1HTTPHeaderBuilder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * author: rale
+ * createdAt: 1/13/19
+ *  封装HTTP get请求
+ */
+@Data
+@NoArgsConstructor
+public class HttpGetAction {
+
+    /*默认值为容器的host名称,即容器名称*/
+    private String host;
+
+    private Map<String, String> httpHeaders = Collections.EMPTY_MAP;
+
+    private String path;
+
+    private int port;
+
+    public HttpGetAction(V1HTTPGetAction v1HTTPGetAction) {
+        this.host = v1HTTPGetAction.getHost();
+        if (v1HTTPGetAction.getHttpHeaders() != null) {
+            httpHeaders = v1HTTPGetAction.getHttpHeaders().stream().collect(Collectors.toMap(V1HTTPHeader::getName, V1HTTPHeader::getValue));
+        }
+        this.path = v1HTTPGetAction.getPath();
+        this.port = v1HTTPGetAction.getPort().getIntValue();
+    }
+
+    public V1HTTPGetAction toV1HTTPGetAction() {
+        return new V1HTTPGetActionBuilder()
+                .withHost(host)
+                .withHttpHeaders(
+                        httpHeaders.entrySet().stream()
+                                .map(entry -> new V1HTTPHeaderBuilder().withName(entry.getKey()).withValue(entry.getValue()).build())
+                                .collect(Collectors.toList()))
+                .withPath(path)
+                .withPort(new IntOrString(port))
+                .build();
+    }
+}

+ 61 - 0
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Probe.java

@@ -0,0 +1,61 @@
+package nju.seec.SEECdemo.logic.api.k8s.model;
+
+import io.kubernetes.client.models.V1Probe;
+import io.kubernetes.client.models.V1ProbeBuilder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * author: rale
+ * createdAt: 1/12/19
+ */
+@Data
+@NoArgsConstructor
+public class Probe {
+
+    private static final int DEFAULT_INITIAL_DELAY_SECONDS = 0;
+    private static final int DEFAULT_PERIOD_SECONDS = 10;
+    private static final int DEFAULT_SUCCESS_THRESHOLD = 1;
+    private static final int DEFAULT_FAILURE_THRESHOLD = 3;
+    private static final int DEFAULT_TIMEOUT_SECONDS = 1;
+
+    /* 容器启动后等待多少秒后执行Probe */
+    private int initialDelaySeconds = DEFAULT_INITIAL_DELAY_SECONDS;
+
+    /* 每隔多少秒执行Probe */
+    private int periodSeconds = DEFAULT_PERIOD_SECONDS;
+
+    /* Probe执行成功多少次方可认为探测成功 */
+    private int successThreshold  = DEFAULT_SUCCESS_THRESHOLD;
+
+    /* Probe执行失败多少次访客认为探测失败 */
+    private int failureThreshold = DEFAULT_FAILURE_THRESHOLD;
+
+    /* 超时时间 */
+    private int timeoutSeconds = DEFAULT_TIMEOUT_SECONDS;
+
+    private HttpGetAction httpGetAction;
+
+    public Probe(V1Probe v1Probe) {
+        this.initialDelaySeconds = v1Probe.getInitialDelaySeconds();
+        this.periodSeconds = v1Probe.getPeriodSeconds();
+        this.successThreshold = v1Probe.getSuccessThreshold();
+        this.failureThreshold = v1Probe.getFailureThreshold();
+        this.timeoutSeconds = v1Probe.getTimeoutSeconds();
+        this.httpGetAction = v1Probe.getHttpGet() == null ? null : new HttpGetAction(v1Probe.getHttpGet());
+    }
+
+    public V1Probe toV1Probe() {
+        V1Probe v1Probe = new V1Probe();
+        v1Probe.setInitialDelaySeconds(initialDelaySeconds);
+        v1Probe.setPeriodSeconds(periodSeconds);
+        v1Probe.setSuccessThreshold(successThreshold);
+        v1Probe.setFailureThreshold(failureThreshold);
+        v1Probe.setTimeoutSeconds(timeoutSeconds);
+        if (httpGetAction != null) {
+            v1Probe.setHttpGet(httpGetAction.toV1HTTPGetAction());
+        }
+        return v1Probe;
+    }
+
+}

+ 10 - 6
src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/StorageQuantity.java

@@ -2,20 +2,22 @@ package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.Quantity;
 import lombok.Data;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 
 /**
  * 存储配额的单位,默认为MB
  * 可选的为KB,MB,GB
  */
-@Data
-@NoArgsConstructor
+@Getter
 public class StorageQuantity {
 
-    private Quantity quantity;
+    private final Quantity quantity;
 
     //存储的默认单位为MB
-    private Unit unit = Unit.MB;
+    private final Unit unit;
+
+    private static final Unit DEFAULT_UNIT = Unit.MB;
 
     //存储空间为0
     public static final StorageQuantity EMPTY = new StorageQuantity(0);
@@ -41,16 +43,18 @@ public class StorageQuantity {
     }
 
     public StorageQuantity(int quantity){
-        this.quantity = Quantity.fromString(quantity + unit.getCode());
+        this.quantity = Quantity.fromString(quantity + DEFAULT_UNIT.getCode());
+        this.unit = DEFAULT_UNIT;
     }
 
     public StorageQuantity(int quantity, Unit unit) {
-        this(quantity);
+        this.quantity = Quantity.fromString(quantity + DEFAULT_UNIT.getCode());
         this.unit = unit;
     }
 
     public StorageQuantity(Quantity quantity) {
         this.quantity = quantity;
+        this.unit = DEFAULT_UNIT;
     }
 
     public Quantity toQuantity(){

+ 41 - 1
src/main/java/nju/seec/SEECdemo/logic/api/k8s/util/BeanAnnouncement.java

@@ -13,9 +13,13 @@ import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;
 import nju.seec.SEECdemo.util.ApplicationProperties.K8s;
 
+import java.util.concurrent.TimeUnit;
+
 @Component
 public class BeanAnnouncement {
 
+    private final ApiClient apiClient;
+
     private final CoreV1Api coreV1Api;
 
     private final AppsV1Api appsV1Api;
@@ -24,18 +28,38 @@ public class BeanAnnouncement {
 
     private final Exec exec;
 
+    /**
+     * http读取的超时时间设置为7分钟
+     */
+    private final ApiClient watchApiClient;
+
+    private final CoreV1Api watchCoreV1Api;
+
+    private final AppsV1Api watchAppsV1Api;
+
     @Autowired
     public BeanAnnouncement(ApplicationProperties applicationProperties) {
         K8s k8s = applicationProperties.getK8s();
         String apiServer = k8s.getApiServer();
         String token = k8s.getToken();
 
-        ApiClient apiClient = Config.fromToken(apiServer, token);
+        this.apiClient = Config.fromToken(apiServer, token);
         Configuration.setDefaultApiClient(apiClient);
         this.coreV1Api = new CoreV1Api();
         this.appsV1Api = new AppsV1Api();
         this.extensionsV1beta1Api = new ExtensionsV1beta1Api();
         this.exec = new Exec();
+
+
+        this.watchApiClient = Config.fromToken(apiServer, token);
+        this.watchApiClient.getHttpClient().setReadTimeout(10, TimeUnit.MINUTES);
+        this.watchCoreV1Api = new CoreV1Api(watchApiClient);
+        this.watchAppsV1Api = new AppsV1Api(watchApiClient);
+    }
+
+    @Bean
+    public ApiClient apiClient() {
+        return apiClient;
     }
 
     @Bean
@@ -58,4 +82,20 @@ public class BeanAnnouncement {
         return exec;
     }
 
+
+    @Bean
+    public ApiClient watchApiClient() {
+        return watchApiClient;
+    }
+
+    @Bean
+    public CoreV1Api watchCoreV1Api() {
+        return watchCoreV1Api;
+    }
+
+    @Bean
+    public AppsV1Api watchAppsV1Api() {
+        return watchAppsV1Api;
+    }
+
 }

+ 70 - 11
src/test/java/nju/seec/SEECdemo/service/api/DeploymentApiImplTest.java

@@ -1,9 +1,16 @@
 package nju.seec.SEECdemo.service.api;
 
+import com.google.common.reflect.TypeToken;
+import io.kubernetes.client.ApiClient;
+import io.kubernetes.client.ApiException;
+import io.kubernetes.client.apis.AppsV1Api;
+import io.kubernetes.client.apis.CoreV1Api;
+import io.kubernetes.client.models.V1Deployment;
+import io.kubernetes.client.models.V1Namespace;
+import io.kubernetes.client.models.V1Pod;
+import io.kubernetes.client.util.Watch;
 import nju.seec.SEECdemo.logic.api.k8s.DeploymentApi;
-import nju.seec.SEECdemo.logic.api.k8s.model.Container;
-import nju.seec.SEECdemo.logic.api.k8s.model.ContainerPort;
-import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
+import nju.seec.SEECdemo.logic.api.k8s.model.*;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -11,9 +18,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.test.context.junit4.SpringRunner;
 
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
+import java.net.SocketTimeoutException;
+import java.util.*;
 
 import static nju.seec.SEECdemo.util.Constants.APPLICATION_LABEL;
 
@@ -25,6 +31,17 @@ public class DeploymentApiImplTest {
     private DeploymentApi deploymentApi;
 
     private Deployment deployment;
+
+    @Autowired
+    private ApiClient watchApiClient;
+
+    @Autowired
+    private CoreV1Api coreV1Api;
+
+    @Autowired
+    private AppsV1Api appsV1Api;
+
+    @Autowired
     @Before
     public void before() {
         deployment = new Deployment();
@@ -34,14 +51,35 @@ public class DeploymentApiImplTest {
 
         Container container = new Container();
         container.setName("container");
-        container.setImage("10.1.1.243:18082/container_demo:1.0");
-        ContainerPort containerPort = new ContainerPort();
-        containerPort.setPort(8081);
-        containerPort.setProtocol("TCP");
+        container.setImage("10.1.1.243:18082/container_demo:3.0");
+        ContainerPort service = new ContainerPort();
+        service.setName("service");
+        service.setPort(8081);
+        service.setProtocol("TCP");
         Set<ContainerPort> ports = new HashSet<>();
-        ports.add(containerPort);
+        ports.add(service);
+
+        ContainerPort health = new ContainerPort();
+        health.setName("health");
+        health.setPort(9090);
+        health.setProtocol("TCP");
+        ports.add(health);
         container.setPorts(ports);
 
+        Map<String, String> env = new HashMap<>();
+        env.put("DB_USERNAME", "root");
+        env.put("DB_URL", "mysql.group25.svc.cluster.local:3306");
+        env.put("DB_SCHEMA", "container_demo");
+        env.put("DB_PASSWORD", "password");
+        container.setEnv(env);
+
+        Probe probe = new Probe();
+        HttpGetAction httpGetAction = new HttpGetAction();
+        httpGetAction.setPath("/actuator/health");
+        httpGetAction.setPort(9090);
+        probe.setHttpGetAction(httpGetAction);
+        container.setReadinessProbe(probe);
+
         deployment.setLabels(Collections.singletonMap(APPLICATION_LABEL, "test"));
         deployment.setImagePullSecrets(Collections.singletonList("docker-registry-secret"));
 
@@ -54,12 +92,32 @@ public class DeploymentApiImplTest {
         deploymentApi.deleteIfExist("demo2", "test");
 
         deploymentApi.createSync(deployment);
+
+        try {
+            Watch<V1Pod> watch = Watch.createWatch(watchApiClient,
+                    new CoreV1Api(watchApiClient).listNamespacedPodCall("demo2", null, null, null, null, "demo.seec.nju.cn/app=test", null, null, null, true, null, null ),
+                    new TypeToken<Watch.Response<V1Pod>>(){}.getType());
+            watch.forEach(response -> {
+                System.out.printf("%s pod : %s %s%n", response.type, response.object.getMetadata().getName(), response.object.getStatus());
+            });
+        } catch (ApiException e) {
+            System.out.println(e.getResponseBody());
+        } catch (Exception e) {
+            System.out.println(e);
+        }
+
+
     }
 
     @Test
     public void testCreateAsync() {
         deploymentApi.deleteIfExist("demo2", "test");
         deploymentApi.createAsync(deployment);
+        try {
+            Thread.sleep(60000);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
     }
 
     @Test
@@ -75,4 +133,5 @@ public class DeploymentApiImplTest {
     public void testDeleteIfExist() {
         deploymentApi.deleteIfExist("demo", "test");
     }
+
 }

+ 1 - 1
src/test/java/nju/seec/SEECdemo/service/api/SecretApiImplTest.java

@@ -128,7 +128,7 @@ public class SecretApiImplTest {
 
     @Test
     public void testGetSecretByType() {
-        List<SecretVO> v1Secret = secretApi.getSecretListByType("demo", SecretTypeEnum.REGISTRY);
+        List<SecretVO> v1Secret = secretApi.getSecretListByType("demo", SecretTypeEnum.Generic);
         v1Secret.stream().forEach((v1Secret1 -> {
             v1Secret1.getData().values().forEach((stringEntry -> {
                 System.out.println(stringEntry);

+ 25 - 0
src/test/java/nju/seec/SEECdemo/service/api/WatchApiImplTest.java

@@ -0,0 +1,25 @@
+package nju.seec.SEECdemo.service.api;
+
+import nju.seec.SEECdemo.logic.api.k8s.WatchApi;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * author: rale
+ * createdAt: 1/13/19
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class WatchApiImplTest {
+
+    @Autowired
+    private WatchApi watchApi;
+
+    @Test
+    public void testWatchDeployment() {
+        watchApi.watchDeployment();
+    }
+}