This is an automated email from the ASF dual-hosted git repository.

cdmikechen pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/submarine.git


The following commit(s) were added to refs/heads/master by this push:
     new b830ac4a SUBMARINE-1381. Upgrade java k8s client versions to support 
1.25+
b830ac4a is described below

commit b830ac4adbfa0a1edf3810efcfe062cbce1b1892
Author: cdmikechen <[email protected]>
AuthorDate: Sun May 28 09:26:27 2023 +0800

    SUBMARINE-1381. Upgrade java k8s client versions to support 1.25+
    
    ### What is this PR for?
    Upgrade java k8s client versions to support 1.25+.
    
    ### What type of PR is it?
    Improvement
    
    ### Todos
    * [x] - `k8s.client-java.version` to 17.0.2
    * [x] - `k8s.fabric8.version` to 6.6.1
    * [x] - `io.javaoperatorsdk:operator-framework` to 4.3.2
    * [x] - change joda DateTime to java OffsetDateTime
    
    ### What is the Jira issue?
    https://issues.apache.org/jira/browse/SUBMARINE-1381
    
    ### How should this be tested?
    CI Test
    
    ### Screenshots (if appropriate)
    
    ### Questions:
    * Do the license files need updating? Yes
    * Are there breaking changes for older versions? Yes
    * Does this need new documentation? No
    
    Author: cdmikechen <[email protected]>
    
    Signed-off-by: cdmikechen <[email protected]>
    
    Closes #1065 from cdmikechen/SUBMARINE-1381 and squashes the following 
commits:
    
    38154538 [cdmikechen] change notebook time
    8c7ff5a3 [cdmikechen] fix indentation
    b2ff56b9 [cdmikechen] fix time format
    6725980f [cdmikechen] cast to 2023-05-23T09:01:12Z
    437ed828 [cdmikechen] try to fix by datetime formatter
    bf66c35e [cdmikechen] Fix agent test case changed apis
    e99ca2bf [cdmikechen] fix fabric8 new api
    c307013b [cdmikechen] add joda-time lib
    36573d97 [cdmikechen] fix version error
    fc221c16 [cdmikechen] Change license version
    c6473bf2 [cdmikechen] Update k8s java client version
---
 .github/workflows/master.yml                       |  4 +-
 LICENSE-binary                                     | 10 ++-
 pom.xml                                            | 16 +++--
 submarine-serve/pom.xml                            | 21 +++++--
 submarine-server/server-core/pom.xml               | 13 +++-
 .../server/manager/ExperimentManager.java          | 27 +++++---
 .../database/notebook/service/NotebookService.java | 13 +++-
 .../submarine/server/k8s/utils/K8sUtils.java       | 19 ++++++
 .../submarine/server/k8s/utils/K8sUtilsTest.java}  | 39 ++++++------
 .../server-submitter/submarine-k8s-agent/pom.xml   |  2 +-
 .../k8s/agent/reconciler/NotebookReconciler.java   | 10 ++-
 .../server/k8s/agent/SubmitSubmarineAgentTest.java | 37 ++++++-----
 .../test/resources/custom-resources/notebook.yml   | 71 +++++++++-------------
 .../resources/custom-resources/pytorchjobs.yaml    | 59 +++++++++---------
 .../test/resources/custom-resources/tfjobs.yaml    | 56 ++++++++---------
 .../resources/custom-resources/xgboostjobs.yaml    | 54 ++++++++--------
 .../src/test/resources/log4j.properties            |  1 +
 .../server-submitter/submitter-k8s/pom.xml         | 59 +++++++++++++++++-
 .../submitter/k8s/model/notebook/NotebookCR.java   |  4 +-
 .../k8s/model/notebook/NotebookCondition.java      |  5 +-
 .../server/submitter/k8s/util/MLJobConverter.java  | 13 ++--
 .../server/submitter/k8s/MLJobConverterTest.java   | 17 +++---
 .../src/test/resources/pytorch_job_req.json        |  2 +-
 submarine-test/test-k8s/pom.xml                    | 23 ++++++-
 24 files changed, 355 insertions(+), 220 deletions(-)

diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml
index 59a34078..a7702420 100644
--- a/.github/workflows/master.yml
+++ b/.github/workflows/master.yml
@@ -539,14 +539,14 @@ jobs:
           java -version
       - name: Build
         env:
-          MODULES: "-pl 
:submarine-server-submitter,:submarine-submitter-k8s,:submarine-k8s-agent"
+          MODULES: "-pl 
:submarine-server-submitter,:submarine-submitter-k8s,:submarine-k8s-agent,:submarine-k8s-utils"
         run: |
           echo ">>> mvn $BUILD_FLAG $MODULES -B"
           mvn $BUILD_FLAG $MODULES -B
       - name: Test
         env:
           # There are some `submitter-k8s` packages under the 
`submarine-server-submitter` that also needs to be tested
-          TEST_MODULES: "-pl 
:submarine-server-submitter,:submarine-submitter-k8s,:submarine-k8s-agent"
+          TEST_MODULES: "-pl 
:submarine-server-submitter,:submarine-submitter-k8s,:submarine-k8s-agent,:submarine-k8s-utils"
         run: |
           echo ">>> mvn $TEST_FLAG $TEST_MODULES -B"
           export SUBMARINE_UID="dfea05c4-dbf2-43cc-833c-62ff329566a5"
diff --git a/LICENSE-binary b/LICENSE-binary
index 83c13a99..25938136 100644
--- a/LICENSE-binary
+++ b/LICENSE-binary
@@ -240,8 +240,12 @@ commons-lang:commons-lang:2.6
 commons-logging:commons-logging:1.1.3
 commons-logging:commons-logging:1.1.1
 commons-net:commons-net:3.1
-io.fabric8:kubernetes-server-mock:6.2.0
-io.javaoperatorsdk:operator-framework:4.1.1
+io.fabric8:kubernetes-client:6.6.1
+io.fabric8:kubernetes-server-mock:6.6.1
+io.javaoperatorsdk:operator-framework:4.3.2
+io.kubernetes:client-java:17.0.2
+io.kubernetes:client-java-api-fluent:17.0.2
+io.minio:minio:8.5.3
 io.netty:netty:3.7.0.Final
 io.netty:netty-all:4.0.23.Final
 javax.inject:javax.inject:1
@@ -338,7 +342,7 @@ com.linkedin.tony:tony-core:0.3.21
 BSD 3-Clause
 ------------
 org.hamcrest:hamcrest-core:1.3
-com.google.protobuf:protobuf-java:2.5.0
+com.google.protobuf:protobuf-java:3.21.10
 com.thoughtworks.paranamer:paranamer:2.3
 org.ow2.asm:asm:5.0.4
 asm:asm:3.3.1
diff --git a/pom.xml b/pom.xml
index 2624524e..2d7f7111 100644
--- a/pom.xml
+++ b/pom.xml
@@ -81,7 +81,7 @@
     <commons-configuration.version>1.10</commons-configuration.version>
     <commons-httpclient.version>3.1</commons-httpclient.version>
 
-    <minio.version>7.1.4</minio.version>
+    <minio.version>8.5.3</minio.version>
 
     <cglib.version>3.3.0</cglib.version>
     <jboss.logging.version>3.4.2.Final</jboss.logging.version>
@@ -133,10 +133,13 @@
     <jgit.version>5.13.0.202109080827-r</jgit.version>
     <atomix.version>3.1.5</atomix.version>
     <json.version>20211205</json.version>
+
     <!--  Submarine on Kubernetes  -->
-    <k8s.client-java.version>11.0.1</k8s.client-java.version>
-    <k8s.fabric8.version>6.2.0</k8s.fabric8.version>
+    <k8s.client-java.version>17.0.2</k8s.client-java.version>
+    <kotlin-stdlib.version>1.6.10</kotlin-stdlib.version>
+    <k8s.fabric8.version>6.6.1</k8s.fabric8.version>
     <jersey.test-framework>2.27</jersey.test-framework>
+
     <!-- integration test-->
     <plugin.failsafe.version>2.17</plugin.failsafe.version>
     <!--  embedded-ldap-junit  -->
@@ -146,7 +149,7 @@
     <guice-servlet.version>3.0</guice-servlet.version>
     <guice.version>3.0</guice.version>
     <!--  server API  -->
-    <protobuf-java.version>3.14.0</protobuf-java.version>
+    <protobuf-java.version>3.21.10</protobuf-java.version>
     <joda-time.version>2.10.8</joda-time.version>
     <!--  pac4j  -->
     <pac4j.version>5.6.1</pac4j.version>
@@ -205,6 +208,11 @@
         <artifactId>client-java</artifactId>
         <version>${k8s.client-java.version}</version>
       </dependency>
+      <dependency>
+        <groupId>io.kubernetes</groupId>
+        <artifactId>client-java-api-fluent</artifactId>
+        <version>${k8s.client-java.version}</version>
+      </dependency>
 
       <dependency>
         <groupId>org.apache.commons</groupId>
diff --git a/submarine-serve/pom.xml b/submarine-serve/pom.xml
index d08ed49a..5ffb3fa4 100644
--- a/submarine-serve/pom.xml
+++ b/submarine-serve/pom.xml
@@ -31,13 +31,26 @@
   <name>Submarine: Serve</name>
 
   <dependencies>
+
     <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
+      <groupId>io.kubernetes</groupId>
+      <artifactId>client-java-api-fluent</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-common</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-jdk8</artifactId>
+        </exclusion>
+      </exclusions>
     </dependency>
+
     <dependency>
-      <groupId>io.kubernetes</groupId>
-      <artifactId>client-java</artifactId>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib-common</artifactId>
+      <version>${kotlin-stdlib.version}</version>
     </dependency>
 
     <!--  Unit Tests  -->
diff --git a/submarine-server/server-core/pom.xml 
b/submarine-server/server-core/pom.xml
index 4ef4a71e..64405664 100644
--- a/submarine-server/server-core/pom.xml
+++ b/submarine-server/server-core/pom.xml
@@ -432,12 +432,21 @@
           <groupId>com.fasterxml.jackson.core</groupId>
           <artifactId>jackson-annotations</artifactId>
         </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-common</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-jdk8</artifactId>
+        </exclusion>
       </exclusions>
     </dependency>
 
     <dependency>
-      <groupId>joda-time</groupId>
-      <artifactId>joda-time</artifactId>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib-common</artifactId>
+      <version>${kotlin-stdlib.version}</version>
     </dependency>
 
     <dependency>
diff --git 
a/submarine-server/server-core/src/main/java/org/apache/submarine/server/manager/ExperimentManager.java
 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/manager/ExperimentManager.java
index d1b95469..d5e407de 100644
--- 
a/submarine-server/server-core/src/main/java/org/apache/submarine/server/manager/ExperimentManager.java
+++ 
b/submarine-server/server-core/src/main/java/org/apache/submarine/server/manager/ExperimentManager.java
@@ -19,6 +19,8 @@
 
 package org.apache.submarine.server.manager;
 
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Optional;
@@ -44,6 +46,7 @@ import org.apache.submarine.server.api.experiment.MlflowInfo;
 import org.apache.submarine.server.api.spec.ExperimentSpec;
 import org.apache.submarine.server.database.experiment.entity.ExperimentEntity;
 import 
org.apache.submarine.server.database.experiment.service.ExperimentService;
+import org.apache.submarine.server.k8s.utils.K8sUtils;
 import org.apache.submarine.server.rest.RestConstants;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
@@ -357,29 +360,37 @@ public class ExperimentManager {
     experiment.setExperimentId(ExperimentId.fromString(entity.getId()));
     experiment.setSpec(new Gson().fromJson(entity.getExperimentSpec(), 
ExperimentSpec.class));
     experiment.setStatus(entity.getExperimentStatus());
-    
+
     if (entity.getCreateTime() != null) {
-      experiment.setCreatedTime(new 
DateTime(entity.getCreateTime()).toString());
+      experiment.setCreatedTime(K8sUtils.castOffsetDatetimeToString(
+          OffsetDateTime.ofInstant(entity.getCreateTime().toInstant(), 
ZoneId.systemDefault()))
+      );
     } else {
       experiment.setCreatedTime(null);
     }
     if (entity.getAcceptedTime() != null) {
-      experiment.setAcceptedTime(new 
DateTime(entity.getAcceptedTime()).toString());
+      experiment.setAcceptedTime(K8sUtils.castOffsetDatetimeToString(
+          OffsetDateTime.ofInstant(entity.getAcceptedTime().toInstant(), 
ZoneId.systemDefault()))
+      );
     } else {
       experiment.setAcceptedTime(null);
     }
     if (entity.getRunningTime() != null) {
-      experiment.setRunningTime(new 
DateTime(entity.getRunningTime()).toString());
+      experiment.setRunningTime(K8sUtils.castOffsetDatetimeToString(
+          OffsetDateTime.ofInstant(entity.getRunningTime().toInstant(), 
ZoneId.systemDefault()))
+      );
     } else {
       experiment.setRunningTime(null);
     }
     if (entity.getFinishedTime() != null) {
-      experiment.setFinishedTime(new 
DateTime(entity.getFinishedTime()).toString());
+      experiment.setFinishedTime(K8sUtils.castOffsetDatetimeToString(
+          OffsetDateTime.ofInstant(entity.getFinishedTime().toInstant(), 
ZoneId.systemDefault()))
+      );
     } else {
       experiment.setFinishedTime(null);
     }
     experiment.setUid(entity.getUid());
-    
+
     return experiment;
   }
 
@@ -396,7 +407,7 @@ public class ExperimentManager {
     if (experiment.getCreatedTime() != null) {
       
entity.setCreateTime(DateTime.parse(experiment.getCreatedTime()).toDate());
     } else {
-      entity.setCreateTime(null);  
+      entity.setCreateTime(null);
     }
     if (experiment.getAcceptedTime() != null) {
       
entity.setAcceptedTime(DateTime.parse(experiment.getAcceptedTime()).toDate());
@@ -406,7 +417,7 @@ public class ExperimentManager {
     if (experiment.getRunningTime() != null) {
       
entity.setRunningTime(DateTime.parse(experiment.getRunningTime()).toDate());
     } else {
-      entity.setRunningTime(null);      
+      entity.setRunningTime(null);
     }
     if (experiment.getFinishedTime() != null) {
       
entity.setFinishedTime(DateTime.parse(experiment.getFinishedTime()).toDate());
diff --git 
a/submarine-server/server-database/src/main/java/org/apache/submarine/server/database/notebook/service/NotebookService.java
 
b/submarine-server/server-database/src/main/java/org/apache/submarine/server/database/notebook/service/NotebookService.java
index c303fdcf..9de8dc7f 100644
--- 
a/submarine-server/server-database/src/main/java/org/apache/submarine/server/database/notebook/service/NotebookService.java
+++ 
b/submarine-server/server-database/src/main/java/org/apache/submarine/server/database/notebook/service/NotebookService.java
@@ -22,6 +22,8 @@ package org.apache.submarine.server.database.notebook.service;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
 import java.util.ArrayList;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.submarine.commons.utils.exception.SubmarineRuntimeException;
@@ -31,6 +33,7 @@ import org.apache.submarine.server.api.spec.NotebookSpec;
 import org.apache.submarine.server.database.utils.MyBatisUtil;
 import org.apache.submarine.server.database.notebook.entity.NotebookEntity;
 import org.apache.submarine.server.database.notebook.mappers.NotebookMapper;
+import org.apache.submarine.server.k8s.utils.K8sUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -161,13 +164,17 @@ public class NotebookService {
       notebook.setSpec(new Gson().fromJson(entity.getNotebookSpec(), 
NotebookSpec.class));
       notebook.setName(notebook.getSpec().getMeta().getName());
       notebook.setStatus(entity.getNotebookStatus());
-      notebook.setCreatedTime(new DateTime(entity.getCreateTime()).toString());
+      notebook.setCreatedTime(K8sUtils.castOffsetDatetimeToString(
+          OffsetDateTime.ofInstant(entity.getCreateTime().toInstant(), 
ZoneId.systemDefault()))
+      );
       notebook.setUrl(entity.getNotebookUrl());
       notebook.setReason(entity.getReason());
       if (entity.getDeletedTime() != null) {
-        notebook.setDeletedTime(new 
DateTime(entity.getDeletedTime()).toString());
+        notebook.setDeletedTime(K8sUtils.castOffsetDatetimeToString(
+            OffsetDateTime.ofInstant(entity.getDeletedTime().toInstant(), 
ZoneId.systemDefault()))
+        );
       }
-      
+
     } catch (Exception e) {
       LOG.error(e.getMessage(), e);
       throw new SubmarineRuntimeException("Unable to build notebook from 
entity");
diff --git 
a/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
 
b/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
index 54a3421e..800d72ca 100644
--- 
a/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
+++ 
b/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
@@ -22,6 +22,10 @@ package org.apache.submarine.server.k8s.utils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.time.OffsetDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+
 /**
  * Utility methods for common k8s operations.
  *
@@ -47,4 +51,19 @@ public abstract class K8sUtils {
     }
     return namespace;
   }
+
+  public static final DateTimeFormatter UTC_DATE_FORMATTER =
+      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssX");
+
+  /**
+   * In k8s resource time declarations, the usual return is something like 
this:
+   * <p>
+   * creationTimestamp: '2023-05-23T09:01:12Z'
+   * <p>
+   * So we try to do the same for our return datetime format
+   */
+  public static String castOffsetDatetimeToString(OffsetDateTime odt) {
+    if (odt == null) return null;
+    return 
UTC_DATE_FORMATTER.format(odt.withOffsetSameInstant(ZoneOffset.UTC));
+  }
 }
diff --git 
a/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
 
b/submarine-server/server-submitter/k8s-utils/src/test/java/org/apache/submarine/server/k8s/utils/K8sUtilsTest.java
similarity index 56%
copy from 
submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
copy to 
submarine-server/server-submitter/k8s-utils/src/test/java/org/apache/submarine/server/k8s/utils/K8sUtilsTest.java
index 54a3421e..66d6a7f5 100644
--- 
a/submarine-server/server-submitter/k8s-utils/src/main/java/org/apache/submarine/server/k8s/utils/K8sUtils.java
+++ 
b/submarine-server/server-submitter/k8s-utils/src/test/java/org/apache/submarine/server/k8s/utils/K8sUtilsTest.java
@@ -19,32 +19,27 @@
 
 package org.apache.submarine.server.k8s.utils;
 
+import org.junit.Assert;
+import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-/**
- * Utility methods for common k8s operations.
- *
- * @author Chi-Sheng Liu
- * @since 0.8.0-SNAPSHOT
- */
-public abstract class K8sUtils {
+import java.time.OffsetDateTime;
+import java.time.format.DateTimeFormatter;
 
-  private static final Logger LOG = LoggerFactory.getLogger(K8sUtils.class);
-  private static String namespace = null;
+public class K8sUtilsTest {
 
-  /**
-   * Get the current Kubernetes namespace.
-   * @return The current Kubernetes namespace.
-   */
-  public static String getNamespace() {
-    if (namespace == null) {
-      namespace = System.getenv("ENV_NAMESPACE");
-      if (namespace == null) {
-        namespace = "default";
-      }
-      LOG.info("Namespace: {}", namespace);
-    }
-    return namespace;
+  private static final Logger LOG = 
LoggerFactory.getLogger(K8sUtilsTest.class);
+
+  @Test
+  public void testCastOffsetDatetime() {
+    OffsetDateTime now = OffsetDateTime.now();
+    LOG.info("current time: {} will cast to string: {}", now, 
K8sUtils.castOffsetDatetimeToString(now));
+    OffsetDateTime testDate1 = OffsetDateTime.parse("2023-05-23T09:01:12Z");
+    Assert.assertEquals("2023-05-23T09:01:12Z", 
K8sUtils.castOffsetDatetimeToString(testDate1));
+    OffsetDateTime testDate2 = 
OffsetDateTime.parse("2023-05-23T17:01:12.000+08:00",
+      DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    Assert.assertEquals("2023-05-23T09:01:12Z", 
K8sUtils.castOffsetDatetimeToString(testDate2));
   }
+
 }
diff --git a/submarine-server/server-submitter/submarine-k8s-agent/pom.xml 
b/submarine-server/server-submitter/submarine-k8s-agent/pom.xml
index 0f0035b1..12c69915 100644
--- a/submarine-server/server-submitter/submarine-k8s-agent/pom.xml
+++ b/submarine-server/server-submitter/submarine-k8s-agent/pom.xml
@@ -37,7 +37,7 @@
     <dependency>
       <groupId>io.javaoperatorsdk</groupId>
       <artifactId>operator-framework</artifactId>
-      <version>4.1.1</version>
+      <version>4.3.2</version>
       <exclusions>
         <exclusion>
           <groupId>com.fasterxml.jackson.core</groupId>
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/main/java/org/apache/submarine/server/k8s/agent/reconciler/NotebookReconciler.java
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/main/java/org/apache/submarine/server/k8s/agent/reconciler/NotebookReconciler.java
index 60ccb66b..7ec61a07 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/main/java/org/apache/submarine/server/k8s/agent/reconciler/NotebookReconciler.java
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/main/java/org/apache/submarine/server/k8s/agent/reconciler/NotebookReconciler.java
@@ -69,10 +69,14 @@ public class NotebookReconciler implements 
Reconciler<NotebookResource> {
                                                    Context<NotebookResource> 
context) {
     LOGGER.debug("Reconciling Notebook: {}", notebook);
     if 
(!notebook.hasOwnerReferenceFor(OwnerReferenceConfig.getSubmarineUid())) {
-      LOGGER.trace("OwnerReference is {}, Skip the processing of this 
notebook",
+      if (LOGGER.isTraceEnabled()) {
+        LOGGER.trace("OwnerReference is {}, Skip the processing of this 
notebook",
           notebook.getMetadata().getOwnerReferences() == null ? "" :
-              notebook.getMetadata().getOwnerReferences().stream()
-                  .map(OwnerReference::getUid).findFirst().orElse(null));
+            notebook.getMetadata().getOwnerReferences().stream()
+              .map(OwnerReference::getUid)
+              .filter(Objects::nonNull)
+              .findFirst().orElse("''"));
+      }
     } else {
       triggerStatus(notebook);
     }
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/java/org/apache/submarine/server/k8s/agent/SubmitSubmarineAgentTest.java
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/java/org/apache/submarine/server/k8s/agent/SubmitSubmarineAgentTest.java
index 440b8fa5..fe20aed1 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/java/org/apache/submarine/server/k8s/agent/SubmitSubmarineAgentTest.java
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/java/org/apache/submarine/server/k8s/agent/SubmitSubmarineAgentTest.java
@@ -24,6 +24,7 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
 import io.fabric8.kubernetes.api.model.OwnerReferenceBuilder;
 import 
io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition;
 import io.fabric8.kubernetes.client.KubernetesClient;
+import io.fabric8.kubernetes.client.dsl.base.CustomResourceDefinitionContext;
 import io.fabric8.kubernetes.client.server.mock.KubernetesServer;
 import io.fabric8.kubernetes.internal.KubernetesDeserializer;
 import io.javaoperatorsdk.operator.Operator;
@@ -105,14 +106,14 @@ public class SubmitSubmarineAgentTest {
     operator = new Operator(client);
 
     // create notbook resource
-    KubernetesDeserializer.registerCustomKind("apiextensions.k8s.io/v1beta1", 
"Notebook", NotebookResource.class);
+    
KubernetesDeserializer.registerCustomKind("apiextensions.k8s.io/v1","Notebook", 
NotebookResource.class);
     CustomResourceDefinition notebookCrd = client
             .apiextensions().v1()
             .customResourceDefinitions()
             
.load(SubmitSubmarineAgentTest.class.getResourceAsStream("/custom-resources/notebook.yml"))
-            .get();
+            .item();
     LOGGER.info("Create Notebook CRD ...");
-    
client.apiextensions().v1().customResourceDefinitions().create(notebookCrd);
+    
client.apiextensions().v1().customResourceDefinitions().createOrReplace(notebookCrd);
 
     // create tf resource
     KubernetesDeserializer.registerCustomKind("apiextensions.k8s.io/v1", 
"TFJob", TFJob.class);
@@ -120,7 +121,7 @@ public class SubmitSubmarineAgentTest {
             .apiextensions().v1()
             .customResourceDefinitions()
             
.load(SubmitSubmarineAgentTest.class.getResourceAsStream("/custom-resources/tfjobs.yaml"))
-            .get();
+            .item();
     LOGGER.info("Create TF CRD ...");
     client.apiextensions().v1().customResourceDefinitions().create(tfCrd);
 
@@ -130,7 +131,7 @@ public class SubmitSubmarineAgentTest {
             .apiextensions().v1()
             .customResourceDefinitions()
             
.load(SubmitSubmarineAgentTest.class.getResourceAsStream("/custom-resources/pytorchjobs.yaml"))
-            .get();
+            .item();
     LOGGER.info("Create PyTorch CRD ...");
     client.apiextensions().v1().customResourceDefinitions().create(ptCrd);
 
@@ -140,7 +141,7 @@ public class SubmitSubmarineAgentTest {
             .apiextensions().v1()
             .customResourceDefinitions()
             
.load(SubmitSubmarineAgentTest.class.getResourceAsStream("/custom-resources/xgboostjobs.yaml"))
-            .get();
+            .item();
     LOGGER.info("Create XGBoost CRD ...");
     client.apiextensions().v1().customResourceDefinitions().create(xgbCrd);
 
@@ -181,10 +182,8 @@ public class SubmitSubmarineAgentTest {
     TFJob resource = new TFJob();
     resource.setMetadata(meta);
     resource.setStatus(status);
-    client.resources(TFJob.class)
-            .inNamespace(client.getNamespace())
-            .withName("experiment-1659167632755-0001")
-            .createOrReplace(resource);
+    client.resource(resource).create();
+    client.resource(resource).updateStatus();
 
     // left 5s to process
     Thread.sleep(TimeUnit.SECONDS.toMillis(5));
@@ -225,10 +224,8 @@ public class SubmitSubmarineAgentTest {
     PyTorchJob resource = new PyTorchJob();
     resource.setMetadata(meta);
     resource.setStatus(status);
-    client.resources(PyTorchJob.class)
-            .inNamespace(client.getNamespace())
-            .withName("experiment-1659167632755-0002")
-            .createOrReplace(resource);
+    client.resource(resource).create();
+    client.resource(resource).updateStatus();
 
     // left 5s to process
     Thread.sleep(TimeUnit.SECONDS.toMillis(5));
@@ -269,10 +266,8 @@ public class SubmitSubmarineAgentTest {
     XGBoostJob resource = new XGBoostJob();
     resource.setMetadata(meta);
     resource.setStatus(status);
-    client.resources(XGBoostJob.class)
-            .inNamespace(client.getNamespace())
-            .withName("experiment-1659167632755-0003")
-            .createOrReplace(resource);
+    client.resource(resource).create();
+    client.resource(resource).updateStatus();
 
     // left 5s to process
     Thread.sleep(TimeUnit.SECONDS.toMillis(5));
@@ -315,7 +310,8 @@ public class SubmitSubmarineAgentTest {
     NotebookResource resource = new NotebookResource();
     resource.setMetadata(meta);
     resource.setStatus(status);
-    client.resource(resource).createOrReplace();
+    client.resource(resource).create();
+    client.resource(resource).updateStatus();
 
     // left 5s to process
     Thread.sleep(TimeUnit.SECONDS.toMillis(5));
@@ -369,7 +365,8 @@ public class SubmitSubmarineAgentTest {
     NotebookResource resource = new NotebookResource();
     resource.setMetadata(meta);
     resource.setStatus(status);
-    client.resource(resource).createOrReplace();
+    client.resource(resource).create();
+    client.resource(resource).updateStatus();
 
     // left 5s to process
     Thread.sleep(TimeUnit.SECONDS.toMillis(5));
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/notebook.yml
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/notebook.yml
index 5528f46b..64d562ad 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/notebook.yml
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/notebook.yml
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-apiVersion: apiextensions.k8s.io/v1beta1
+apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   name: notebooks.kubeflow.org
@@ -23,49 +23,34 @@ spec:
   group: kubeflow.org
   names:
     kind: Notebook
+    listKind: NotebookList
     plural: notebooks
     singular: notebook
   scope: Namespaced
-  subresources:
-    status: {}
   versions:
-    - name: v1alpha1
-      served: true
-      storage: false
-    - name: v1beta1
-      served: true
-      storage: true
-    - name: v1
-      served: true
-      storage: false
-  validation:
-    openAPIV3Schema:
-      properties:
-        apiVersion:
-          type: string
-        kind:
-          type: string
-        metadata:
-          type: object
-        spec:
-          properties:
-            template:
-              properties:
-                spec:
-                  type: object
-              type: object
-          type: object
-        status:
-          properties:
-            conditions:
-              items:
-                properties:
-                  type:
-                    type: string
-                required:
-                  - type
-                type: object
-              type: array
-          required:
-            - conditions
-          type: object
+  - name: v1
+    schema:
+      openAPIV3Schema:
+        properties:
+          apiVersion:
+            type: string
+          kind:
+            type: string
+          metadata:
+            type: object
+          spec:
+            type: object
+          status:
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+status:
+  acceptedNames:
+    kind: ""
+    plural: ""
+  conditions: []
+  storedVersions: []
+
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/pytorchjobs.yaml
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/pytorchjobs.yaml
index 0b99c44d..1b9951eb 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/pytorchjobs.yaml
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/pytorchjobs.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-apiVersion: apiextensions.k8s.io/v1beta1
+apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   name: pytorchjobs.kubeflow.org
@@ -27,35 +27,38 @@ spec:
     plural: pytorchjobs
     singular: pytorchjob
   scope: Namespaced
-  subresources:
-    status: {}
   versions:
     - name: v1
       served: true
       storage: false
-  validation:
-    openAPIV3Schema:
-      properties:
-        apiVersion:
-          type: string
-        kind:
-          type: string
-        metadata:
-          type: object
-        spec:
-          type: object
-        status:
+      schema:
+        openAPIV3Schema:
           properties:
-            conditions:
-              items:
-                properties:
-                  type:
-                    type: string
-                required:
-                  - type
-                type: object
-              type: array
-          required:
-            - conditions
-          type: object
-
+            apiVersion:
+              type: string
+            kind:
+              type: string
+            metadata:
+              type: object
+            spec:
+              type: object
+            status:
+              properties:
+                conditions:
+                  items:
+                    properties:
+                      type:
+                        type: string
+                    required:
+                      - type
+                    type: object
+                  type: array
+              required:
+                - conditions
+              type: object
+      subresources:
+        scale:
+          labelSelectorPath: .status.replicaStatuses.Worker.selector
+          specReplicasPath: .spec.pytorchReplicaSpecs.Worker.replicas
+          statusReplicasPath: .status.replicaStatuses.Worker.active
+        status: {}
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/tfjobs.yaml
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/tfjobs.yaml
index 50f2c215..ca68de83 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/tfjobs.yaml
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/tfjobs.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-apiVersion: apiextensions.k8s.io/v1beta1
+apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   name: tfjobs.kubeflow.org
@@ -26,34 +26,34 @@ spec:
     plural: tfjobs
     singular: tfjob
   scope: Namespaced
-  subresources:
-    status: {}
   versions:
     - name: v1
       served: true
-      storage: false
-  validation:
-    openAPIV3Schema:
-      properties:
-        apiVersion:
-          type: string
-        kind:
-          type: string
-        metadata:
-          type: object
-        spec:
-          type: object
-        status:
+      storage: true
+      schema:
+        openAPIV3Schema:
           properties:
-            conditions:
-              items:
-                properties:
-                  type:
-                    type: string
-                required:
-                  - type
-                type: object
-              type: array
-          required:
-            - conditions
-          type: object
+            apiVersion:
+              type: string
+            kind:
+              type: string
+            metadata:
+              type: object
+            spec:
+              type: object
+            status:
+              properties:
+                conditions:
+                  items:
+                    properties:
+                      type:
+                        type: string
+                    required:
+                      - type
+                    type: object
+                  type: array
+              required:
+                - conditions
+              type: object
+      subresources:
+        status: {}
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/xgboostjobs.yaml
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/xgboostjobs.yaml
index 589f050e..b1e36d2b 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/xgboostjobs.yaml
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/custom-resources/xgboostjobs.yaml
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-apiVersion: apiextensions.k8s.io/v1beta1
+apiVersion: apiextensions.k8s.io/v1
 kind: CustomResourceDefinition
 metadata:
   name: xgboostjobs.kubeflow.org
@@ -27,34 +27,34 @@ spec:
     plural: xgboostjobs
     singular: xgboostjob
   scope: Namespaced
-  subresources:
-    status: {}
   versions:
     - name: v1
       served: true
       storage: false
-  validation:
-    openAPIV3Schema:
-      properties:
-        apiVersion:
-          type: string
-        kind:
-          type: string
-        metadata:
-          type: object
-        spec:
-          type: object
-        status:
+      schema:
+        openAPIV3Schema:
           properties:
-            conditions:
-              items:
-                properties:
-                  type:
-                    type: string
-                required:
-                  - type
-                type: object
-              type: array
-          required:
-            - conditions
-          type: object
+            apiVersion:
+              type: string
+            kind:
+              type: string
+            metadata:
+              type: object
+            spec:
+              type: object
+            status:
+              properties:
+                conditions:
+                  items:
+                    properties:
+                      type:
+                        type: string
+                    required:
+                      - type
+                    type: object
+                  type: array
+              required:
+                - conditions
+              type: object
+      subresources:
+        status: {}
diff --git 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/log4j.properties
 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/log4j.properties
index 0162fd5c..d5a53cdb 100644
--- 
a/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/log4j.properties
+++ 
b/submarine-server/server-submitter/submarine-k8s-agent/src/test/resources/log4j.properties
@@ -21,4 +21,5 @@ log4j.appender.stdout.encoding=UTF-8
 log4j.logger.org.apache.submarine.server.database=DEBUG
 # operator debug
 log4j.logger.io.javaoperatorsdk.operator=DEBUG
+log4j.logger.org.apache.submarine=TRACE
 log4j.logger.io.fabric8.kubernetes=DEBUG
diff --git a/submarine-server/server-submitter/submitter-k8s/pom.xml 
b/submarine-server/server-submitter/submitter-k8s/pom.xml
index 77218fe7..e47fc8a2 100644
--- a/submarine-server/server-submitter/submitter-k8s/pom.xml
+++ b/submarine-server/server-submitter/submitter-k8s/pom.xml
@@ -47,7 +47,58 @@
     <dependency>
       <groupId>io.kubernetes</groupId>
       <artifactId>client-java</artifactId>
-      <version>${k8s.client-java.version}</version>
+      <exclusions>
+        <exclusion>
+          <groupId>io.kubernetes</groupId>
+          <artifactId>client-java</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-common</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-jdk8</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.code.gson</groupId>
+          <artifactId>gson</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>joda-time</groupId>
+      <artifactId>joda-time</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>io.kubernetes</groupId>
+      <artifactId>client-java-api-fluent</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>io.kubernetes</groupId>
+          <artifactId>client-java</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-common</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib-jdk8</artifactId>
+        </exclusion>
+        <exclusion>
+          <groupId>com.google.code.gson</groupId>
+          <artifactId>gson</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib-common</artifactId>
+      <version>${kotlin-stdlib.version}</version>
     </dependency>
 
     <dependency>
@@ -62,6 +113,12 @@
       <version>${project.version}</version>
     </dependency>
 
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>${gson.version}</version>
+    </dependency>
+
     <dependency>
       <groupId>org.apache.submarine</groupId>
       <artifactId>submarine-server-core</artifactId>
diff --git 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCR.java
 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCR.java
index fe08419f..fcfbbde7 100644
--- 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCR.java
+++ 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCR.java
@@ -35,10 +35,10 @@ import 
org.apache.submarine.server.submitter.k8s.parser.NotebookSpecParser;
 import org.apache.submarine.server.submitter.k8s.util.NotebookUtils;
 import org.apache.submarine.server.submitter.k8s.util.OwnerReferenceUtils;
 import org.apache.submarine.server.utils.YamlUtils;
-import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.time.OffsetDateTime;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -267,7 +267,7 @@ public class NotebookCR implements KubernetesObject, 
K8sResource<Notebook> {
     } finally {
       if (notebook == null) {
         // add metadata time info
-        this.getMetadata().setDeletionTimestamp(new DateTime());
+        this.getMetadata().setDeletionTimestamp(OffsetDateTime.now());
         // build notebook response
         notebook = NotebookUtils.buildNotebookResponse(this);
         notebook.setStatus(Notebook.Status.STATUS_NOT_FOUND.getValue());
diff --git 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCondition.java
 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCondition.java
index 26dbfd66..0005a3ca 100644
--- 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCondition.java
+++ 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/model/notebook/NotebookCondition.java
@@ -19,7 +19,8 @@
 package org.apache.submarine.server.submitter.k8s.model.notebook;
 
 import com.google.gson.annotations.SerializedName;
-import org.joda.time.DateTime;
+
+import java.time.OffsetDateTime;
 
 public class NotebookCondition {
 
@@ -31,7 +32,7 @@ public class NotebookCondition {
   private String type;
 
   @SerializedName("lastProbeTime")
-  private DateTime lastProbeTime;
+  private OffsetDateTime lastProbeTime;
 
   @SerializedName("reason")
   private String reason;
diff --git 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/MLJobConverter.java
 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/MLJobConverter.java
index 9c2f1952..af56da47 100644
--- 
a/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/MLJobConverter.java
+++ 
b/submarine-server/server-submitter/submitter-k8s/src/main/java/org/apache/submarine/server/submitter/k8s/util/MLJobConverter.java
@@ -19,6 +19,7 @@
 
 package org.apache.submarine.server.submitter.k8s.util;
 
+import java.time.OffsetDateTime;
 import java.util.List;
 import io.kubernetes.client.openapi.models.V1JobCondition;
 import io.kubernetes.client.openapi.models.V1JobStatus;
@@ -26,8 +27,8 @@ import io.kubernetes.client.openapi.models.V1Status;
 import io.kubernetes.client.openapi.models.V1StatusDetails;
 import io.kubernetes.client.util.generic.options.DeleteOptions;
 import org.apache.submarine.server.api.experiment.Experiment;
+import org.apache.submarine.server.k8s.utils.K8sUtils;
 import org.apache.submarine.server.submitter.k8s.model.mljob.MLJob;
-import org.joda.time.DateTime;
 
 /**
  * Converter for different types.
@@ -37,9 +38,9 @@ public class MLJobConverter {
   public static Experiment toJobFromMLJob(MLJob mlJob) {
     Experiment experiment = new Experiment();
     experiment.setUid(mlJob.getMetadata().getUid());
-    DateTime dateTime = mlJob.getMetadata().getCreationTimestamp();
+    OffsetDateTime dateTime = mlJob.getMetadata().getCreationTimestamp();
     if (dateTime != null) {
-      experiment.setAcceptedTime(dateTime.toString());
+      
experiment.setAcceptedTime(K8sUtils.castOffsetDatetimeToString(dateTime));
       experiment.setStatus(Experiment.Status.STATUS_ACCEPTED.getValue());
     }
 
@@ -47,7 +48,7 @@ public class MLJobConverter {
     if (status != null) {
       dateTime = status.getStartTime();
       if (dateTime != null) {
-        experiment.setCreatedTime(dateTime.toString());
+        
experiment.setCreatedTime(K8sUtils.castOffsetDatetimeToString(dateTime));
         experiment.setStatus(Experiment.Status.STATUS_CREATED.getValue());
       }
 
@@ -57,7 +58,7 @@ public class MLJobConverter {
         for (V1JobCondition condition : conditions) {
           if (condition.getType().toLowerCase().equals("running")) {
             dateTime = condition.getLastTransitionTime();
-            experiment.setRunningTime(dateTime.toString());
+            
experiment.setRunningTime(K8sUtils.castOffsetDatetimeToString(dateTime));
             break;
           }
         }
@@ -65,7 +66,7 @@ public class MLJobConverter {
 
       dateTime = status.getCompletionTime();
       if (conditions != null && dateTime != null) {
-        experiment.setFinishedTime(dateTime.toString());
+        
experiment.setFinishedTime(K8sUtils.castOffsetDatetimeToString(dateTime));
         if ("Succeeded".equalsIgnoreCase(conditions.get(conditions.size() - 
1).getType())) {
           experiment.setStatus(Experiment.Status.STATUS_SUCCEEDED.getValue());
         } else if ("Failed".equalsIgnoreCase(conditions.get(conditions.size() 
- 1).getType())) {
diff --git 
a/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/MLJobConverterTest.java
 
b/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/MLJobConverterTest.java
index 63c050cd..1065ce3d 100644
--- 
a/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/MLJobConverterTest.java
+++ 
b/submarine-server/server-submitter/submitter-k8s/src/test/java/org/apache/submarine/server/submitter/k8s/MLJobConverterTest.java
@@ -21,6 +21,7 @@ package org.apache.submarine.server.submitter.k8s;
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.time.OffsetDateTime;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -34,10 +35,10 @@ import io.kubernetes.client.openapi.models.V1StatusBuilder;
 import org.apache.submarine.server.api.exception.InvalidSpecException;
 import org.apache.submarine.server.api.experiment.Experiment;
 import org.apache.submarine.server.api.spec.ExperimentSpec;
+import org.apache.submarine.server.k8s.utils.K8sUtils;
 import org.apache.submarine.server.submitter.k8s.model.mljob.MLJobFactory;
 import org.apache.submarine.server.submitter.k8s.util.MLJobConverter;
 import org.apache.submarine.server.submitter.k8s.model.mljob.MLJob;
-import org.joda.time.DateTime;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -54,11 +55,11 @@ public class MLJobConverterTest extends SpecBuilder {
     Assert.assertNull(experiment.getStatus());
 
     // Created Status
-    DateTime startTime = new DateTime();
+    OffsetDateTime startTime = OffsetDateTime.now();
     mlJob.getStatus().setStartTime(startTime);
 
     List<V1JobCondition> conditions = new ArrayList<>();
-    DateTime createdTime = new DateTime();
+    OffsetDateTime createdTime = OffsetDateTime.now();
     V1JobCondition condition = new V1JobConditionBuilder().withStatus("True")
         .withType("Created").withLastTransitionTime(createdTime).build();
     conditions.add(condition);
@@ -66,10 +67,10 @@ public class MLJobConverterTest extends SpecBuilder {
 
     experiment = MLJobConverter.toJobFromMLJob(mlJob);
     Assert.assertEquals(Experiment.Status.STATUS_CREATED.getValue(), 
experiment.getStatus());
-    Assert.assertEquals(startTime.toString(), experiment.getCreatedTime());
+    Assert.assertEquals(K8sUtils.castOffsetDatetimeToString(startTime), 
experiment.getCreatedTime());
 
     // Running Status
-    DateTime runningTime = new DateTime();
+    OffsetDateTime runningTime = OffsetDateTime.now();
     condition = new V1JobConditionBuilder().withStatus("True")
         .withType("Running").withLastTransitionTime(runningTime).build();
     conditions.add(condition);
@@ -77,10 +78,10 @@ public class MLJobConverterTest extends SpecBuilder {
 
     experiment = MLJobConverter.toJobFromMLJob(mlJob);
     Assert.assertEquals(Experiment.Status.STATUS_RUNNING.toString(), 
experiment.getStatus());
-    Assert.assertEquals(runningTime.toString(), experiment.getRunningTime());
+    Assert.assertEquals(K8sUtils.castOffsetDatetimeToString(runningTime), 
experiment.getRunningTime());
 
     // Succeeded Status
-    DateTime finishedTime = new DateTime();
+    OffsetDateTime finishedTime = OffsetDateTime.now();
     mlJob.getStatus().setCompletionTime(finishedTime);
     condition = new V1JobConditionBuilder().withStatus("True")
             .withType("Succeeded").withLastTransitionTime(runningTime).build();
@@ -89,7 +90,7 @@ public class MLJobConverterTest extends SpecBuilder {
 
     experiment = MLJobConverter.toJobFromMLJob(mlJob);
     Assert.assertEquals(Experiment.Status.STATUS_SUCCEEDED.toString(), 
experiment.getStatus());
-    Assert.assertEquals(finishedTime.toString(), experiment.getFinishedTime());
+    Assert.assertEquals(K8sUtils.castOffsetDatetimeToString(finishedTime), 
experiment.getFinishedTime());
   }
 
   @Test
diff --git 
a/submarine-server/server-submitter/submitter-k8s/src/test/resources/pytorch_job_req.json
 
b/submarine-server/server-submitter/submitter-k8s/src/test/resources/pytorch_job_req.json
index 69b1101d..bf75389e 100644
--- 
a/submarine-server/server-submitter/submitter-k8s/src/test/resources/pytorch_job_req.json
+++ 
b/submarine-server/server-submitter/submitter-k8s/src/test/resources/pytorch_job_req.json
@@ -23,7 +23,7 @@
       "resources": "cpu=1,memory=1024M"
     }
   },
-   experimentHandlerSpec": {
+   "experimentHandlerSpec": {
     "FILE_SYSTEM_TYPE": "HDFS",
     "HDFS_HOST": "127.0.0.1",
     "HDFS_PORT": "9000",
diff --git a/submarine-test/test-k8s/pom.xml b/submarine-test/test-k8s/pom.xml
index f8f2abe7..13a54e94 100644
--- a/submarine-test/test-k8s/pom.xml
+++ b/submarine-test/test-k8s/pom.xml
@@ -42,8 +42,8 @@
       <version>${project.version}</version>
       <exclusions>
         <exclusion>
-          <groupId>joda-time</groupId>
-          <artifactId>joda-time</artifactId>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib</artifactId>
         </exclusion>
       </exclusions>
     </dependency>
@@ -55,6 +55,19 @@
       <type>test-jar</type>
       <classifier>tests</classifier>
       <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.jetbrains.kotlin</groupId>
+          <artifactId>kotlin-stdlib</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.jetbrains.kotlin</groupId>
+      <artifactId>kotlin-stdlib</artifactId>
+      <version>${kotlin-stdlib.version}</version>
+      <scope>test</scope>
     </dependency>
 
     <dependency>
@@ -109,6 +122,12 @@
       <version>${k8s.client-java.version}</version>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>io.kubernetes</groupId>
+      <artifactId>client-java-api-fluent</artifactId>
+      <version>${k8s.client-java.version}</version>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to