Просмотр исходного кода

疯狂重构
1. 将vo和dto整合到model包中
2. 将异常汇总,只提供概述的异常,不提供过于具体的异常描述
3. 提供deleteIfExist接口,适用于资源清理

raledong 7 лет назад
Родитель
Сommit
f0deec60b1
37 измененных файлов с 557 добавлено и 508 удалено
  1. 2 2
      src/main/java/nju/seec/SEECdemo/data/entity/ResourceConfig.java
  2. 36 4
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/DeploymentApi.java
  3. 9 2
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/ExecApi.java
  4. 13 9
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/IngressApi.java
  5. 27 12
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/NamespaceApi.java
  6. 22 17
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/ResourceQuotaApi.java
  7. 26 2
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/ServiceApi.java
  8. 0 69
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/NamespaceDTO.java
  9. 2 0
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/exception/K8sApiException.java
  10. 12 2
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ExecApiImpl.java
  11. 51 38
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/IngressApiImpl.java
  12. 82 49
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/NamespaceApiImpl.java
  13. 69 70
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ResourceQuotaImpl.java
  14. 72 10
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ServiceApiImpl.java
  15. 4 4
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Container.java
  16. 4 4
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ContainerPort.java
  17. 1 3
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/CpuQuantity.java
  18. 6 6
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Deployment.java
  19. 4 4
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Ingress.java
  20. 2 10
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Namespace.java
  21. 4 5
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ResourceQuota.java
  22. 6 6
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Service.java
  23. 3 3
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ServicePort.java
  24. 1 4
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/StorageQuantity.java
  25. 0 23
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/Ingress.java
  26. 2 2
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/LimitRange.java
  27. 0 44
      src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/ResourceQuota.java
  28. 28 29
      src/main/java/nju/seec/SEECdemo/logic/service/impl/ApplicationServiceImpl.java
  29. 9 11
      src/main/java/nju/seec/SEECdemo/logic/service/impl/ProjectServiceImpl.java
  30. 2 2
      src/main/java/nju/seec/SEECdemo/util/BeanUtil.java
  31. 17 17
      src/main/java/nju/seec/SEECdemo/web/dto/ApplicationDTO.java
  32. 7 6
      src/main/java/nju/seec/SEECdemo/web/dto/ContainerDTO.java
  33. 14 17
      src/main/java/nju/seec/SEECdemo/web/dto/PortDTO.java
  34. 7 7
      src/test/java/nju/seec/SEECdemo/service/api/DeploymentApiImplTest.java
  35. 8 10
      src/test/java/nju/seec/SEECdemo/service/api/IngressApiImplTest.java
  36. 3 3
      src/test/java/nju/seec/SEECdemo/service/api/NamespaceApiImplTest.java
  37. 2 2
      src/test/java/nju/seec/SEECdemo/service/api/ResourceQuotaApiImplTest.java

+ 2 - 2
src/main/java/nju/seec/SEECdemo/data/entity/ResourceConfig.java

@@ -2,8 +2,8 @@ package nju.seec.SEECdemo.data.entity;
 
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.CpuQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.StorageQuantity;
 
 /**
  * @Todo 是否需要将不同的配置新建为不同的类

+ 36 - 4
src/main/java/nju/seec/SEECdemo/logic/api/k8s/DeploymentApi.java

@@ -1,7 +1,6 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
-import nju.seec.SEECdemo.logic.api.k8s.dto.DeploymentDTO;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
+import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
 
 /**
  * author: rale
@@ -12,13 +11,46 @@ public interface DeploymentApi {
     /**
      * 同步创建Deployment
      * @param deployment
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND namespace不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException ALREADY_EXIST deployment已经存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
      */
-    void createSync(DeploymentDTO deployment);
+    void createSync(Deployment deployment);
 
-    void createAsync();
+    /**
+     * 异步创建Deployment
+     * @param deployment
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND namespace不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException ALREADY_EXIST deployment已经存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void createAsync(Deployment deployment);
 
+    /**
+     * 删除deployment
+     * @param namespace
+     * @param name
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND namespace不存在/deployment不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
     void delete(String namespace, String name);
 
+
+    /**
+     * 删除deployment,如果该deployment不存在,则不执行任何操作,且不抛出异常
+     * @param namespace
+     * @param name
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void deleteIfExist(String namespace, String name);
+
+    /**
+     * 判断deployment是否存在
+     * @param namespace
+     * @param name
+     * @return 如果命名空间下deployment存在,则返回true,其它情况返回false
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
     boolean exists(String namespace, String name);
 
 }

+ 9 - 2
src/main/java/nju/seec/SEECdemo/logic/api/k8s/ExecApi.java

@@ -1,5 +1,6 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
+
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
 
 import java.util.List;
@@ -17,14 +18,20 @@ public interface ExecApi {
      * @param podName
      * @param containerName
      * @param commands
+     * @return exitCode=0 则返回true,其它情况返回false
+     * @throws K8sApiException NOT_FOUND 命名空间/pod/container不存在
+     * @throws K8sApiException SYSTEM_ERROR 系统异常
      */
-    boolean exec(String namespace, String podName, String containerName, List<String> commands) throws K8sApiException;
+    boolean exec(String namespace, String podName, String containerName, List<String> commands);
 
     /**
      * 当且仅当pod下只有一个container时,该指令才会执行成功,否则会抛出异常
      * @param namespace
      * @param podName
      * @param commands
+     * @return exitCode=0 则返回true,其它情况返回false
+     * @throws K8sApiException NOT_FOUND 命名空间不存在/pod不存在/pod下没有container
+     * @throws K8sApiException SYSTEM_ERROR pod存在多个container/系统异常/指令执行异常
      */
-    boolean exec(String namespace, String podName, List<String> commands) throws K8sApiException;
+    boolean exec(String namespace, String podName, List<String> commands);
 }

+ 13 - 9
src/main/java/nju/seec/SEECdemo/logic/api/k8s/IngressApi.java

@@ -1,7 +1,6 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
 
 /**
  * author: rale
@@ -11,23 +10,28 @@ public interface IngressApi {
 
     /**
      * 创建Ingress资源
-     * @param ingressDTO 不能为null,
+     * @param ingress
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND 命名空间不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException ALREADY_EXIST ingress已经存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
      */
-    void create(IngressDTO ingressDTO);
+    void create(Ingress ingress);
 
     /**
-     * 若命名空间不存在或者Ingress不存在,抛出K8sApiException
+     * 删除namespace命名空间下的ingress
      * @param namespace
      * @param name
-     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException 当K8s系统执行操作出现系统异常时,会抛出系统异常
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND 命名空间/ingress不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
      */
     void delete(String namespace, String name);
 
     /**
+     * 删除namespace命名空间下的ingress
      * 若命名空间不存在或者资源不存在,不会执行任何操作,也不会抛出异常
      * @param namespace
      * @param name
-     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException 当K8s系统执行操作出现系统异常时,会抛出系统异常
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
      */
     void deleteIfExists(String namespace, String name);
 
@@ -35,8 +39,8 @@ public interface IngressApi {
      * 判断Ingress资源是否存在
      * @param namespace
      * @param name
-     * @return 存在返回true,否则返回false
-     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException 会抛出系统异常
+     * @return namespace下ingress存在返回true,否则返回false
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
      */
     boolean exists(String namespace, String name);
 }

+ 27 - 12
src/main/java/nju/seec/SEECdemo/logic/api/k8s/NamespaceApi.java

@@ -1,8 +1,7 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
-import nju.seec.SEECdemo.logic.api.k8s.dto.NamespaceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Namespace;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.Namespace;
 
 import java.util.List;
 import java.util.Map;
@@ -10,52 +9,68 @@ import java.util.Map;
 public interface NamespaceApi {
 
     /**
-     * 新建一个命名空间
+     * 新建命名空间
      * @param namespace 命名空间名称需要唯一
      * @return
+     * @throws K8sApiException 命名空间已经存在
+     * @throws K8sApiException 系统异常
      */
-    void create(NamespaceDTO namespace) throws K8sApiException;
+    void create(Namespace namespace) throws K8sApiException;
 
 
     /**
-     * 删除命名空间
+     * 删除命名空间,如果命名空间不存在,则抛出异常
      * @param name
      * @return
+     * @throws K8sApiException 命名空间不存在
+     * @throws K8sApiException 系统异常
      */
-    void deleteByName(String name) throws K8sApiException;
+    void delete(String name);
+
+    /**
+     * 删除命名空间,如果命名空间不存在,则不执行任何操作
+     * @param name
+     * @throws K8sApiException 系统异常
+     */
+    void deleteIfExists(String name);
 
     /**
      * 获得名称为name的命名空间
      * @param name
-     * @return
+     * @return 如果不存在,则返回null
+     * @throws K8sApiException 系统异常
      */
-    Namespace getByName(String name) throws K8sApiException;
+    Namespace getByName(String name);
 
     /**
      * 获得所有命名空间
      * @return
+     * @throws K8sApiException 系统异常
      */
-    List<Namespace> getAll() throws K8sApiException;
+    List<Namespace> getAll();
 
     /**
      * 获取匹配labels标签的namespace
      * @param labels
      * @return
+     * @throws K8sApiException 系统异常
      */
-    List<Namespace> getByLabels(Map<String, String> labels) throws K8sApiException;
+    List<Namespace> getByLabels(Map<String, String> labels);
 
     /**
      * 获取匹配了label标签的namespace
      * @param key
      * @param value
      * @return
+     * @throws K8sApiException 系统异常
      */
-    List<Namespace> getByLabel(String key, String value) throws K8sApiException;
+    List<Namespace> getByLabel(String key, String value);
 
     /**
      * 判断该命名空间是否存在
      * @param name
-     * @return
+     * @return 存在返回true,否则返回false
+     * @throws K8sApiException 系统异常
      */
     boolean exists(String name);
 }

+ 22 - 17
src/main/java/nju/seec/SEECdemo/logic/api/k8s/ResourceQuotaApi.java

@@ -1,9 +1,7 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
-import nju.seec.SEECdemo.logic.api.k8s.dto.ResourceQuotaDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.ResourceQuota;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
 
 public interface ResourceQuotaApi {
 
@@ -11,39 +9,46 @@ public interface ResourceQuotaApi {
      * 新建资源限额,如果该命名空间下的限额已经存在,则更新限额
      * @param resourceQuota
      * @return
+     * @throws K8sApiException NOT_FOUND 命名空间不存在
+     * @throws K8sApiException ALREADY_EXIST 资源已经存在
+     * @throws K8sApiException SYSTEM_ERROR 系统异常
      */
-    void create(ResourceQuotaDTO resourceQuota) throws K8sApiException;
+    void create(ResourceQuota resourceQuota);
 
-    /**
-     * 更新资源限额
-     * @param resourceQuota
-     * @return
-     */
-    void update(ResourceQuotaDTO resourceQuota) throws K8sApiException;
 
     /**
      * 删除namespace下名为name的资源限额
      * @param namespace
      * @param name
      * @return
+     * @throws K8sApiException NOT FOUND 命名空间不存在/资源限额不存在
+     * @throws K8sApiException 系统异常
      */
-    void delete(String namespace, String name) throws K8sApiException;
+    void delete(String namespace, String name);
 
+    /**
+     * 删除namespace下名为name的资源限额, 如果资源限额不存在,则不执行任何操作
+     * @param namespace
+     * @param name
+     * @throws K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void deleteIfExists(String namespace, String name);
 
     /**
-     * 获取namespace下名为name的资源
+     * 获取namespace下名为name的资源配额
      * @param namespace
      * @param name
-     * @return
-     * @throws K8sApiException
+     * @return 如果该资源配额或者命名空间不存在,则返回null
+     * @throws K8sApiException SYSTEM_ERROR 系统异常
      */
-    ResourceQuota getByName(String namespace, String name) throws K8sApiException;
+    ResourceQuota getByName(String namespace, String name);
 
     /**
      * 当前的资源限额是否存在
      * @param namespace
      * @param name
-     * @throws K8sApiException
+     * @return 如果命名空间下资源配额存在,则返回true,否则返回false
+     * @throws K8sApiException SYSTEM_ERROR 系统异常
      */
-    boolean exist(String namespace, String name) throws K8sApiException;
+    boolean exist(String namespace, String name);
 }

+ 26 - 2
src/main/java/nju/seec/SEECdemo/logic/api/k8s/ServiceApi.java

@@ -1,6 +1,6 @@
 package nju.seec.SEECdemo.logic.api.k8s;
 
-import nju.seec.SEECdemo.logic.api.k8s.dto.ServiceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Service;
 
 /**
  * author: rale
@@ -8,7 +8,31 @@ import nju.seec.SEECdemo.logic.api.k8s.dto.ServiceDTO;
  */
 public interface ServiceApi {
 
-    void create(ServiceDTO serviceDTO);
+    /**
+     * 创建Service
+     * @param service
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND namespace不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException ALREADY_EXISTS service已经存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void create(Service service);
 
+    /**
+     * 删除命名空间namespace下名为name的Service
+     * @param namespace
+     * @param name
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException NOT_FOUND 命名空间不存在/资源不存在
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void delete(String namespace, String name);
+
+    /**
+     * 删除命名空间namespace下名为name的Service
+     * 如果该资源不存在或者命名空间不存在,则不执行任何操作,也不抛出异常
+     * @param namespace
+     * @param name
+     * @throws nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException SYSTEM_ERROR 系统异常
+     */
+    void deleteIfExists(String namespace, String name);
 
 }

+ 0 - 69
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/NamespaceDTO.java

@@ -1,69 +0,0 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
-
-import io.kubernetes.client.models.*;
-import io.swagger.annotations.ApiModelProperty;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import nju.seec.SEECdemo.util.DateUtil;
-
-import javax.validation.constraints.NotNull;
-import java.time.LocalDateTime;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * author: rale
- * createdAt: 1/4/19
- */
-@Data
-@NoArgsConstructor
-public class NamespaceDTO {
-
-    private static final String KIND = "Namespace";
-
-    private static final String VERSION = "v1";
-
-    //@todo 添加一个label标记该Namespace为seec创建的
-    //获取时只获取seec创建的label
-
-    @NotNull
-    private String name;
-
-    private Map<String, String> labels = new HashMap<>();
-
-    private Map<String, String> annotations = new HashMap<>();
-
-    @ApiModelProperty(readOnly = true)
-    private LocalDateTime createdAt;
-
-
-    public NamespaceDTO(V1Namespace v1Namespace) {
-        this.name = v1Namespace.getMetadata().getName();
-        this.labels = v1Namespace.getMetadata().getLabels();
-        this.annotations = v1Namespace.getMetadata().getAnnotations();
-        this.createdAt = DateUtil.fromJodaDateTime(v1Namespace.getMetadata().getCreationTimestamp());
-    }
-
-    public V1Namespace toV1Namespace(){
-        V1ObjectMeta v1ObjectMeta = new V1ObjectMetaBuilder()
-                .withName(name)
-                .withLabels(labels)
-                .withAnnotations(annotations)
-                .build();
-        V1Namespace v1Namespace = new V1NamespaceBuilder()
-                .withApiVersion(VERSION)
-                .withKind(KIND)
-                .withMetadata(v1ObjectMeta)
-                .build();
-        return v1Namespace;
-
-    }
-
-    public void addToLabel(String key, String value) {
-        labels.put(key, value);
-    }
-
-    public void addToAnnotation(String key, String value){
-        annotations.put(key, value);
-    }
-}

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

@@ -35,6 +35,8 @@ public class K8sApiException extends RuntimeException{
 
 
     public static final K8sApiException K8s_SYSTEM_ERROR_EXCEPTION = new K8sApiException(SYSTEM_ERROR);
+
+    public static final K8sApiException K8s_NAMESPACE_NOT_EXIST = new K8sApiException(NAMESPACE_NOT_EXIST);
     //系统故障
     static {
         codeMap.put(NAMESPACE_NOT_EXIST, "命名空间不存在");

+ 12 - 2
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ExecApiImpl.java

@@ -13,6 +13,8 @@ import org.springframework.stereotype.Service;
 import java.io.IOException;
 import java.util.List;
 
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.NOT_FOUND;
+
 
 @Service
 public class ExecApiImpl implements ExecApi{
@@ -45,12 +47,20 @@ public class ExecApiImpl implements ExecApi{
             return proc.exitValue() == 0;
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "指令执行异常, namespace={}, podName={}, commands={}, response={}",
-                    namespace, podName, commands, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+                namespace, podName, commands, e.getResponseBody());
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(NOT_FOUND, "容器不存在");
+            }else{
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         } catch (InterruptedException | IOException e) {
             LoggerUtil.error(logger, e, "指令执行异常, namespace={}, podName={}, commands={}",
                     namespace, podName, commands);
             throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "指令执行异常, namespace={}, podName={}, commands={}",
+                    namespace, podName, commands);
         }
+        return false;
     }
 }

+ 51 - 38
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/IngressApiImpl.java

@@ -1,24 +1,20 @@
 package nju.seec.SEECdemo.logic.api.k8s.impl;
 
 import io.kubernetes.client.ApiException;
-import io.kubernetes.client.apis.AppsV1beta1Api;
-import io.kubernetes.client.apis.CoreV1Api;
 import io.kubernetes.client.apis.ExtensionsV1beta1Api;
-import io.kubernetes.client.custom.IntOrString;
 import io.kubernetes.client.models.*;
-import io.kubernetes.client.proto.V1beta1Apps;
-import io.kubernetes.client.proto.V1beta1Extensions;
 import nju.seec.SEECdemo.logic.api.k8s.IngressApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ApiResult;
-import nju.seec.SEECdemo.logic.api.k8s.vo.Namespace;
 import nju.seec.SEECdemo.util.ApplicationProperties;
 import nju.seec.SEECdemo.util.LoggerUtil;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.ALREADY_EXIST;
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.NOT_FOUND;
 import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
 import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
 
@@ -29,6 +25,7 @@ import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
 @Service
 public class IngressApiImpl implements IngressApi{
     private static final Logger logger = LoggerUtil.getLogger(IngressApi.class);
+
     @Autowired
     private final ExtensionsV1beta1Api extensionsV1beta1Api;
 
@@ -38,67 +35,83 @@ public class IngressApiImpl implements IngressApi{
     }
 
     @Override
-    public void create(IngressDTO ingressDTO) {
-        V1beta1Ingress v1beta1Ingress = ingressDTO.toV1beta1Ingress();
+    public void create(Ingress ingress) {
+        V1beta1Ingress v1beta1Ingress = ingress.toV1beta1Ingress();
 
         try {
-            extensionsV1beta1Api.createNamespacedIngress(ingressDTO.getNamespace(), v1beta1Ingress, PRETTY_FORMAT);
+            extensionsV1beta1Api.createNamespacedIngress(
+                    ingress.getNamespace(),
+                    v1beta1Ingress,
+                    PRETTY_FORMAT);
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "ingress 创建失败,ingressDTO={}, response={}", ingressDTO, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            LoggerUtil.error(logger, e, "ingress 创建失败,ingress={}, response={}", ingress, e.getResponseBody());
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(NOT_FOUND, "命名空间不存在");
+            }else if (e.getCode() == ALREADY_EXIST) {
+                throw new K8sApiException(ALREADY_EXIST, "ingress已经存在");
+            }else {
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "ingress 创建异常,ingress={}", ingress);
         }
     }
 
-    /**
-     * @see IngressApi#delete(String, String)
-     * @param namespace
-     * @param name
-     */
     @Override
     public void delete(String namespace, String name) {
-        //@todo 判断是否存在
-        V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
-                .withApiVersion(IngressDTO.API_VERSION)
-                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
-                .build();
         try {
-            extensionsV1beta1Api.deleteNamespacedIngress(name, namespace, v1DeleteOptions, PRETTY_FORMAT, null, null, FOREGROUND_PROPAGATION_POLICY);;
+
+            deleteIngress(namespace, name);
+
         }catch (ApiException e) {
             LoggerUtil.error(logger, e, "ingress 删除失败,name={}, namespace={}, response={}", name, namespace, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(NOT_FOUND, "ingress不存在");
+            }else {
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         }catch (Exception e) {
             //K8s swagger 异常, 无需进行处理
         }
     }
 
-    /**
-     * @see IngressApi#deleteIfExists(String, String)
-     * @param namespace
-     * @param name
-     */
     @Override
     public void deleteIfExists(String namespace, String name) {
         V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
-                .withApiVersion(IngressDTO.API_VERSION)
+                .withApiVersion(Ingress.API_VERSION)
                 .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
                 .build();
         try {
             extensionsV1beta1Api.deleteNamespacedIngress(name, namespace, v1DeleteOptions, PRETTY_FORMAT, null, null, FOREGROUND_PROPAGATION_POLICY);;
         }catch (ApiException e) {
-            LoggerUtil.error(logger, e, "ingress 删除失败,name={}, namespace={}, response={}", name, namespace, e.getResponseBody());
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "ingress 删除失败,name={}, namespace={}, response={}", name, namespace, e.getResponseBody());
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         }catch (Exception e) {
             //K8s Swagger 异常, 无需进行处理
+            LoggerUtil.error(logger, e, "ingress 删除异常,name={}, namespace={}", name, namespace);
         }
     }
 
-    /**
-     * @see IngressApi#exists(String, String)
-     * @param namespace
-     * @param name
-     * @return
-     */
+    //@todo
     @Override
     public boolean exists(String namespace, String name) {
         return false;
     }
+
+    private void deleteIngress(String namespace, String name) throws ApiException{
+        V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
+                .withApiVersion(Ingress.API_VERSION)
+                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
+                .build();
+        extensionsV1beta1Api.deleteNamespacedIngress(
+                name,
+                namespace,
+                v1DeleteOptions,
+                PRETTY_FORMAT,
+                null,
+                null,
+                FOREGROUND_PROPAGATION_POLICY);
+    }
 }

+ 82 - 49
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/NamespaceApiImpl.java

@@ -7,11 +7,9 @@ import io.kubernetes.client.models.V1DeleteOptionsBuilder;
 import io.kubernetes.client.models.V1Namespace;
 import io.kubernetes.client.models.V1NamespaceList;
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.NamespaceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Namespace;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.Namespace;
 import nju.seec.SEECdemo.util.LoggerUtil;
-import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -20,6 +18,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.*;
 import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
 import static nju.seec.SEECdemo.util.Constants.METADATA_NAME_SELECTOR;
 import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
@@ -35,67 +34,81 @@ public class NamespaceApiImpl implements NamespaceApi{
     /**
      * @param namespace
      * @return
-     * @see NamespaceApi#create(nju.seec.SEECdemo.logic.api.k8s.dto.NamespaceDTO)
+     * @see NamespaceApi#create(Namespace)
      */
     @Override
-    public void create(NamespaceDTO namespace) throws K8sApiException{
-        if (exists(namespace.getName())) {
-            throw new K8sApiException(K8sApiException.NAMESPACE_ALREADY_EXIST);
-        }
+    public void create(Namespace namespace) throws K8sApiException{
         V1Namespace v1Namespace = namespace.toV1Namespace();
         try {
             coreV1Api.createNamespace(v1Namespace, "true");
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "Namespace创建失败,namespace={}, v1Namespace={}, response={}", namespace, v1Namespace, e.getResponseBody());
-            throw new K8sApiException(K8sApiException.SYSTEM_ERROR);
+            if (e.getCode() == ALREADY_EXIST) {
+                throw new K8sApiException(K8sApiException.NAMESPACE_ALREADY_EXIST);
+            }else{
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "Namespace创建异常, namespace={}, v1Namespace={}", namespace, v1Namespace);
         }
     }
 
+    /**
+     *
+     * @param name
+     * @throws K8sApiException
+     */
     @Override
-    public void deleteByName(String name) throws K8sApiException{
-        if (!exists(name)) {
-            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
-        }
+    public void delete(String name) throws K8sApiException{
         try {
-            V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
-                    .withApiVersion(Namespace.VERSION)
-                    .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
-                    .build();
-            coreV1Api.deleteNamespace(
-                    name,
-                    v1DeleteOptions,
-                    PRETTY_FORMAT,
-                    null,
-                    null,
-                    FOREGROUND_PROPAGATION_POLICY);
+            deleteNamespace(name);
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "Namespace删除失败,name={}, response={}", name , e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            if (e.getCode() == NOT_FOUND) {
+                throw K8s_NAMESPACE_NOT_EXIST;
+            }else {
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            //k8s 由swagger导致的bug
+            LoggerUtil.error(logger, e, "Namespace删除异常, name={}", name);
+        }
+    }
+
+    @Override
+    public void deleteIfExists(String name) {
+        try {
+            deleteNamespace(name);
+        } catch (ApiException e) {
+            //只打印系统执行一场
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "Namespace删除失败,name={}, response={}", name , e.getResponseBody());
+            }
         } catch (Exception e) {
             //k8s 由swagger导致的bug
-            LoggerUtil.warn(logger, e, "k8s swagger bug");
+            LoggerUtil.error(logger, e, "Namespace删除异常, name={}", name);
         }
     }
 
     @Override
     public Namespace getByName(String name) throws K8sApiException{
-        if (exists(name)){
-            try {
-                V1NamespaceList v1NamespaceList = coreV1Api.listNamespace(
-                        PRETTY_FORMAT,
-                        null,
-                        METADATA_NAME_SELECTOR + name,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null,
-                        null);
-                List<Namespace> result = v1NamespaceList.getItems().stream().limit(1).map(Namespace::new).collect(Collectors.toList());
-                return result.get(0);
-            }catch (ApiException e) {
-                LoggerUtil.error(logger, e, "查询Namespace失败,name={}, response={}", name, e.getResponseBody());
-                throw new K8sApiException(K8sApiException.SYSTEM_ERROR);
+        try {
+            V1NamespaceList v1NamespaceList = coreV1Api.listNamespace(
+                    PRETTY_FORMAT,
+                    null,
+                    METADATA_NAME_SELECTOR + name,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null,
+                    null);
+            List<Namespace> result = v1NamespaceList.getItems().stream().limit(1).map(Namespace::new).collect(Collectors.toList());
+            return result.get(0);
+        }catch (ApiException e) {
+            LoggerUtil.error(logger, e, "查询Namespace失败,name={}, response={}", name, e.getResponseBody());
+            if (e.getCode() != NOT_FOUND) {
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
             }
         }
         return null;
@@ -119,7 +132,7 @@ public class NamespaceApiImpl implements NamespaceApi{
             return namespaces;
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "获取全部Namespace异常, response={}", e.getResponseBody());
-            throw new K8sApiException(K8sApiException.SYSTEM_ERROR);
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
         }
     }
 
@@ -147,13 +160,12 @@ public class NamespaceApiImpl implements NamespaceApi{
             return namespaces;
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "根据标签获取Namespace异常, key={}, value={}, response={}", key, value, e.getResponseBody());
-            throw new K8sApiException(K8sApiException.SYSTEM_ERROR);
+            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
         }
     }
 
     @Override
     public boolean exists(String name) {
-        if (StringUtils.isBlank(name)) throw new K8sApiException(K8sApiException.ILLEGAL_PARAMETER, "名称不能为空");
         try {
             V1NamespaceList v1NamespaceList = coreV1Api.listNamespace(PRETTY_FORMAT,
                     null,
@@ -166,12 +178,34 @@ public class NamespaceApiImpl implements NamespaceApi{
                     null);
             return v1NamespaceList.getItems().size() > 0;
         }catch (ApiException e) {
-            LoggerUtil.error(logger, e, "查询命名空间失败, name={}, response={}", name, e.getResponseBody());
-            return false;
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "查询命名空间失败, name={}, response={}", name, e.getResponseBody());
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         }
+        return false;
     }
 
 
+    /**
+     * 删除命名空间,执行错误会抛出一切异常
+     * @param name
+     * @throws ApiException
+     */
+    private void deleteNamespace(String name) throws ApiException{
+        V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
+                .withApiVersion(Namespace.VERSION)
+                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
+                .build();
+        coreV1Api.deleteNamespace(
+                name,
+                v1DeleteOptions,
+                PRETTY_FORMAT,
+                null,
+                null,
+                FOREGROUND_PROPAGATION_POLICY);
+    }
+
     private String buildLabelSelector(String key, String value) {
         return key + "=" + value;
     }
@@ -187,5 +221,4 @@ public class NamespaceApiImpl implements NamespaceApi{
         return result.toString();
     }
 
-
 }

+ 69 - 70
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ResourceQuotaImpl.java

@@ -10,15 +10,16 @@ import io.kubernetes.client.models.V1DeleteOptions;
 import io.kubernetes.client.models.V1DeleteOptionsBuilder;
 import io.kubernetes.client.models.V1ResourceQuotaList;
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ResourceQuotaDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.ResourceQuota;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
 import nju.seec.SEECdemo.util.LoggerUtil;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.ALREADY_EXIST;
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.NOT_FOUND;
 import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
 import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
 
@@ -33,21 +34,8 @@ public class ResourceQuotaImpl implements ResourceQuotaApi {
     @Autowired
     private NamespaceApi namespaceApi;
 
-    /**
-     * @see ResourceQuotaApi#create(nju.seec.SEECdemo.logic.api.k8s.dto.ResourceQuotaDTO)
-     * @param resourceQuota
-     * @return
-     */
     @Override
-    public void create(ResourceQuotaDTO resourceQuota) throws K8sApiException{
-        if (!namespaceApi.exists(resourceQuota.getNamespace())) {
-            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
-        }
-
-        if (this.exist(resourceQuota.getNamespace(), resourceQuota.getName())) {
-            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_ALREADY_EXIST);
-        }
-
+    public void create(ResourceQuota resourceQuota) throws K8sApiException{
         try {
             V1ResourceQuota v1ResourceQuota = resourceQuota.toV1ResourceQuota();
             coreV1Api.createNamespacedResourceQuota(
@@ -57,72 +45,54 @@ public class ResourceQuotaImpl implements ResourceQuotaApi {
         } catch (ApiException e) {
             LoggerUtil.error(logger, e, "创建resource quota失败, resourceQuota={}, response={}",
                     resourceQuota, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(NOT_FOUND, "命名空间不存在");
+            }else if (e.getCode() == ALREADY_EXIST) {
+                throw new K8sApiException(ALREADY_EXIST, "资源配额已经存在");
+            }else {
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "创建resource quota失败, resourceQuota={}", resourceQuota);
         }
     }
 
-    /**
-     * @see ResourceQuotaApi#update(ResourceQuotaDTO)
-     * @param resourceQuota
-     * @return
-     */
     @Override
-    public void update(ResourceQuotaDTO resourceQuota) throws K8sApiException{
-        if (!namespaceApi.exists(resourceQuota.getNamespace())) {
-            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
-        }
-
-        if (!this.exist(resourceQuota.getNamespace(), resourceQuota.getName())) {
-            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_NOT_EXIST);
-        }
+    public void delete(String namespace, String name) throws K8sApiException{
         try {
-            coreV1Api.patchNamespacedResourceQuota(
-                    resourceQuota.getNamespace(),
-                    resourceQuota.getNamespace(),
-                    resourceQuota.toV1ResourceQuota(),
-                    PRETTY_FORMAT);
+
+            deleteResourceQuota(namespace, name);
+
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "更新Resource Quota失败, resourceQuota={}, response={}", resourceQuota, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            LoggerUtil.error(logger, e, "删除resource quota失败,namespace={}, name={}, response={}",
+                    namespace, name, e.getResponseBody());
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(NOT_FOUND, "资源配额不存在");
+            }else {
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         }
     }
 
     @Override
-    public void delete(String namespace, String name) throws K8sApiException{
-        if (!namespaceApi.exists(namespace)) {
-            throw new K8sApiException(K8sApiException.NAMESPACE_NOT_EXIST);
-        }
-        if (!this.exist(namespace, name)) {
-            throw new K8sApiException(K8sApiException.RESOURCE_QUOTA_NOT_EXIST);
-        }
+    public void deleteIfExists(String namespace, String name) {
+        try {
 
-        V1DeleteOptions deleteOptions = new V1DeleteOptionsBuilder()
-                .withApiVersion(ResourceQuota.API_VERSION)
-                .withApiVersion(ResourceQuota.KIND)
-                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
-                .build();
+            deleteResourceQuota(namespace, name);
 
-        try {
-            coreV1Api.deleteNamespacedResourceQuota(
-                    name,
-                    namespace,
-                    deleteOptions,
-                    PRETTY_FORMAT,
-                    null,
-                    null,
-                    FOREGROUND_PROPAGATION_POLICY);
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "删除resource quota异常,namespace={}, name={}, response={}",
-                    namespace, name, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "删除resource quota失败,namespace={}, name={}, response={}",
+                        namespace, name, e.getResponseBody());
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "删除resource quota异常,namespace={}, name={}", namespace, name);
         }
     }
 
     @Override
     public ResourceQuota getByName(String namespace, String name) throws K8sApiException {
-        if (exist(namespace, name)) {
-            return null;
-        }
         try {
 
             V1ResourceQuotaList resourceQuotaList = coreV1Api.listNamespacedResourceQuota(namespace,
@@ -137,10 +107,15 @@ public class ResourceQuotaImpl implements ResourceQuotaApi {
                     null);
             return new ResourceQuota(resourceQuotaList.getItems().get(0));
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, response={}", namespace, e.getResponseBody());
-            throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, name={}, response={}",
+                        namespace,
+                        name,
+                        e.getResponseBody());
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
         }
-
+        return null;
     }
 
     @Override
@@ -159,10 +134,34 @@ public class ResourceQuotaImpl implements ResourceQuotaApi {
                     null);
             return resourceQuotaList.getItems().size() > 0;
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, response={}", namespace, e.getResponseBody());
-            return false;
+            if (e.getCode() != NOT_FOUND) {
+                LoggerUtil.error(logger, e, "查找resource quota失败, namespace={}, name={}, response={}",
+                        namespace,
+                        name,
+                        e.getResponseBody());
+                throw K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "查找resource quota异常, namespace={}, name={}",
+                    namespace,
+                    name);
         }
+        return false;
     }
 
-
+    private void deleteResourceQuota(String namespace, String name) throws ApiException{
+        V1DeleteOptions deleteOptions = new V1DeleteOptionsBuilder()
+                .withApiVersion(ResourceQuota.API_VERSION)
+                .withApiVersion(ResourceQuota.KIND)
+                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
+                .build();
+        coreV1Api.deleteNamespacedResourceQuota(
+                name,
+                namespace,
+                deleteOptions,
+                PRETTY_FORMAT,
+                null,
+                null,
+                FOREGROUND_PROPAGATION_POLICY);
+    }
 }

+ 72 - 10
src/main/java/nju/seec/SEECdemo/logic/api/k8s/impl/ServiceApiImpl.java

@@ -2,38 +2,100 @@ package nju.seec.SEECdemo.logic.api.k8s.impl;
 
 import io.kubernetes.client.ApiException;
 import io.kubernetes.client.apis.CoreV1Api;
+import io.kubernetes.client.models.V1DeleteOptions;
+import io.kubernetes.client.models.V1DeleteOptionsBuilder;
 import io.kubernetes.client.models.V1Service;
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
 import nju.seec.SEECdemo.logic.api.k8s.ServiceApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ServiceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
+import nju.seec.SEECdemo.logic.api.k8s.model.Service;
 import nju.seec.SEECdemo.util.LoggerUtil;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.ALREADY_EXIST;
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.K8s_SYSTEM_ERROR_EXCEPTION;
+import static nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException.NOT_FOUND;
+import static nju.seec.SEECdemo.util.Constants.FOREGROUND_PROPAGATION_POLICY;
 import static nju.seec.SEECdemo.util.Constants.PRETTY_FORMAT;
 
 /**
  * author: rale
  * createdAt: 1/3/19
  */
-@Service
+@org.springframework.stereotype.Service
 public class ServiceApiImpl implements ServiceApi{
     private static final Logger logger = LoggerUtil.getLogger(ServiceApi.class);
 
-    @Autowired
-    private NamespaceApi namespaceApi;
-
     @Autowired
     private CoreV1Api coreV1Api;
 
     @Override
-    public void create(ServiceDTO serviceDTO) {
+    public void create(Service service) {
         try {
-            V1Service v1Service = serviceDTO.toV1Service();
-            coreV1Api.createNamespacedService(serviceDTO.getNamespace(), v1Service, PRETTY_FORMAT);
+            V1Service v1Service = service.toV1Service();
+            coreV1Api.createNamespacedService(service.getNamespace(), v1Service, PRETTY_FORMAT);
         } catch (ApiException e) {
-            LoggerUtil.error(logger, e, "service创建失败, service={}, response={}", serviceDTO, e.getResponseBody());
+            LoggerUtil.error(logger, e, "service创建失败, service={}, response={}", service, e.getResponseBody());
+            if (e.getCode() == ALREADY_EXIST) {
+                throw new K8sApiException(ALREADY_EXIST, "Service已经存在");
+            }else if (e.getCode() == NOT_FOUND){
+                throw new K8sApiException(NOT_FOUND, "Namespace不存在");
+            }else {
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        }
+    }
+
+    @Override
+    public void delete(String namespace, String name) {
+        try {
+
+            deleteService(namespace, name);
+
+        }catch (ApiException e) {
+            LoggerUtil.error(logger, e, "Service删除失败,namespace={}, name={}, response={}",
+                    namespace, name, e.getResponseBody());
+
+            if (e.getCode() == NOT_FOUND) {
+                throw new K8sApiException(K8sApiException.NOT_FOUND, "Service不存在");
+            }else {
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        }catch (Exception e) {
+            LoggerUtil.error(logger, e, "Service删除异常,namespace={}, name={}, response={}", namespace, name);
         }
     }
+
+    @Override
+    public void deleteIfExists(String namespace, String name) {
+        try {
+            deleteService(namespace, name);
+        } catch (ApiException e) {
+            LoggerUtil.error(logger, e, "Service删除失败,namespace={}, name={}, response={}",
+                    namespace, name, e.getResponseBody());
+
+            if (e.getCode() != NOT_FOUND) {
+                throw K8s_SYSTEM_ERROR_EXCEPTION;
+            }
+        } catch (Exception e) {
+            LoggerUtil.error(logger, e, "Service删除异常,namespace={}, name={}, response={}", namespace, name);
+        }
+    }
+
+    private void deleteService(String namespace, String name) throws ApiException{
+        V1DeleteOptions v1DeleteOptions = new V1DeleteOptionsBuilder()
+                .withApiVersion(Service.API_VERSION)
+                .withPropagationPolicy(FOREGROUND_PROPAGATION_POLICY)
+                .build();
+        coreV1Api.deleteNamespacedService(
+                name,
+                namespace,
+                v1DeleteOptions,
+                PRETTY_FORMAT,
+                null,
+                null,
+                FOREGROUND_PROPAGATION_POLICY);
+    }
 }

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

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.models.V1Container;
 import io.kubernetes.client.models.V1ContainerBuilder;
@@ -20,7 +20,7 @@ import static nju.seec.SEECdemo.util.Constants.NAME_PATTERN;
  */
 @Data
 @NoArgsConstructor
-public class ContainerDTO {
+public class Container {
 
     private static final String IMAGE_PULL_POLICY = "Always";
 //    private static final String IMAGE_PULL_POLICY = "IfNotPresent";
@@ -33,7 +33,7 @@ public class ContainerDTO {
     private String image;
 
 
-    private Set<ContainerPortDTO> ports = new HashSet<>();
+    private Set<ContainerPort> ports = new HashSet<>();
 
     /* 启动指令的参数 */
     private List<String> args;
@@ -52,7 +52,7 @@ public class ContainerDTO {
                 .withImagePullPolicy(IMAGE_PULL_POLICY)
                 .withArgs(args)
                 .withCommand(command)
-                .withPorts(ports.stream().map(ContainerPortDTO::toV1ContainerPort).collect(Collectors.toList()))
+                .withPorts(ports.stream().map(ContainerPort::toV1ContainerPort).collect(Collectors.toList()))
                 .withEnv(env
                         .entrySet()
                         .stream()

+ 4 - 4
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/ContainerPortDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ContainerPort.java

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.models.V1ContainerPort;
 import io.kubernetes.client.models.V1ContainerPortBuilder;
@@ -19,7 +19,7 @@ import static nju.seec.SEECdemo.util.Constants.NAME_PATTERN;
 @Data
 @EqualsAndHashCode
 @NoArgsConstructor
-public class ContainerPortDTO {
+public class ContainerPort {
 
     @NotNull
     @Pattern(regexp = NAME_PATTERN)
@@ -33,8 +33,8 @@ public class ContainerPortDTO {
     @Pattern(regexp = "^(TCP|UDP)$")
     private String protocol;
 
-    public ContainerPortDTO(V1ContainerPort v1ContainerPort) {
-        ContainerPortDTO containerPort = new ContainerPortDTO();
+    public ContainerPort(V1ContainerPort v1ContainerPort) {
+        ContainerPort containerPort = new ContainerPort();
         containerPort.setName(v1ContainerPort.getName());
         containerPort.setPort(v1ContainerPort.getContainerPort());
         containerPort.setProtocol(v1ContainerPort.getProtocol());

+ 1 - 3
src/main/java/nju/seec/SEECdemo/logic/api/k8s/util/CpuQuantity.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/CpuQuantity.java

@@ -1,11 +1,9 @@
-package nju.seec.SEECdemo.logic.api.k8s.util;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.Quantity;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.math.BigDecimal;
-
 /**
  * CPU配额数量,默认单位为m,即CPU时间
  */

+ 6 - 6
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/DeploymentDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Deployment.java

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.models.*;
 import lombok.Data;
@@ -15,9 +15,9 @@ import java.util.stream.Collectors;
  */
 @Data
 @NoArgsConstructor
-public class DeploymentDTO {
+public class Deployment {
 
-    private static final String DEPLOYMENT_VERSION = "apps/v1";
+    public static final String API_VERSION = "apps/v1";
 
     private static final String DEPLOYMENT_KIND = "Deployment";
 
@@ -26,7 +26,7 @@ public class DeploymentDTO {
 
     private String namespace;
 
-    private List<ContainerDTO> containers = new ArrayList<>();
+    private List<Container> containers = new ArrayList<>();
 
     private List<String> imagePullSecrets = new ArrayList<>();
 
@@ -37,7 +37,7 @@ public class DeploymentDTO {
 
     public V1Deployment toV1Deployment(){
         return new V1DeploymentBuilder()
-                .withApiVersion(DEPLOYMENT_VERSION)
+                .withApiVersion(API_VERSION)
                 .withKind(DEPLOYMENT_KIND)
                 .withMetadata(this.toV1ObjectMeta())
                 .withSpec(this.toV1DeploymentSpec())
@@ -66,7 +66,7 @@ public class DeploymentDTO {
                 .map(secret -> new V1LocalObjectReference().name(secret))
                 .collect(Collectors.toList());
         V1PodSpec v1PodSpec = new V1PodSpecBuilder()
-                .addAllToContainers(containers.stream().map(ContainerDTO::toV1Container).collect(Collectors.toList()))
+                .addAllToContainers(containers.stream().map(Container::toV1Container).collect(Collectors.toList()))
                 .withImagePullSecrets(references)
                 .build();
         V1PodTemplateSpec v1PodTemplateSpec = new V1PodTemplateSpecBuilder()

+ 4 - 4
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/IngressDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Ingress.java

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.IntOrString;
 import io.kubernetes.client.models.*;
@@ -17,11 +17,12 @@ import java.util.stream.Collectors;
  */
 @Data
 @NoArgsConstructor
-public class IngressDTO {
+public class Ingress {
     public static final String API_VERSION = "extensions/v1beta1";
 
     private static final String KIND = "Ingress";
 
+    private static final String REWRITE_ANNOTATION = "nginx.ingress.kubernetes.io/rewrite-target";
     private String namespace;
 
     private String name;
@@ -66,8 +67,7 @@ public class IngressDTO {
         return new V1ObjectMetaBuilder()
                 .withName(name)
                 .withNamespace(namespace)
-                //@fixme ingress重定向的位置,目前默认为根路径,以后应当允许配置
-                .addToAnnotations("nginx.ingress.kubernetes.io/rewrite-target", redirectPath)
+                .addToAnnotations(REWRITE_ANNOTATION, redirectPath)
                 .build();
     }
 

+ 2 - 10
src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/Namespace.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Namespace.java

@@ -1,25 +1,20 @@
-package nju.seec.SEECdemo.logic.api.k8s.vo;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.models.*;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import lombok.ToString;
 import nju.seec.SEECdemo.util.DateUtil;
-import org.springframework.data.annotation.ReadOnlyProperty;
-import org.springframework.util.CollectionUtils;
 
 import javax.validation.constraints.NotNull;
 import java.time.LocalDateTime;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
 /**
  * author: rale
- * createdAt: 12/22/18
+ * createdAt: 1/4/19
  */
-@ToString
 @Data
 @NoArgsConstructor
 public class Namespace {
@@ -55,13 +50,10 @@ public class Namespace {
                 .withLabels(labels)
                 .withAnnotations(annotations)
                 .build();
-        V1NamespaceSpec v1NamespaceSpec = new V1NamespaceSpecBuilder()
-                .build();
         V1Namespace v1Namespace = new V1NamespaceBuilder()
                 .withApiVersion(VERSION)
                 .withKind(KIND)
                 .withMetadata(v1ObjectMeta)
-                .withSpec(v1NamespaceSpec)
                 .build();
         return v1Namespace;
 

+ 4 - 5
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/ResourceQuotaDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ResourceQuota.java

@@ -1,11 +1,9 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.Quantity;
 import io.kubernetes.client.models.*;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -16,7 +14,7 @@ import java.util.Map;
  */
 @Data
 @NoArgsConstructor
-public class ResourceQuotaDTO {
+public class ResourceQuota {
     public static final String API_VERSION = "v1";
 
     public static final String KIND = "ResourceQuota";
@@ -38,9 +36,10 @@ public class ResourceQuotaDTO {
 
     private StorageQuantity maxMemoryTotalLimit;
 
-    public ResourceQuotaDTO(V1ResourceQuota v1ResourceQuota) {
+    public ResourceQuota(V1ResourceQuota v1ResourceQuota) {
         this.namespace = v1ResourceQuota.getMetadata().getNamespace();
         this.name = v1ResourceQuota.getMetadata().getName();
+
     }
 
     public V1ResourceQuota toV1ResourceQuota(){

+ 6 - 6
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/ServiceDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/Service.java

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.models.*;
 import lombok.Data;
@@ -9,9 +9,9 @@ import java.util.stream.Collectors;
 
 @Data
 @NoArgsConstructor
-public class ServiceDTO {
+public class Service {
 
-    private static final String SERVICE_VERSION = "v1";
+    public static final String API_VERSION = "v1";
 
     private static final String SERVICE_KIND = "Service";
 
@@ -19,13 +19,13 @@ public class ServiceDTO {
 
     private String namespace;
 
-    private Set<ServicePortDTO> servicePorts = new HashSet<>();
+    private Set<ServicePort> servicePorts = new HashSet<>();
 
     private Map<String, String> selectors = new HashMap<>();
 
     public V1Service toV1Service() {
         V1Service v1Service = new V1ServiceBuilder()
-                .withApiVersion(SERVICE_VERSION)
+                .withApiVersion(API_VERSION)
                 .withKind(SERVICE_KIND)
                 .withMetadata(this.toV1ObjectMeta())
                 .withSpec(this.toV1ServiceSpec())
@@ -43,7 +43,7 @@ public class ServiceDTO {
     private V1ServiceSpec toV1ServiceSpec() {
         V1ServiceSpec serviceSpec = new V1ServiceSpecBuilder()
                 .withSelector(selectors)
-                .withPorts(servicePorts.stream().map(ServicePortDTO::toV1ServicePort).collect(Collectors.toList()))
+                .withPorts(servicePorts.stream().map(ServicePort::toV1ServicePort).collect(Collectors.toList()))
                 .build();
         return serviceSpec;
     }

+ 3 - 3
src/main/java/nju/seec/SEECdemo/logic/api/k8s/dto/ServicePortDTO.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/ServicePort.java

@@ -1,4 +1,4 @@
-package nju.seec.SEECdemo.logic.api.k8s.dto;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.IntOrString;
 import io.kubernetes.client.models.V1ServicePort;
@@ -17,7 +17,7 @@ import javax.validation.constraints.NotNull;
 @Data
 @NoArgsConstructor
 @EqualsAndHashCode
-public class ServicePortDTO {
+public class ServicePort {
 
     @NotNull
     private String name;
@@ -34,7 +34,7 @@ public class ServicePortDTO {
     @NotNull
     private int targetPort;
 
-    public ServicePortDTO(V1ServicePort v1ServicePort) {
+    public ServicePort(V1ServicePort v1ServicePort) {
         this.name = v1ServicePort.getName();
         this.port = v1ServicePort.getPort();
         this.targetPort = v1ServicePort.getTargetPort().getIntValue();

+ 1 - 4
src/main/java/nju/seec/SEECdemo/logic/api/k8s/util/StorageQuantity.java → src/main/java/nju/seec/SEECdemo/logic/api/k8s/model/StorageQuantity.java

@@ -1,12 +1,9 @@
-package nju.seec.SEECdemo.logic.api.k8s.util;
+package nju.seec.SEECdemo.logic.api.k8s.model;
 
 import io.kubernetes.client.custom.Quantity;
-import io.kubernetes.client.custom.QuantityFormatter;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
-import java.math.BigDecimal;
-
 /**
  * 存储配额的单位,默认为MB
  * 可选的为KB,MB,GB

+ 0 - 23
src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/Ingress.java

@@ -1,23 +0,0 @@
-package nju.seec.SEECdemo.logic.api.k8s.vo;
-
-import io.kubernetes.client.models.V1beta1Ingress;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-/**
- * author: rale
- * createdAt: 1/5/19
- */
-@Data
-@NoArgsConstructor
-public class Ingress {
-
-    private String name;
-
-    private String namespace;
-
-    public Ingress(V1beta1Ingress v1beta1Ingress) {
-        this.name = v1beta1Ingress.getMetadata().getName();
-        this.namespace = v1beta1Ingress.getMetadata().getNamespace();
-    }
-}

+ 2 - 2
src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/LimitRange.java

@@ -4,8 +4,8 @@ import io.kubernetes.client.custom.Quantity;
 import io.kubernetes.client.models.*;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.CpuQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.StorageQuantity;
 
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Pattern;

+ 0 - 44
src/main/java/nju/seec/SEECdemo/logic/api/k8s/vo/ResourceQuota.java

@@ -1,44 +0,0 @@
-package nju.seec.SEECdemo.logic.api.k8s.vo;
-
-import io.kubernetes.client.custom.Quantity;
-import io.kubernetes.client.models.*;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
-
-import java.util.HashMap;
-import java.util.Map;
-
-@Data
-@NoArgsConstructor
-public class ResourceQuota {
-
-    public static final String API_VERSION = "v1";
-
-    public static final String KIND = "ResourceQuota";
-
-    private static final String HARD_REQUEST_CPU = "requests.cpu";
-    private static final String HARD_REQUEST_MEMORY = "requests.memory";
-    private static final String HARD_LIMITS_CPU = "limits.cpu";
-    private static final String HARD_LIMITS_MEMORY = "limits.memory";
-
-    private String namespace;
-
-    private String name;
-
-    private CpuQuantity maxCpuTotalRequest;
-
-    private StorageQuantity maxMemoryTotalRequest;
-
-    private CpuQuantity maxCpuTotalLimit;
-
-    private StorageQuantity maxMemoryTotalLimit;
-
-    public ResourceQuota(V1ResourceQuota v1ResourceQuota) {
-        this.namespace = v1ResourceQuota.getMetadata().getNamespace();
-        this.name = v1ResourceQuota.getMetadata().getName();
-    }
-
-
-}

+ 28 - 29
src/main/java/nju/seec/SEECdemo/logic/service/impl/ApplicationServiceImpl.java

@@ -1,9 +1,9 @@
 package nju.seec.SEECdemo.logic.service.impl;
 
 import nju.seec.SEECdemo.logic.api.k8s.*;
-import nju.seec.SEECdemo.logic.api.k8s.dto.DeploymentDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ServiceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
+import nju.seec.SEECdemo.logic.api.k8s.model.Service;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
 import nju.seec.SEECdemo.logic.api.k8s.util.SecretTypeEnum;
 import nju.seec.SEECdemo.logic.api.k8s.vo.SecretVO;
@@ -15,12 +15,11 @@ import nju.seec.SEECdemo.web.dto.ContainerDTO;
 import nju.seec.SEECdemo.web.dto.PortDTO;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 
 import java.util.*;
 import java.util.stream.Collectors;
 
-@Service
+@org.springframework.stereotype.Service
 public class ApplicationServiceImpl implements ApplicationService{
 
     private static final Logger logger = LoggerUtil.getLogger(ApplicationServiceImpl.class);
@@ -65,16 +64,16 @@ public class ApplicationServiceImpl implements ApplicationService{
         String projectName = applicationDTO.getProjectName();
         if (namespaceApi.exists(projectName)) {
             try {
-                DeploymentDTO deploymentDTO = buildDeploymentDTO(applicationDTO);
-                LoggerUtil.info(logger, "deploymentDTO={}", deploymentDTO);
-                deploymentApi.createSync(deploymentDTO);
+                Deployment deployment = buildDeploymentDTO(applicationDTO);
+                LoggerUtil.info(logger, "deployment={}", deployment);
+                deploymentApi.createSync(deployment);
 
                 //判断service是否存在
-                ServiceDTO serviceDTO = buildServiceDTO(applicationDTO);
-                serviceApi.create(serviceDTO);
+                Service service = buildServiceDTO(applicationDTO);
+                serviceApi.create(service);
 
-                IngressDTO ingressDTO = buildIngressDTO(applicationDTO);
-                ingressApi.create(ingressDTO);
+                Ingress ingress = buildIngressDTO(applicationDTO);
+                ingressApi.create(ingress);
             } catch (K8sApiException e) {
 
             }
@@ -82,8 +81,8 @@ public class ApplicationServiceImpl implements ApplicationService{
 
     }
 
-    private DeploymentDTO buildDeploymentDTO(ApplicationDTO applicationDTO) {
-        DeploymentDTO deploymentDTO = applicationDTO.toDeploymentDTO();
+    private Deployment buildDeploymentDTO(ApplicationDTO applicationDTO) {
+        Deployment deployment = applicationDTO.toDeployment();
 
         //将registry密钥作为imagePullSecrets注入
         List<String> registrySecrets = secretApi
@@ -94,42 +93,42 @@ public class ApplicationServiceImpl implements ApplicationService{
                 .map(SecretVO::getName)
                 .collect(Collectors.toList()
         );
-        deploymentDTO.setImagePullSecrets(registrySecrets);
+        deployment.setImagePullSecrets(registrySecrets);
 
         //将一般密钥作为环境变量注入
         List<SecretVO> genericSecrets = secretApi.getSecretListByType(applicationDTO.getProjectName(), SecretTypeEnum.Generic);
         Map<String, String> env = new HashMap<>();
         genericSecrets.forEach(secretVO -> env.putAll(secretVO.getData()));
-        deploymentDTO.getContainers().forEach(containerDTO -> containerDTO.setEnv(env));
+        deployment.getContainers().forEach(containerDTO -> containerDTO.setEnv(env));
 
-        return deploymentDTO;
+        return deployment;
     }
 
-    private ServiceDTO buildServiceDTO(ApplicationDTO applicationDTO) {
-        return applicationDTO.toServiceDTO();
+    private Service buildServiceDTO(ApplicationDTO applicationDTO) {
+        return applicationDTO.toService();
     }
 
     //@todo 构建Ingress
     //@fixme 潜在bug 如果容器上的IP和Service上的IP并非一一对应,根据容器的IP暴露Service会出现映射错误
-    private IngressDTO buildIngressDTO(ApplicationDTO applicationDTO) {
+    private Ingress buildIngressDTO(ApplicationDTO applicationDTO) {
         String appName = applicationDTO.getName();
         String projectName = applicationDTO.getProjectName();
 
-        IngressDTO ingressDTO = new IngressDTO();
-        ingressDTO.setName(appName);
-        ingressDTO.setNamespace(projectName);
-        ingressDTO.setHttpHost("deernowl.cn");
+        Ingress ingress = new Ingress();
+        ingress.setName(appName);
+        ingress.setNamespace(projectName);
+        ingress.setHttpHost("deernowl.cn");
 
         //@todo lambda表达式解决
-        Set<IngressDTO.IngressDetailDTO> detailDTOS = new HashSet<>();
+        Set<Ingress.IngressDetailDTO> detailDTOS = new HashSet<>();
         for (ContainerDTO containerDTO : applicationDTO.getContainers()) {
             String containerName = containerDTO.getName();
 
-            Set<IngressDTO.IngressDetailDTO> ingressDetailDTOS = containerDTO.getPorts()
+            Set<Ingress.IngressDetailDTO> ingressDetailDTOS = containerDTO.getPorts()
                     .stream()
                     .filter(PortDTO::isExpose)
                     .map(portDTO ->{
-                        IngressDTO.IngressDetailDTO ingressDetailDTO = new IngressDTO.IngressDetailDTO();
+                        Ingress.IngressDetailDTO ingressDetailDTO = new Ingress.IngressDetailDTO();
                         ingressDetailDTO.setServiceName(applicationDTO.getName());
                         ingressDetailDTO.setPort(portDTO.getPort());
                         ingressDetailDTO.setPath("/" + appName + "/" + containerName);
@@ -138,7 +137,7 @@ public class ApplicationServiceImpl implements ApplicationService{
                     .collect(Collectors.toSet());
             detailDTOS.addAll(ingressDetailDTOS);
         }
-        ingressDTO.setHttpRules(detailDTOS);
-        return ingressDTO;
+        ingress.setHttpRules(detailDTOS);
+        return ingress;
     }
 }

+ 9 - 11
src/main/java/nju/seec/SEECdemo/logic/service/impl/ProjectServiceImpl.java

@@ -6,10 +6,8 @@ import nju.seec.SEECdemo.logic.api.k8s.LimitRangeApi;
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
 import nju.seec.SEECdemo.logic.api.k8s.ResourceQuotaApi;
 import nju.seec.SEECdemo.logic.api.k8s.SecretApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.NamespaceDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ResourceQuotaDTO;
-import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
-import nju.seec.SEECdemo.logic.api.k8s.vo.*;
+import nju.seec.SEECdemo.logic.api.k8s.model.Namespace;
+import nju.seec.SEECdemo.logic.api.k8s.model.ResourceQuota;
 import nju.seec.SEECdemo.logic.service.DBService;
 import nju.seec.SEECdemo.logic.service.ProjectService;
 import nju.seec.SEECdemo.logic.vo.DBDetailVO;
@@ -64,7 +62,7 @@ public class ProjectServiceImpl implements ProjectService{
         try {
             //创建部署空间
             String type = seecIITemplate.getName();
-            NamespaceDTO namespace = buildNamespace(projectName, type, description, startsAt, endsAt);
+            Namespace namespace = buildNamespace(projectName, type, description, startsAt, endsAt);
             namespaceApi.create(namespace);
         } catch (Exception e) {
             LoggerUtil.error(logger, e, "创建项目失败,projectName={}, projectType={}", projectName, seecIITemplate.getName());
@@ -77,7 +75,7 @@ public class ProjectServiceImpl implements ProjectService{
             secretApi.createPrivateRegistrySecret(projectName, registry.getHost(), registry.getUsername(), registry.getPassword());
 
             //创建项目资源限额
-            ResourceQuotaDTO resourceQuota = buildResourceQuota(projectName, seecIITemplate.getDefaultResourceConfig());
+            ResourceQuota resourceQuota = buildResourceQuota(projectName, seecIITemplate.getDefaultResourceConfig());
             resourceQuotaApi.create(resourceQuota);
 
             //创建项目资源默认配额
@@ -103,7 +101,7 @@ public class ProjectServiceImpl implements ProjectService{
             return projectVO;
         } catch (Exception e) {
             LoggerUtil.error(logger, e, "配置项目失败,projectName={}, projectType={}", projectName, seecIITemplate.getName());
-            namespaceApi.deleteByName(projectName);
+            namespaceApi.delete(projectName);
         }
         return null;
     }
@@ -127,8 +125,8 @@ public class ProjectServiceImpl implements ProjectService{
      * @param endsAt 项目的结束时间,存在Namespace的标签中
      * @return
      */
-    private NamespaceDTO buildNamespace(String projectName, String type, String description, LocalDate startsAt, LocalDate endsAt){
-        NamespaceDTO namespace = new NamespaceDTO();
+    private Namespace buildNamespace(String projectName, String type, String description, LocalDate startsAt, LocalDate endsAt){
+        Namespace namespace = new Namespace();
         namespace.setName(projectName);
         namespace.addToLabel(TYPE_LABEL, type);
         namespace.addToLabel(DESCRIPTION_LABEL, description);
@@ -137,8 +135,8 @@ public class ProjectServiceImpl implements ProjectService{
         return namespace;
     }
 
-    private ResourceQuotaDTO buildResourceQuota(String projectName, ResourceConfig resourceConfig) {
-        ResourceQuotaDTO resourceQuota = new ResourceQuotaDTO();
+    private ResourceQuota buildResourceQuota(String projectName, ResourceConfig resourceConfig) {
+        ResourceQuota resourceQuota = new ResourceQuota();
         resourceQuota.setNamespace(projectName);
         resourceQuota.setName(projectName);
         resourceQuota.setMaxMemoryTotalRequest(resourceConfig.getMaxMemory());

+ 2 - 2
src/main/java/nju/seec/SEECdemo/util/BeanUtil.java

@@ -1,8 +1,8 @@
 package nju.seec.SEECdemo.util;
 
 import nju.seec.SEECdemo.data.entity.ResourceConfig;
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.CpuQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.StorageQuantity;
 import nju.seec.SEECdemo.logic.vo.projecttemplate.ProjectTemplate;
 import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;

+ 17 - 17
src/main/java/nju/seec/SEECdemo/web/dto/ApplicationDTO.java

@@ -1,8 +1,8 @@
 package nju.seec.SEECdemo.web.dto;
 
 import lombok.Data;
-import nju.seec.SEECdemo.logic.api.k8s.dto.DeploymentDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ServiceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Deployment;
+import nju.seec.SEECdemo.logic.api.k8s.model.Service;
 import org.hibernate.validator.constraints.Range;
 
 import javax.validation.constraints.NotEmpty;
@@ -37,23 +37,23 @@ public class ApplicationDTO {
     @Range(min = 0)
     private int storageRequest;
 
-    public DeploymentDTO toDeploymentDTO(){
-        DeploymentDTO deploymentDTO = new DeploymentDTO();
-        deploymentDTO.setNamespace(projectName);
-        deploymentDTO.setName(name);
-        deploymentDTO.setContainers(containers.stream().map(ContainerDTO::toContainerDTO).collect(Collectors.toList()));
-        deploymentDTO.setReplicas(replicas);
-        deploymentDTO.setLabels(Collections.singletonMap(APPLICATION_LABEL, name));
+    public Deployment toDeployment(){
+        Deployment deployment = new Deployment();
+        deployment.setNamespace(projectName);
+        deployment.setName(name);
+        deployment.setContainers(containers.stream().map(ContainerDTO::toContainerDTO).collect(Collectors.toList()));
+        deployment.setReplicas(replicas);
+        deployment.setLabels(Collections.singletonMap(APPLICATION_LABEL, name));
         //@todo 设置资源限额
-        return deploymentDTO;
+        return deployment;
     }
 
-    public ServiceDTO toServiceDTO() {
-        ServiceDTO serviceDTO = new ServiceDTO();
-        serviceDTO.setNamespace(projectName);
-        serviceDTO.setName(name);
-        serviceDTO.setSelectors(Collections.singletonMap(APPLICATION_LABEL, name));
-        serviceDTO.setServicePorts(
+    public Service toService() {
+        Service service = new Service();
+        service.setNamespace(projectName);
+        service.setName(name);
+        service.setSelectors(Collections.singletonMap(APPLICATION_LABEL, name));
+        service.setServicePorts(
                 containers
                         .stream()
                         .map(ContainerDTO::getPorts)
@@ -61,6 +61,6 @@ public class ApplicationDTO {
                         .map(PortDTO::toServicePortDTO)
                         .collect(Collectors.toSet())
         );
-        return serviceDTO;
+        return service;
     }
 }

+ 7 - 6
src/main/java/nju/seec/SEECdemo/web/dto/ContainerDTO.java

@@ -1,6 +1,7 @@
 package nju.seec.SEECdemo.web.dto;
 
 import lombok.Data;
+import nju.seec.SEECdemo.logic.api.k8s.model.Container;
 
 import javax.validation.constraints.NotEmpty;
 import java.util.HashSet;
@@ -18,12 +19,12 @@ public class ContainerDTO {
 
     private Set<PortDTO> ports = new HashSet<>();
 
-    public nju.seec.SEECdemo.logic.api.k8s.dto.ContainerDTO toContainerDTO() {
-        nju.seec.SEECdemo.logic.api.k8s.dto.ContainerDTO containerDTO = new nju.seec.SEECdemo.logic.api.k8s.dto.ContainerDTO();
-        containerDTO.setName(name);
-        containerDTO.setImage(image);
-        containerDTO.setPorts(ports.stream().map(PortDTO::toContainerPortDTO).collect(Collectors.toSet()));
-        return containerDTO;
+    public Container toContainerDTO() {
+        Container container = new Container();
+        container.setName(name);
+        container.setImage(image);
+        container.setPorts(ports.stream().map(PortDTO::toContainerPortDTO).collect(Collectors.toSet()));
+        return container;
     }
 
 }

+ 14 - 17
src/main/java/nju/seec/SEECdemo/web/dto/PortDTO.java

@@ -1,15 +1,12 @@
 package nju.seec.SEECdemo.web.dto;
 
 import lombok.Data;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ContainerPortDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ServicePortDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.ContainerPort;
+import nju.seec.SEECdemo.logic.api.k8s.model.ServicePort;
 import org.hibernate.validator.constraints.Range;
 
 import javax.validation.constraints.Pattern;
 
-import static nju.seec.SEECdemo.util.Constants.NAME_PATTERN;
-
 @Data
 public class PortDTO {
 
@@ -31,24 +28,24 @@ public class PortDTO {
     @Pattern(regexp = "^(TCP|UDP)$")
     private String protocol;
 
-    public ContainerPortDTO toContainerPortDTO(){
-        ContainerPortDTO containerPortDTO = new ContainerPortDTO();
-        containerPortDTO.setName(protocol.toLowerCase() + "-" + port);
-        containerPortDTO.setPort(port);
-        containerPortDTO.setProtocol(protocol);
-        return containerPortDTO;
+    public ContainerPort toContainerPortDTO(){
+        ContainerPort containerPort = new ContainerPort();
+        containerPort.setName(protocol.toLowerCase() + "-" + port);
+        containerPort.setPort(port);
+        containerPort.setProtocol(protocol);
+        return containerPort;
     }
 
     /**
      * @warning 目前还没有考虑端口重合的问题
      * @return
      */
-    public ServicePortDTO toServicePortDTO() {
-        ServicePortDTO servicePortDTO = new ServicePortDTO();
-        servicePortDTO.setName(protocol.toLowerCase() + "-" + port + "-" + port);
-        servicePortDTO.setPort(port);
-        servicePortDTO.setTargetPort(port);
-        return servicePortDTO;
+    public ServicePort toServicePortDTO() {
+        ServicePort servicePort = new ServicePort();
+        servicePort.setName(protocol.toLowerCase() + "-" + port + "-" + port);
+        servicePort.setPort(port);
+        servicePort.setTargetPort(port);
+        return servicePort;
     }
 
 }

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

@@ -1,9 +1,9 @@
 package nju.seec.SEECdemo.service.api;
 
 import nju.seec.SEECdemo.logic.api.k8s.DeploymentApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ContainerDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.ContainerPortDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.DeploymentDTO;
+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 org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -25,18 +25,18 @@ public class DeploymentApiImplTest {
 
     @Test
     public void testCreate() {
-        DeploymentDTO deployment = new DeploymentDTO();
+        Deployment deployment = new Deployment();
         deployment.setName("test");
         deployment.setNamespace("demo");
         deployment.setReplicas(1);
 
-        ContainerDTO container = new ContainerDTO();
+        Container container = new Container();
         container.setName("container");
         container.setImage("10.1.1.243:18082/container_demo:2.0");
-        ContainerPortDTO containerPort = new ContainerPortDTO();
+        ContainerPort containerPort = new ContainerPort();
         containerPort.setPort(8081);
         containerPort.setProtocol("TCP");
-        Set<ContainerPortDTO> ports = new HashSet<>();
+        Set<ContainerPort> ports = new HashSet<>();
         ports.add(containerPort);
         container.setPorts(ports);
 

+ 8 - 10
src/test/java/nju/seec/SEECdemo/service/api/IngressApiImplTest.java

@@ -1,10 +1,8 @@
 package nju.seec.SEECdemo.service.api;
 
-import io.kubernetes.client.models.V1Secret;
-import io.kubernetes.client.models.V1SecretBuilder;
 import nju.seec.SEECdemo.logic.api.k8s.IngressApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO;
-import nju.seec.SEECdemo.logic.api.k8s.dto.IngressDTO.IngressDetailDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress;
+import nju.seec.SEECdemo.logic.api.k8s.model.Ingress.IngressDetailDTO;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,18 +25,18 @@ public class IngressApiImplTest {
 
     @Test
     public void testCreate(){
-        IngressDTO ingressDTO = new IngressDTO();
-        ingressDTO.setName("test");
-        ingressDTO.setNamespace("demo");
-        ingressDTO.setHttpHost("deernowl.cn");
+        Ingress ingress = new Ingress();
+        ingress.setName("test");
+        ingress.setNamespace("demo");
+        ingress.setHttpHost("deernowl.cn");
         IngressDetailDTO ingressDetailDTO = new IngressDetailDTO();
         ingressDetailDTO.setPath("/demo/test");
         ingressDetailDTO.setPort(8081);
         ingressDetailDTO.setServiceName("test");
         Set<IngressDetailDTO> details = new HashSet<>();
         details.add(ingressDetailDTO);
-        ingressDTO.setHttpRules(details);
-        ingressApi.create(ingressDTO);
+        ingress.setHttpRules(details);
+        ingressApi.create(ingress);
 
     }
 

+ 3 - 3
src/test/java/nju/seec/SEECdemo/service/api/NamespaceApiImplTest.java

@@ -1,7 +1,7 @@
 package nju.seec.SEECdemo.service.api;
 
 import nju.seec.SEECdemo.logic.api.k8s.NamespaceApi;
-import nju.seec.SEECdemo.logic.api.k8s.dto.NamespaceDTO;
+import nju.seec.SEECdemo.logic.api.k8s.model.Namespace;
 import nju.seec.SEECdemo.logic.api.k8s.exception.K8sApiException;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -26,7 +26,7 @@ public class NamespaceApiImplTest {
 
     @Test
     public void testCreate() throws K8sApiException {
-        NamespaceDTO namespace = new NamespaceDTO();
+        Namespace namespace = new Namespace();
         namespace.setName("group21");
         Map<String, String> labels = new HashMap<>();
         labels.put("test1", "test1");
@@ -37,7 +37,7 @@ public class NamespaceApiImplTest {
 
     @Test
     public void testDelete() throws K8sApiException {
-        namespaceApi.deleteByName("group21");
+        namespaceApi.delete("group21");
     }
 
     @Test

+ 2 - 2
src/test/java/nju/seec/SEECdemo/service/api/ResourceQuotaApiImplTest.java

@@ -1,8 +1,8 @@
 package nju.seec.SEECdemo.service.api;
 
-import nju.seec.SEECdemo.logic.api.k8s.util.CpuQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.CpuQuantity;
 import nju.seec.SEECdemo.logic.api.k8s.vo.ResourceQuota;
-import nju.seec.SEECdemo.logic.api.k8s.util.StorageQuantity;
+import nju.seec.SEECdemo.logic.api.k8s.model.StorageQuantity;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.boot.test.context.SpringBootTest;