You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ki...@apache.org on 2020/07/23 09:21:14 UTC

[shardingsphere-elasticjob-ui] 45/47: Add app config page

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

kimmking pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob-ui.git

commit b235f59c2d890a2087f815522c0dae9ed49ddec4
Author: menghaoranss <lo...@163.com>
AuthorDate: Thu Jul 23 17:11:21 2020 +0800

    Add app config page
---
 .../pom.xml                                        |   2 +-
 .../JobRegisterStatisticsRepository.java           |  43 ---
 .../statistics/JobRunningStatisticsRepository.java |  43 ---
 .../cloud/ui/dao/statistics/StatisticInterval.java |  37 --
 .../statistics/TaskResultStatisticsRepository.java |  55 ---
 .../TaskRunningStatisticsRepository.java           |  43 ---
 .../type/job/JobExecutionTypeStatistics.java       |  33 --
 .../dao/statistics/type/job/JobTypeStatistics.java |  35 --
 .../cloud/ui/domain/DataSourceFactory.java         |  41 ---
 .../cloud/ui/domain/EventTraceDataSource.java      |  52 ---
 .../domain/EventTraceDataSourceConfiguration.java  |  66 ----
 .../domain/EventTraceDataSourceConfigurations.java |  37 --
 .../ui/domain/EventTraceDataSourceFactory.java     |  66 ----
 .../cloud/ui/domain/GlobalConfiguration.java       |   2 -
 .../cloud/ui/domain/JobExecutionLog.java           |  86 -----
 .../cloud/ui/domain/JobRegisterStatistics.java     |  59 ----
 .../cloud/ui/domain/JobRunningStatistics.java      |  59 ----
 .../cloud/ui/domain/JobStatusTraceLog.java         |  86 -----
 .../cloud/ui/domain/TaskResultStatistics.java      |  72 ----
 .../cloud/ui/domain/TaskRunningStatistics.java     |  59 ----
 .../cloud/ui/dto/request/BasePageRequest.java      |  60 ----
 .../dto/request/FindJobExecutionEventsRequest.java |  76 ----
 .../request/FindJobStatusTraceEventsRequest.java   |  63 ----
 .../cloud/ui/dto/response/BasePageResponse.java    |  65 ----
 .../cloud/ui/service/CloudServiceFactory.java      |  65 ++++
 .../EventTraceDataSourceConfigurationService.java  |  75 ----
 .../cloud/ui/service/EventTraceHistoryService.java |  46 ---
 .../elasticjob/cloud/ui/service/JobAPIService.java |  70 ----
 .../cloud/ui/service/RegistryCenterFactory.java    |  94 +++++
 ...entTraceDataSourceConfigurationServiceImpl.java | 124 -------
 .../service/impl/EventTraceHistoryServiceImpl.java | 132 -------
 .../cloud/ui/service/impl/JobAPIServiceImpl.java   |  73 ----
 .../elasticjob/cloud/ui/util/BeanUtils.java        |  56 ---
 .../SessionEventTraceDataSourceConfiguration.java  |  42 ---
 .../ui/web/controller/CloudAppController.java      | 173 +++++++++
 .../ui/web/controller/CloudJobController.java      | 393 +++++++++++++++++++++
 .../web/controller/CloudOperationController.java   |  98 +++++
 .../controller/EventTraceDataSourceController.java | 139 --------
 .../controller/EventTraceHistoryController.java    |  69 ----
 .../ui/web/controller/JobConfigController.java     |  80 -----
 .../ui/web/controller/JobOperationController.java  | 148 --------
 .../web/controller/RegistryCenterController.java   |   4 +-
 .../web/controller/ServerOperationController.java  | 173 ---------
 .../web/controller/search/JobEventRdbSearch.java   | 297 ++++++++++++++++
 .../conf/elasticjob-cloud-scheduler.properties     |  19 +
 .../cloud/ui/dao/search/RDBJobEventSearchTest.java | 217 ------------
 .../search/RDBJobEventSearchTestConfiguration.java |  70 ----
 .../statistics/rdb/RDBStatisticRepositoryTest.java | 175 ---------
 .../package.json                                   |   1 +
 .../src/lang/en-US.js                              | 163 +--------
 .../src/lang/zh-CN.js                              | 168 ++-------
 .../src/router/index.js                            |  14 +-
 .../src/views/app-config/api.js}                   |  13 +-
 .../src/views/app-config/index.vue                 |  33 ++
 .../src/views/app-config/module/appConfig.vue      | 283 +++++++++++++++
 .../src/views/registry-center/api.js}              |  13 +-
 .../src/views/registry-center/index.vue            |  33 ++
 .../registry-center/module/registryCenter.vue      | 285 +++++++++++++++
 58 files changed, 1844 insertions(+), 3234 deletions(-)

diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/pom.xml b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/pom.xml
index 990c69c..877f36e 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/pom.xml
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/pom.xml
@@ -34,7 +34,7 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.shardingsphere.elasticjob</groupId>
-            <artifactId>elasticjob-lite-lifecycle</artifactId>
+            <artifactId>elasticjob-cloud-scheduler</artifactId>
             <version>${project.parent.version}</version>
         </dependency>
         <dependency>
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRegisterStatisticsRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRegisterStatisticsRepository.java
deleted file mode 100644
index 040a930..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRegisterStatisticsRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobRegisterStatistics;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * Job register statistics repository.
- */
-@Repository
-public interface JobRegisterStatisticsRepository extends JpaRepository<JobRegisterStatistics, Long> {
-    
-    /**
-     * Find job register statistics.
-     *
-     * @param fromTime from date to statistics
-     * @return job register statistics
-     */
-    @Query("FROM JobRegisterStatistics WHERE statisticsTime >= :fromTime")
-    List<JobRegisterStatistics> findJobRegisterStatistics(@Param("fromTime") Date fromTime);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRunningStatisticsRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRunningStatisticsRepository.java
deleted file mode 100644
index 767a172..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/JobRunningStatisticsRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobRunningStatistics;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * Job running statistics repository.
- */
-@Repository
-public interface JobRunningStatisticsRepository extends JpaRepository<JobRunningStatistics, Long> {
-    
-    /**
-     * Find job running statistics.
-     *
-     * @param fromTime from date to statistics
-     * @return job running statistics
-     */
-    @Query("FROM JobRunningStatistics WHERE statisticsTime >= :fromTime")
-    List<JobRunningStatistics> findJobRunningStatistics(@Param("fromTime") Date fromTime);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/StatisticInterval.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/StatisticInterval.java
deleted file mode 100644
index bf7f638..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/StatisticInterval.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-
-/**
- * Statistic interval.
- */
-@Getter
-@RequiredArgsConstructor
-public enum StatisticInterval {
-    
-    MINUTE("0 * * * * ?"),
-    
-    HOUR("0 0 * * * ?"), 
-    
-    DAY("0 0 0 * * ?");
-    
-    private final String cron;
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskResultStatisticsRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskResultStatisticsRepository.java
deleted file mode 100644
index 86f6a00..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskResultStatisticsRepository.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.TaskResultStatistics;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * Task result statistics repository.
- */
-@Repository
-public interface TaskResultStatisticsRepository extends JpaRepository<TaskResultStatistics, Long> {
-    
-    /**
-     * Find task result statistics.
-     *
-     * @param fromTime from date to statistics
-     * @param statisticInterval statistic interval
-     * @return task result statistics
-     */
-    @Query("FROM TaskResultStatistics WHERE statisticInterval = :statisticInterval AND statisticsTime >= :fromTime ORDER BY id ASC")
-    List<TaskResultStatistics> findTaskResultStatistics(@Param("fromTime") Date fromTime, @Param("statisticInterval") String statisticInterval);
-    
-    /**
-     * Get summed task result statistics.
-     *
-     * @param fromTime from date to statistics
-     * @param statisticInterval statistic interval
-     * @return summed task result statistics
-     */
-    @Query("SELECT new TaskResultStatistics(SUM(successCount), SUM(failedCount)) FROM TaskResultStatistics WHERE "
-        + "statisticInterval = :statisticInterval AND statisticsTime >= :fromTime")
-    TaskResultStatistics getSummedTaskResultStatistics(@Param("fromTime") Date fromTime, @Param("statisticInterval") String statisticInterval);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskRunningStatisticsRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskRunningStatisticsRepository.java
deleted file mode 100644
index 9c7e9f4..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/TaskRunningStatisticsRepository.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.TaskRunningStatistics;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.Query;
-import org.springframework.data.repository.query.Param;
-import org.springframework.stereotype.Repository;
-
-import java.util.Date;
-import java.util.List;
-
-/**
- * Task running statistics repository.
- */
-@Repository
-public interface TaskRunningStatisticsRepository extends JpaRepository<TaskRunningStatistics, Long> {
-    
-    /**
-     * Find task running statistics.
-     *
-     * @param fromTime from date to statistics
-     * @return Task running statistics
-     */
-    @Query("FROM TaskRunningStatistics where statisticsTime >= :fromTime")
-    List<TaskRunningStatistics> findTaskRunningStatistics(@Param("fromTime") Date fromTime);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobExecutionTypeStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobExecutionTypeStatistics.java
deleted file mode 100644
index 7f50466..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobExecutionTypeStatistics.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.type.job;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Job execution type statistics.
- */
-@Getter
-@AllArgsConstructor
-public final class JobExecutionTypeStatistics {
-    
-    private int transientJobCount;
-    
-    private int daemonJobCount;
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobTypeStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobTypeStatistics.java
deleted file mode 100644
index eafeb84..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/type/job/JobTypeStatistics.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.type.job;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * Job type statistics.
- */
-@Getter
-@AllArgsConstructor
-public final class JobTypeStatistics {
-    
-    private int scriptJobCount;
-    
-    private int simpleJobCount;
-    
-    private int dataflowJobCount;
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/DataSourceFactory.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/DataSourceFactory.java
deleted file mode 100644
index 377bc3e..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/DataSourceFactory.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import org.apache.commons.dbcp.BasicDataSource;
-import org.springframework.boot.jdbc.DataSourceBuilder;
-
-import javax.sql.DataSource;
-
-/**
- * Dynamic data source factory.
- */
-public final class DataSourceFactory {
-    
-    /**
-     * Create a DataSource.
-     * @param config event trace data source config
-     * @return data source
-     */
-    public static DataSource createDataSource(final EventTraceDataSourceConfiguration config) {
-        // Determine whether the data source is valid.
-        new EventTraceDataSource(config).init();
-        return DataSourceBuilder.create().type(BasicDataSource.class).driverClassName(config.getDriver()).url(config.getUrl())
-            .username(config.getUsername()).password(config.getPassword()).build();
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSource.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSource.java
deleted file mode 100644
index 5febd8f..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSource.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.extern.slf4j.Slf4j;
-
-import java.sql.DriverManager;
-import java.sql.SQLException;
-
-/**
- * Event tracing data source.
- */
-@Slf4j
-public final class EventTraceDataSource {
-    
-    @Getter(AccessLevel.PROTECTED)
-    private EventTraceDataSourceConfiguration eventTraceDataSourceConfiguration;
-    
-    public EventTraceDataSource(final EventTraceDataSourceConfiguration eventTraceDataSourceConfiguration) {
-        this.eventTraceDataSourceConfiguration = eventTraceDataSourceConfiguration;
-    }
-    
-    /**
-     * Initialize data source.
-     */
-    public void init() {
-        log.debug("Elastic job: data source init, connection url is: {}.", eventTraceDataSourceConfiguration.getUrl());
-        try {
-            Class.forName(eventTraceDataSourceConfiguration.getDriver());
-            DriverManager.getConnection(eventTraceDataSourceConfiguration.getUrl(), eventTraceDataSourceConfiguration.getUsername(), eventTraceDataSourceConfiguration.getPassword());
-        } catch (final ClassNotFoundException | SQLException ex) {
-            throw new RuntimeException(ex);
-        }
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfiguration.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfiguration.java
deleted file mode 100644
index ecc4610..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfiguration.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.io.Serializable;
-
-/**
- * Event trace data source configuration.
- */
-@NoArgsConstructor
-@Getter
-@Setter
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public final class EventTraceDataSourceConfiguration implements Serializable {
-    
-    private static final long serialVersionUID = -5996257770767863699L;
-    
-    @XmlAttribute(required = true)
-    private String name;
-    
-    @XmlAttribute(required = true)
-    private String driver;
-    
-    @XmlAttribute
-    private String url;
-    
-    @XmlAttribute
-    private String username;
-    
-    @XmlAttribute
-    private String password;
-    
-    @XmlAttribute
-    private boolean activated;
-    
-    public EventTraceDataSourceConfiguration(final String driver, final String url, final String username, final String password) {
-        this.driver = driver;
-        this.url = url;
-        this.username = username;
-        this.password = password;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfigurations.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfigurations.java
deleted file mode 100644
index 25df55e..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceConfigurations.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.Getter;
-
-import javax.xml.bind.annotation.XmlAccessType;
-import javax.xml.bind.annotation.XmlAccessorType;
-import javax.xml.bind.annotation.XmlRootElement;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-/**
- * Event trace data source configurations.
- */
-@Getter
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.FIELD)
-public final class EventTraceDataSourceConfigurations {
-    
-    private Set<EventTraceDataSourceConfiguration> eventTraceDataSourceConfiguration = new LinkedHashSet<>();
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceFactory.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceFactory.java
deleted file mode 100644
index d2f8577..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/EventTraceDataSourceFactory.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Strings;
-import com.google.common.hash.HashCode;
-import com.google.common.hash.Hasher;
-import com.google.common.hash.Hashing;
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Event trace data source factory.
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class EventTraceDataSourceFactory {
-    
-    private static final ConcurrentHashMap<HashCode, EventTraceDataSource> DATA_SOURCE_REGISTRY = new ConcurrentHashMap<>();
-    
-    /**
-     * Create event trace data source.
-     * 
-     * @param driverClassName database driver class name
-     * @param url database URL
-     * @param username database username
-     * @param password database password
-     * @return event trace data source
-     */
-    public static EventTraceDataSource createEventTraceDataSource(final String driverClassName, final String url, final String username, final String password) {
-        Hasher hasher = Hashing.sha256().newHasher().putString(driverClassName, Charsets.UTF_8).putString(url, Charsets.UTF_8);
-        if (!Strings.isNullOrEmpty(username)) {
-            hasher.putString(username, Charsets.UTF_8);
-        }
-        if (null != password) {
-            hasher.putString(password, Charsets.UTF_8);
-        }
-        HashCode hashCode = hasher.hash();
-        EventTraceDataSource result = DATA_SOURCE_REGISTRY.get(hashCode);
-        if (null != result) {
-            return result;
-        }
-        EventTraceDataSourceConfiguration eventTraceDataSourceConfiguration = new EventTraceDataSourceConfiguration(driverClassName, url, username, password);
-        result = new EventTraceDataSource(eventTraceDataSourceConfiguration);
-        result.init();
-        DATA_SOURCE_REGISTRY.put(hashCode, result);
-        return result;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/GlobalConfiguration.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/GlobalConfiguration.java
index 1dbfe4f..d412165 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/GlobalConfiguration.java
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/GlobalConfiguration.java
@@ -34,6 +34,4 @@ import javax.xml.bind.annotation.XmlRootElement;
 public final class GlobalConfiguration {
     
     private RegistryCenterConfigurations registryCenterConfigurations;
-    
-    private EventTraceDataSourceConfigurations eventTraceDataSourceConfigurations;
 }
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobExecutionLog.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobExecutionLog.java
deleted file mode 100644
index 6915564..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobExecutionLog.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.Data;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.util.Date;
-
-@Data
-@Entity(name = "JOB_EXECUTION_LOG")
-public class JobExecutionLog {
-    
-    @Id
-    private String id;
-    
-    @Column(name = "job_name")
-    private String jobName;
-    
-    @Column(name = "task_id")
-    private String taskId;
-    
-    @Column(name = "hostname")
-    private String hostname;
-    
-    @Column(name = "ip")
-    private String ip;
-    
-    @Column(name = "sharding_item")
-    private Integer shardingItem;
-    
-    @Column(name = "execution_source")
-    private String executionSource;
-    
-    @Column(name = "failure_cause")
-    private String failureCause;
-    
-    @Column(name = "is_success")
-    private Boolean isSuccess;
-    
-    @Column(name = "start_time")
-    private Date startTime;
-    
-    @Column(name = "complete_time")
-    private Date completeTime;
-    
-    /**
-     * JobExecutionLog convert to JobExecutionEvent.
-     *
-     * @return JobExecutionEvent entity
-     */
-    public JobExecutionEvent toJobExecutionEvent() {
-        return new JobExecutionEvent(
-                id,
-                hostname,
-                ip,
-                taskId,
-                jobName,
-                JobExecutionEvent.ExecutionSource.valueOf(executionSource),
-                shardingItem,
-                startTime,
-                completeTime,
-                isSuccess,
-                failureCause
-        );
-    }
-    
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRegisterStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRegisterStatistics.java
deleted file mode 100644
index 83bf6fe..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRegisterStatistics.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.util.Date;
-
-/**
- * Job register statistics.
- */
-@Getter
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "JOB_REGISTER_STATISTICS")
-public final class JobRegisterStatistics {
-    
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-    
-    @Column(name = "registered_count", length = 11)
-    private Integer registeredCount;
-    
-    @Column(name = "statistics_time", nullable = false)
-    private Date statisticsTime;
-    
-    @Column(name = "creation_time", nullable = false)
-    private Date creationTime = new Date();
-    
-    public JobRegisterStatistics(final Integer registeredCount, final Date statisticsTime) {
-        this.registeredCount = registeredCount;
-        this.statisticsTime = statisticsTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRunningStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRunningStatistics.java
deleted file mode 100644
index 4a9c584..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobRunningStatistics.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.util.Date;
-
-/**
- * Job running statistics.
- */
-@Getter
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "JOB_RUNNING_STATISTICS")
-public final class JobRunningStatistics {
-    
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-    
-    @Column(name = "running_count", length = 11)
-    private Integer runningCount;
-    
-    @Column(name = "statistics_time", nullable = false)
-    private Date statisticsTime;
-    
-    @Column(name = "creation_time", nullable = false)
-    private Date creationTime = new Date();
-    
-    public JobRunningStatistics(final Integer runningCount, final Date statisticsTime) {
-        this.runningCount = runningCount;
-        this.statisticsTime = statisticsTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobStatusTraceLog.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobStatusTraceLog.java
deleted file mode 100644
index 82d7664..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/JobStatusTraceLog.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.Data;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.Id;
-import java.util.Date;
-
-@Data
-@Entity(name = "JOB_STATUS_TRACE_LOG")
-public class JobStatusTraceLog {
-    
-    @Id
-    private String id;
-    
-    @Column(name = "job_name")
-    private String jobName;
-    
-    @Column(name = "original_task_id")
-    private String originalTaskId;
-    
-    @Column(name = "task_id")
-    private String taskId;
-    
-    @Column(name = "slave_id")
-    private String slaveId;
-    
-    @Column(name = "source")
-    private String source;
-    
-    @Column(name = "execution_type")
-    private String executionType;
-    
-    @Column(name = "sharding_item")
-    private String shardingItem;
-    
-    @Column(name = "state")
-    private String state;
-    
-    @Column(name = "message")
-    private String message;
-    
-    @Column(name = "creation_time")
-    private Date creationTime;
-    
-    /**
-     * JobStatusTraceLog convert to JobStatusTraceEvent.
-     *
-     * @return JobStatusTraceEvent entity
-     */
-    public JobStatusTraceEvent toJobStatusTraceEvent() {
-        return new JobStatusTraceEvent(
-                id,
-                jobName,
-                originalTaskId,
-                taskId,
-                slaveId,
-                JobStatusTraceEvent.Source.valueOf(source),
-                executionType,
-                shardingItem,
-                JobStatusTraceEvent.State.valueOf(state),
-                message,
-                creationTime
-        );
-    }
-    
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskResultStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskResultStatistics.java
deleted file mode 100644
index 6ff96a9..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskResultStatistics.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.util.Date;
-
-/**
- * Task result statistics.
- */
-@Getter
-@AllArgsConstructor
-@NoArgsConstructor
-@Entity
-@Table(name = "TASK_RESULT_STATISTICS")
-public final class TaskResultStatistics {
-    
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-    
-    @Column(name = "success_count", length = 11)
-    private Long successCount;
-    
-    @Column(name = "failed_count", length = 11)
-    private Long failedCount;
-    
-    @Column(name = "statistic_interval", length = 10)
-    private String statisticInterval;
-    
-    @Column(name = "statistics_time", nullable = false)
-    private Date statisticsTime;
-    
-    @Column(name = "creation_time", nullable = false)
-    private Date creationTime = new Date();
-    
-    public TaskResultStatistics(final Long successCount, final Long failedCount) {
-        this.successCount = successCount;
-        this.failedCount = failedCount;
-    }
-    
-    public TaskResultStatistics(final Long successCount, final Long failedCount, final String statisticInterval, final Date statisticsTime) {
-        this.successCount = successCount;
-        this.failedCount = failedCount;
-        this.statisticInterval = statisticInterval;
-        this.statisticsTime = statisticsTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskRunningStatistics.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskRunningStatistics.java
deleted file mode 100644
index 682d6fd..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/domain/TaskRunningStatistics.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.domain;
-
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-import javax.persistence.Column;
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-import javax.persistence.Table;
-import java.util.Date;
-
-/**
- * Task running statistics.
- */
-@Getter
-@NoArgsConstructor
-@AllArgsConstructor
-@Entity
-@Table(name = "TASK_RUNNING_STATISTICS")
-public final class TaskRunningStatistics {
-    
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private Long id;
-    
-    @Column(name = "running_count", length = 11)
-    private Integer runningCount;
-    
-    @Column(name = "statistics_time", nullable = false)
-    private Date statisticsTime;
-    
-    @Column(name = "creation_time", nullable = false)
-    private Date creationTime = new Date();
-    
-    public TaskRunningStatistics(final Integer runningCount, final Date statisticsTime) {
-        this.runningCount = runningCount;
-        this.statisticsTime = statisticsTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/BasePageRequest.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/BasePageRequest.java
deleted file mode 100644
index c6d6152..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/BasePageRequest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dto.request;
-
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-/**
- * Pageable request base request.
- */
-@Getter
-@Setter
-@NoArgsConstructor
-@AllArgsConstructor
-public class BasePageRequest {
-    
-    public static final int DEFAULT_PAGE_SIZE = 10;
-    
-    /**
-     * Page size of request.
-     */
-    @JsonProperty("per_page")
-    private Integer pageSize = DEFAULT_PAGE_SIZE;
-    
-    /**
-     * Page number of request.
-     */
-    @JsonProperty("page")
-    private Integer pageNumber = 1;
-    
-    /**
-     * The field name for sort by.
-     */
-    @JsonProperty("sort")
-    private String sortBy;
-    
-    /**
-     * Order type, asc or desc.
-     */
-    @JsonProperty("order")
-    private String orderType;
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobExecutionEventsRequest.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobExecutionEventsRequest.java
deleted file mode 100644
index b4eb05b..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobExecutionEventsRequest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dto.request;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import java.util.Date;
-
-/**
- * Request object of uri '/event-trace/execution'.
- */
-@Getter
-@Setter
-@NoArgsConstructor
-@AllArgsConstructor
-public class FindJobExecutionEventsRequest extends BasePageRequest {
-    
-    private String jobName;
-    
-    private String ip;
-    
-    private Boolean isSuccess;
-    
-    @JsonProperty("startTime")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private Date start;
-    
-    @JsonProperty("endTime")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private Date end;
-    
-    /**
-     * Create new FindJobExecutionEventsRequest with pageSize and pageNumber.
-     * @param pageNumber page number
-     * @param pageSize page size
-     */
-    public FindJobExecutionEventsRequest(final Integer pageSize, final Integer pageNumber) {
-        super(pageSize, pageNumber, null, null);
-    }
-    
-    /**
-     * Create new FindJobExecutionEventsRequest with properties.
-     * @param pageNumber page number
-     * @param pageSize page size
-     * @param sortBy the field name sort by
-     * @param orderType order type, asc or desc
-     * @param startTime start time
-     * @param endTime end time
-     */
-    public FindJobExecutionEventsRequest(final Integer pageSize, final Integer pageNumber, final String sortBy,
-                                         final String orderType, final Date startTime, final Date endTime) {
-        super(pageSize, pageNumber, sortBy, orderType);
-        this.start = startTime;
-        this.end = endTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobStatusTraceEventsRequest.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobStatusTraceEventsRequest.java
deleted file mode 100644
index 3d48156..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/request/FindJobStatusTraceEventsRequest.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dto.request;
-
-import com.fasterxml.jackson.annotation.JsonFormat;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import lombok.Setter;
-
-import java.util.Date;
-
-/**
- * Request object of uri '/event-trace/status'.
- */
-@Getter
-@Setter
-@NoArgsConstructor
-@AllArgsConstructor
-public class FindJobStatusTraceEventsRequest extends BasePageRequest {
-    
-    private String jobName;
-    
-    private String source;
-    
-    private String executionType;
-    
-    private String state;
-    
-    @JsonProperty("startTime")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private Date start;
-    
-    @JsonProperty("endTime")
-    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
-    private Date end;
-    
-    public FindJobStatusTraceEventsRequest(final Integer pageSize, final Integer pageNumber) {
-        super(pageSize, pageNumber, null, null);
-    }
-    
-    public FindJobStatusTraceEventsRequest(final Integer pageSize, final Integer pageNumber, final String sortBy, final String orderType, final Date startTime, final Date endTime) {
-        super(pageSize, pageNumber, sortBy, orderType);
-        this.start = startTime;
-        this.end = endTime;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/response/BasePageResponse.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/response/BasePageResponse.java
deleted file mode 100644
index 095d45d..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dto/response/BasePageResponse.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dto.response;
-
-import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-import org.springframework.data.domain.Page;
-
-import java.io.Serializable;
-import java.util.List;
-
-@Getter
-@AllArgsConstructor
-@NoArgsConstructor
-@JsonIgnoreProperties(ignoreUnknown = true)
-public class BasePageResponse<T> implements Serializable {
-    
-    /**
-     * Total count of rows.
-     */
-    private Long total;
-    
-    /**
-     * Rows data.
-     */
-    private List<T> rows;
-    
-    /**
-     * Create new BasePageResponse with total and data.
-     * @param total Total count of match data
-     * @param data Current page of data
-     * @param <T> Data type
-     * @return BasePageResponse
-     */
-    public static <T> BasePageResponse of(final Long total, final List<T> data) {
-        return new BasePageResponse(total, data);
-    }
-    
-    /**
-     * Create new BasePageResponse with Page.
-     * @param page match data info.
-     * @param <T> Data type
-     * @return BasePageResponse
-     */
-    public static <T> BasePageResponse of(final Page<T> page) {
-        return new BasePageResponse(page.getTotalElements(), page.getContent());
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/CloudServiceFactory.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/CloudServiceFactory.java
new file mode 100644
index 0000000..f130dac
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/CloudServiceFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.service;
+
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.app.CloudAppConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.job.CloudJobConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.MesosStateService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.state.disable.app.DisableAppService;
+
+/**
+ * Cloud service factory.
+ */
+public final class CloudServiceFactory {
+    
+    /**
+     * Get app config service.
+     *
+     * @return app config service
+     */
+    public static CloudAppConfigurationService getAppConfigService() {
+        return new CloudAppConfigurationService(RegistryCenterFactory.getRegistryCenter());
+    }
+    
+    /**
+     * Get job config service.
+     *
+     * @return job config service
+     */
+    public static CloudJobConfigurationService getJobConfigService() {
+        return new CloudJobConfigurationService(RegistryCenterFactory.getRegistryCenter());
+    }
+    
+    /**
+     * Get mesos state service.
+     *
+     * @return mesos state service
+     */
+    public static MesosStateService getMesosStateService() {
+        return new MesosStateService(RegistryCenterFactory.getRegistryCenter());
+    }
+    
+    /**
+     * Get disable app service.
+     *
+     * @return disable app service
+     */
+    public static DisableAppService getDisableAppService() {
+        return new DisableAppService(RegistryCenterFactory.getRegistryCenter());
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceDataSourceConfigurationService.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceDataSourceConfigurationService.java
deleted file mode 100644
index 620ab81..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceDataSourceConfigurationService.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfigurations;
-
-import java.util.Optional;
-
-/**
- * Event trace data source configuration service.
- */
-public interface EventTraceDataSourceConfigurationService {
-    
-    /**
-     * Load all event trace data source configurations.
-     *
-     * @return all event trace data source configuration
-     */
-    EventTraceDataSourceConfigurations loadAll();
-    
-    /**
-     * Load event trace data source configuration.
-     * 
-     * @param name name of event trace data source configuration
-     * @return event trace data source configuration
-     */
-    EventTraceDataSourceConfiguration load(String name);
-    
-    /**
-     * Find event trace data source configuration.
-     *
-     * @param name name of event trace data source configuration
-     * @param configs event trace data source configurations
-     * @return event trace data source configuration
-     */
-    EventTraceDataSourceConfiguration find(String name, EventTraceDataSourceConfigurations configs);
-    
-    /**
-     * Load activated event trace data source configuration.
-     * 
-     * @return activated event trace data source configuration
-     */
-    Optional<EventTraceDataSourceConfiguration> loadActivated();
-    
-    /**
-     * Add event trace data source configuration.
-     * 
-     * @param config event trace data source configuration
-     * @return success to add or not
-     */
-    boolean add(EventTraceDataSourceConfiguration config);
-    
-    /**
-     * Delete event trace data source configuration.
-     *
-     * @param name name of event trace data source configuration
-     */
-    void delete(String name);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceHistoryService.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceHistoryService.java
deleted file mode 100644
index 050c820..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/EventTraceHistoryService.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service;
-
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobExecutionEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobStatusTraceEventsRequest;
-import org.springframework.data.domain.Page;
-
-/**
- * Event trace history service.
- */
-public interface EventTraceHistoryService {
-    
-    /**
-     * Find job execution events.
-     *
-     * @param findJobExecutionEventsRequest query params
-     * @return job execution events
-     */
-    Page<JobExecutionEvent> findJobExecutionEvents(FindJobExecutionEventsRequest findJobExecutionEventsRequest);
-    
-    /**
-     * Find job status trace events.
-     *
-     * @param findJobStatusTraceEventsRequest query params
-     * @return job status trace events
-     */
-    Page<JobStatusTraceEvent> findJobStatusTraceEvents(FindJobStatusTraceEventsRequest findJobStatusTraceEventsRequest);
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/JobAPIService.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/JobAPIService.java
deleted file mode 100644
index ddf38cd..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/JobAPIService.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service;
-
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobConfigurationAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobOperateAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobStatisticsAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ServerStatisticsAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ShardingOperateAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ShardingStatisticsAPI;
-
-public interface JobAPIService {
-    
-    /**
-     * Job configuration API.
-     *
-     * @return job configuration API
-     */
-    JobConfigurationAPI getJobConfigurationAPI();
-    
-    /**
-     * Job operate API.
-     *
-     * @return Job operate API
-     */
-    JobOperateAPI getJobOperatorAPI();
-    
-    /**
-     * Sharding operate API.
-     *
-     * @return sharding operate API
-     */
-    ShardingOperateAPI getShardingOperateAPI();
-    
-    /**
-     * Job statistics API.
-     *
-     * @return job statistics API
-     */
-    JobStatisticsAPI getJobStatisticsAPI();
-    
-    /**
-     * Servers statistics API.
-     *
-     * @return server statistics API
-     */
-    ServerStatisticsAPI getServerStatisticsAPI();
-    
-    /**
-     * Sharding statistics API.
-     *
-     * @return sharding statistics API
-     */
-    ShardingStatisticsAPI getShardingStatisticsAPI();
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/RegistryCenterFactory.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/RegistryCenterFactory.java
new file mode 100644
index 0000000..d29ccc7
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/RegistryCenterFactory.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.service;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Strings;
+import com.google.common.hash.HashCode;
+import com.google.common.hash.Hasher;
+import com.google.common.hash.Hashing;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.elasticjob.cloud.ui.domain.RegistryCenterConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.ui.util.SessionRegistryCenterConfiguration;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperConfiguration;
+import org.apache.shardingsphere.elasticjob.reg.zookeeper.ZookeeperRegistryCenter;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Registry center factory.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class RegistryCenterFactory {
+    
+    private static final ConcurrentHashMap<HashCode, CoordinatorRegistryCenter> REG_CENTER_REGISTRY = new ConcurrentHashMap<>();
+    
+    /**
+     * Create registry center.
+     *
+     * @param connectString registry center connect string
+     * @param namespace registry center namespace
+     * @param digest registry center digest
+     * @return registry center
+     */
+    public static CoordinatorRegistryCenter createCoordinatorRegistryCenter(final String connectString, final String namespace, final String digest) {
+        Hasher hasher = Hashing.sha256().newHasher().putString(connectString, Charsets.UTF_8).putString(namespace, Charsets.UTF_8);
+        if (!Strings.isNullOrEmpty(digest)) {
+            hasher.putString(digest, Charsets.UTF_8);
+        }
+        HashCode hashCode = hasher.hash();
+        CoordinatorRegistryCenter result = REG_CENTER_REGISTRY.get(hashCode);
+        if (null != result) {
+            return result;
+        }
+        ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(connectString, namespace);
+        if (!Strings.isNullOrEmpty(digest)) {
+            zkConfig.setDigest(digest);
+        }
+        result = new ZookeeperRegistryCenter(zkConfig);
+        result.init();
+        REG_CENTER_REGISTRY.put(hashCode, result);
+        return result;
+    }
+    
+    public static CoordinatorRegistryCenter getRegistryCenter() {
+        RegistryCenterConfiguration registryCenterConfiguration = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
+        String connectString = registryCenterConfiguration.getZkAddressList();
+        String namespace = registryCenterConfiguration.getNamespace();
+        String digest = registryCenterConfiguration.getDigest();
+        Hasher hasher = Hashing.sha256().newHasher().putString(connectString, Charsets.UTF_8).putString(namespace, Charsets.UTF_8);
+        if (!Strings.isNullOrEmpty(digest)) {
+            hasher.putString(digest, Charsets.UTF_8);
+        }
+        HashCode hashCode = hasher.hash();
+        CoordinatorRegistryCenter result = REG_CENTER_REGISTRY.get(hashCode);
+        if (null != result) {
+            return result;
+        }
+        ZookeeperConfiguration zkConfig = new ZookeeperConfiguration(connectString, namespace);
+        if (!Strings.isNullOrEmpty(digest)) {
+            zkConfig.setDigest(digest);
+        }
+        result = new ZookeeperRegistryCenter(zkConfig);
+        result.init();
+        REG_CENTER_REGISTRY.put(hashCode, result);
+        return result;
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceDataSourceConfigurationServiceImpl.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceDataSourceConfigurationServiceImpl.java
deleted file mode 100644
index 0f21585..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceDataSourceConfigurationServiceImpl.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service.impl;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.config.DynamicDataSourceConfig;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.DataSourceFactory;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfigurations;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.GlobalConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.repository.ConfigurationsXmlRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.repository.impl.ConfigurationsXmlRepositoryImpl;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceDataSourceConfigurationService;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-import javax.sql.DataSource;
-import java.util.Optional;
-
-/**
- * Event trace data source configuration service implementation.
- */
-@Service
-public final class EventTraceDataSourceConfigurationServiceImpl implements EventTraceDataSourceConfigurationService {
-    
-    private ConfigurationsXmlRepository configurationsXmlRepository = new ConfigurationsXmlRepositoryImpl();
-    
-    @Autowired
-    private DynamicDataSourceConfig.DynamicDataSource dynamicDataSource;
-    
-    @Override
-    public EventTraceDataSourceConfigurations loadAll() {
-        return loadGlobal().getEventTraceDataSourceConfigurations();
-    }
-    
-    @Override
-    public EventTraceDataSourceConfiguration load(final String name) {
-        GlobalConfiguration configs = loadGlobal();
-        EventTraceDataSourceConfiguration result = find(name, configs.getEventTraceDataSourceConfigurations());
-        setActivated(configs, result);
-        // Activate the dataSource by data source name for spring boot
-        DynamicDataSourceConfig.DynamicDataSourceContextHolder.setDataSourceName(name);
-        return result;
-    }
-    
-    @Override
-    public EventTraceDataSourceConfiguration find(final String name, final EventTraceDataSourceConfigurations configs) {
-        for (EventTraceDataSourceConfiguration each : configs.getEventTraceDataSourceConfiguration()) {
-            if (name.equals(each.getName())) {
-                return each;
-            }
-        }
-        return null;
-    }
-    
-    private void setActivated(final GlobalConfiguration configs, final EventTraceDataSourceConfiguration toBeConnectedConfig) {
-        EventTraceDataSourceConfiguration activatedConfig = findActivatedDataSourceConfiguration(configs);
-        if (!toBeConnectedConfig.equals(activatedConfig)) {
-            if (null != activatedConfig) {
-                activatedConfig.setActivated(false);
-            }
-            toBeConnectedConfig.setActivated(true);
-            configurationsXmlRepository.save(configs);
-        }
-    }
-    
-    @Override
-    public Optional<EventTraceDataSourceConfiguration> loadActivated() {
-        return Optional.ofNullable(findActivatedDataSourceConfiguration(loadGlobal()));
-    }
-    
-    private EventTraceDataSourceConfiguration findActivatedDataSourceConfiguration(final GlobalConfiguration configs) {
-        for (EventTraceDataSourceConfiguration each : configs.getEventTraceDataSourceConfigurations().getEventTraceDataSourceConfiguration()) {
-            if (each.isActivated()) {
-                return each;
-            }
-        }
-        return null;
-    }
-    
-    @Override
-    public boolean add(final EventTraceDataSourceConfiguration config) {
-        GlobalConfiguration configs = loadGlobal();
-        boolean result = configs.getEventTraceDataSourceConfigurations().getEventTraceDataSourceConfiguration().add(config);
-        if (result) {
-            configurationsXmlRepository.save(configs);
-        }
-        DataSource dataSource = DataSourceFactory.createDataSource(config);
-        dynamicDataSource.addDataSource(config.getName(), dataSource);
-        return result;
-    }
-    
-    @Override
-    public void delete(final String name) {
-        GlobalConfiguration configs = loadGlobal();
-        EventTraceDataSourceConfiguration toBeRemovedConfig = find(name, configs.getEventTraceDataSourceConfigurations());
-        if (null != toBeRemovedConfig) {
-            configs.getEventTraceDataSourceConfigurations().getEventTraceDataSourceConfiguration().remove(toBeRemovedConfig);
-            configurationsXmlRepository.save(configs);
-        }
-    }
-    
-    private GlobalConfiguration loadGlobal() {
-        GlobalConfiguration result = configurationsXmlRepository.load();
-        if (null == result.getEventTraceDataSourceConfigurations()) {
-            result.setEventTraceDataSourceConfigurations(new EventTraceDataSourceConfigurations());
-        }
-        return result;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceHistoryServiceImpl.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceHistoryServiceImpl.java
deleted file mode 100644
index 9c3009c..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/EventTraceHistoryServiceImpl.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service.impl;
-
-import com.google.common.base.Strings;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.search.JobExecutionLogRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.search.JobStatusTraceLogRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobExecutionLog;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobStatusTraceLog;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.BasePageRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobExecutionEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobStatusTraceEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceHistoryService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.util.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Example;
-import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
-import org.springframework.data.domain.Sort;
-import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
-import org.springframework.data.jpa.domain.Specification;
-import org.springframework.stereotype.Component;
-
-import javax.persistence.criteria.Predicate;
-import java.lang.reflect.Field;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Event trace history service implementation.
- */
-@Slf4j
-@Component
-public final class EventTraceHistoryServiceImpl implements EventTraceHistoryService {
-    
-    @Autowired
-    private JobExecutionLogRepository jobExecutionLogRepository;
-    
-    @Autowired
-    private JobStatusTraceLogRepository jobStatusTraceLogRepository;
-    
-    @Override
-    public Page<JobExecutionEvent> findJobExecutionEvents(final FindJobExecutionEventsRequest findJobExecutionEventsRequest) {
-        Example<JobExecutionLog> jobExecutionLogExample = getExample(findJobExecutionEventsRequest, JobExecutionLog.class);
-        Specification<JobExecutionLog> specification = getSpecWithExampleAndDate(jobExecutionLogExample, findJobExecutionEventsRequest.getStart(),
-            findJobExecutionEventsRequest.getEnd(), "startTime");
-
-        Page<JobExecutionLog> page = jobExecutionLogRepository.findAll(specification, getPageable(findJobExecutionEventsRequest, JobExecutionLog.class));
-        return new PageImpl<>(page.get().map(JobExecutionLog::toJobExecutionEvent).collect(Collectors.toList()), page.getPageable(), page.getTotalElements());
-    }
-    
-    @Override
-    public Page<JobStatusTraceEvent> findJobStatusTraceEvents(final FindJobStatusTraceEventsRequest findJobStatusTraceEventsRequest) {
-        Example<JobStatusTraceLog> jobStatusTraceLogExample = getExample(findJobStatusTraceEventsRequest, JobStatusTraceLog.class);
-        Specification<JobStatusTraceLog> specification = getSpecWithExampleAndDate(jobStatusTraceLogExample, findJobStatusTraceEventsRequest.getStart(),
-            findJobStatusTraceEventsRequest.getEnd(), "creationTime");
-        Page<JobStatusTraceLog> page = jobStatusTraceLogRepository.findAll(specification, getPageable(findJobStatusTraceEventsRequest, JobStatusTraceLog.class));
-        return new PageImpl<>(page.get().map(JobStatusTraceLog::toJobStatusTraceEvent).collect(Collectors.toList()), page.getPageable(), page.getTotalElements());
-    }
-    
-    private <T> Pageable getPageable(final BasePageRequest pageRequest, final Class<T> clazz) {
-        int page = 0;
-        int perPage = BasePageRequest.DEFAULT_PAGE_SIZE;
-        if (pageRequest.getPageNumber() > 0 && pageRequest.getPageSize() > 0) {
-            page = pageRequest.getPageNumber() - 1;
-            perPage = pageRequest.getPageSize();
-        }
-        return PageRequest.of(page, perPage, getSort(pageRequest, clazz));
-    }
-    
-    private <T> Sort getSort(final BasePageRequest pageRequest, final Class<T> clazz) {
-        Sort sort = Sort.unsorted();
-        boolean sortFieldIsPresent = Arrays.stream(clazz.getDeclaredFields())
-            .map(Field::getName)
-            .anyMatch(e -> e.equals(pageRequest.getSortBy()));
-        if (!sortFieldIsPresent) {
-            return sort;
-        }
-        if (!Strings.isNullOrEmpty(pageRequest.getSortBy())) {
-            Sort.Direction order = Sort.Direction.ASC;
-            try {
-                order = Sort.Direction.valueOf(pageRequest.getOrderType());
-            } catch (IllegalArgumentException ignored) {
-            }
-            sort = Sort.by(order, pageRequest.getSortBy());
-        }
-        return sort;
-    }
-    
-    private <T> Specification<T> getSpecWithExampleAndDate(final Example<T> example, final Date from, final Date to, final String field) {
-        return (Specification<T>) (root, query, builder) -> {
-            final List<Predicate> predicates = new ArrayList<>();
-            if (from != null) {
-                predicates.add(builder.greaterThan(root.get(field), from));
-            }
-            if (to != null) {
-                predicates.add(builder.lessThan(root.get(field), to));
-            }
-            predicates.add(QueryByExamplePredicateBuilder.getPredicate(root, builder, example));
-            return builder.and(predicates.toArray(new Predicate[0]));
-        };
-    }
-    
-    private <T> Example<T> getExample(final Object source, final Class<T> clazz) {
-        T instance = BeanUtils.newInstance(clazz);
-        BeanUtils.copyProperties(source, instance);
-        return Example.of(instance);
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/JobAPIServiceImpl.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/JobAPIServiceImpl.java
deleted file mode 100644
index 84fd447..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/service/impl/JobAPIServiceImpl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.service.impl;
-
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobAPIFactory;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobConfigurationAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobOperateAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.JobStatisticsAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ServerStatisticsAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ShardingOperateAPI;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.api.ShardingStatisticsAPI;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.RegistryCenterConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.JobAPIService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.util.SessionRegistryCenterConfiguration;
-import org.springframework.stereotype.Service;
-
-/**
- * Job API service implementation.
- */
-@Service
-public final class JobAPIServiceImpl implements JobAPIService {
-    
-    @Override
-    public JobConfigurationAPI getJobConfigurationAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createJobConfigurationAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-    
-    @Override
-    public JobOperateAPI getJobOperatorAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createJobOperateAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-    
-    @Override
-    public ShardingOperateAPI getShardingOperateAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createShardingOperateAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-    
-    @Override
-    public JobStatisticsAPI getJobStatisticsAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createJobStatisticsAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-    
-    @Override
-    public ServerStatisticsAPI getServerStatisticsAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createServerStatisticsAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-    
-    @Override
-    public ShardingStatisticsAPI getShardingStatisticsAPI() {
-        RegistryCenterConfiguration regCenterConfig = SessionRegistryCenterConfiguration.getRegistryCenterConfiguration();
-        return JobAPIFactory.createShardingStatisticsAPI(regCenterConfig.getZkAddressList(), regCenterConfig.getNamespace(), regCenterConfig.getDigest());
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/BeanUtils.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/BeanUtils.java
deleted file mode 100644
index e2f58fb..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/BeanUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.util;
-
-import org.springframework.cglib.beans.BeanMap;
-
-import java.util.Map;
-import java.util.Objects;
-
-public class BeanUtils extends org.springframework.beans.BeanUtils {
-    
-    /**
-     * return a new instance by specified java type.
-     *
-     * @param clazz java type class
-     * @param <T>   java type
-     * @return new instance
-     */
-    public static <T> T newInstance(final Class<T> clazz) {
-        return instantiateClass(clazz);
-    }
-    
-    /**
-     * map to java object.
-     *
-     * @param map  source map
-     * @param type class
-     * @param <T>  target java type
-     * @return java object
-     */
-    public static <T> T toBean(final Map<String, Object> map, final Class<T> type) {
-        if (Objects.isNull(map)) {
-            return null;
-        }
-        T bean = newInstance(type);
-        BeanMap beanMap = BeanMap.create(bean);
-        beanMap.putAll(map);
-        return bean;
-    }
-    
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/SessionEventTraceDataSourceConfiguration.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/SessionEventTraceDataSourceConfiguration.java
deleted file mode 100644
index 0708941..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/util/SessionEventTraceDataSourceConfiguration.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.util;
-
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.elasticjob.cloud.ui.config.DynamicDataSourceConfig;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfiguration;
-
-/**
- * Event trace data source configuration in session.
- */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class SessionEventTraceDataSourceConfiguration {
-    
-    private static EventTraceDataSourceConfiguration eventTraceDataSourceConfiguration;
-    
-    /**
-     * Set event trace data source configuration.
-     *
-     * @param eventTraceDataSourceConfiguration event trace data source configuration
-     */
-    public static void setDataSourceConfiguration(final EventTraceDataSourceConfiguration eventTraceDataSourceConfiguration) {
-        DynamicDataSourceConfig.DynamicDataSourceContextHolder.setDataSourceName(eventTraceDataSourceConfiguration.getName());
-        SessionEventTraceDataSourceConfiguration.eventTraceDataSourceConfiguration = eventTraceDataSourceConfiguration;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudAppController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudAppController.java
new file mode 100644
index 0000000..956a493
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudAppController.java
@@ -0,0 +1,173 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
+
+import org.apache.mesos.Protos.ExecutorID;
+import org.apache.mesos.Protos.SlaveID;
+import org.apache.shardingsphere.elasticjob.cloud.config.pojo.CloudJobConfigurationPOJO;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.app.CloudAppConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.app.pojo.CloudAppConfigurationPOJO;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.job.CloudJobConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.exception.AppConfigurationException;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.MesosStateService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.MesosStateService.ExecutorStateInfo;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.producer.ProducerManager;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.state.disable.app.DisableAppService;
+import org.apache.shardingsphere.elasticjob.cloud.ui.service.CloudServiceFactory;
+import org.apache.shardingsphere.elasticjob.cloud.ui.util.SessionRegistryCenterConfiguration;
+import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
+import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
+import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.codehaus.jettison.json.JSONException;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collection;
+import java.util.Optional;
+
+/**
+ * Cloud app controller.
+ */
+@RestController
+@RequestMapping("/api/app")
+public final class CloudAppController {
+    
+    private static ProducerManager producerManager;
+    
+    /**
+     * Register app config.
+     * @param appConfig cloud app config
+     */
+    @PostMapping
+    public void register(@RequestBody final CloudAppConfigurationPOJO appConfig) {
+        CloudAppConfigurationService appConfigService = CloudServiceFactory.getAppConfigService();
+        Optional<CloudAppConfigurationPOJO> appConfigFromZk = appConfigService.load(appConfig.getAppName());
+        if (appConfigFromZk.isPresent()) {
+            throw new AppConfigurationException("app '%s' already existed.", appConfig.getAppName());
+        }
+        appConfigService.add(appConfig);
+    }
+    
+    /**
+     * Update app config.
+     * @param appConfig cloud app config
+     */
+    @PutMapping
+    public void update(@RequestBody final CloudAppConfigurationPOJO appConfig) {
+        CloudServiceFactory.getAppConfigService().update(appConfig);
+    }
+    
+    /**
+     * Query app config.
+     * @param appName app name
+     * @return cloud app config
+     */
+    @GetMapping("/{appName}")
+    public CloudAppConfigurationPOJO detail(@PathVariable("appName") final String appName) {
+        Optional<CloudAppConfigurationPOJO> appConfig = CloudServiceFactory.getAppConfigService().load(appName);
+        return appConfig.orElse(null);
+    }
+    
+    /**
+     * Find all registered app configs.
+     * @return collection of registered app configs
+     */
+    @GetMapping("/list")
+    public ResponseResult<Collection<CloudAppConfigurationPOJO>> findAllApps() {
+        return ResponseResultUtil.build(CloudServiceFactory.getAppConfigService().loadAll());
+    }
+    
+    /**
+     * Query the app is disabled or not.
+     * @param appName app name
+     * @return true is disabled, otherwise not
+     */
+    @GetMapping("/{appName}/disable")
+    public boolean isDisabled(@PathVariable("appName") final String appName) {
+        return CloudServiceFactory.getDisableAppService().isDisabled(appName);
+    }
+    
+    /**
+     * Disable app config.
+     * @param appName app name
+     */
+    @PostMapping("/{appName}/disable")
+    public void disable(@PathVariable("appName") final String appName) {
+        if (CloudServiceFactory.getAppConfigService().load(appName).isPresent()) {
+            CloudServiceFactory.getDisableAppService().add(appName);
+            for (CloudJobConfigurationPOJO each : CloudServiceFactory.getJobConfigService().loadAll()) {
+                if (appName.equals(each.getAppName())) {
+                    producerManager.unschedule(each.getJobName());
+                }
+            }
+        }
+    }
+    
+    /**
+     * Enable app.
+     * @param appName app name
+     */
+    @PostMapping("/{appName}/enable")
+    public void enable(@PathVariable("appName") final String appName) {
+        if (CloudServiceFactory.getAppConfigService().load(appName).isPresent()) {
+            CloudServiceFactory.getDisableAppService().remove(appName);
+            for (CloudJobConfigurationPOJO each : CloudServiceFactory.getJobConfigService().loadAll()) {
+                if (appName.equals(each.getAppName())) {
+                    producerManager.reschedule(each.getJobName());
+                }
+            }
+        }
+    }
+    
+    /**
+     * Deregister app.
+     * @param appName app name
+     */
+    @DeleteMapping("/{appName}")
+    public void deregister(@PathVariable("appName") final String appName) {
+        if (CloudServiceFactory.getAppConfigService().load(appName).isPresent()) {
+            removeAppAndJobConfigurations(appName);
+            stopExecutors(appName);
+        }
+    }
+    
+    private void removeAppAndJobConfigurations(final String appName) {
+        for (CloudJobConfigurationPOJO each : CloudServiceFactory.getJobConfigService().loadAll()) {
+            if (appName.equals(each.getAppName())) {
+                producerManager.deregister(each.getJobName());
+            }
+        }
+        CloudServiceFactory.getDisableAppService().remove(appName);
+        CloudServiceFactory.getAppConfigService().remove(appName);
+    }
+    
+    private void stopExecutors(final String appName) {
+        Collection<ExecutorStateInfo> executorBriefInfo = CloudServiceFactory.getMesosStateService().executors(appName);
+        for (ExecutorStateInfo each : executorBriefInfo) {
+            producerManager.sendFrameworkMessage(ExecutorID.newBuilder().setValue(each.getId()).build(),
+                    SlaveID.newBuilder().setValue(each.getSlaveId()).build(), "STOP".getBytes());
+        }
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudJobController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudJobController.java
new file mode 100644
index 0000000..5b657ac
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudJobController.java
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.elasticjob.cloud.config.CloudJobExecutionType;
+import org.apache.shardingsphere.elasticjob.cloud.config.pojo.CloudJobConfigurationPOJO;
+import org.apache.shardingsphere.elasticjob.cloud.console.controller.search.JobEventRdbSearch;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.config.job.CloudJobConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.env.BootstrapEnvironment;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.FacadeService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.producer.ProducerManager;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.state.failover.FailoverTaskInfo;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.statistics.StatisticManager;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.StatisticInterval;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.job.JobExecutionTypeStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.job.JobRegisterStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.job.JobRunningStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.task.TaskResultStatistics;
+import org.apache.shardingsphere.elasticjob.cloud.statistics.type.task.TaskRunningStatistics;
+import org.apache.shardingsphere.elasticjob.infra.context.TaskContext;
+import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.tracing.api.TracingConfiguration;
+import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.sql.DataSource;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Cloud job restful api.
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/job")
+public final class CloudJobController {
+    
+    private static CoordinatorRegistryCenter regCenter;
+    
+    private static JobEventRdbSearch jobEventRdbSearch;
+    
+    private static ProducerManager producerManager;
+    
+    private final CloudJobConfigurationService configService;
+    
+    private final FacadeService facadeService;
+    
+    private final StatisticManager statisticManager;
+    
+    public CloudJobController() {
+       // Preconditions.checkNotNull(regCenter);
+        configService = new CloudJobConfigurationService(regCenter);
+        facadeService = new FacadeService(regCenter);
+        statisticManager = StatisticManager.getInstance(regCenter, null);
+    }
+    
+    /**
+     * Init.
+     * @param regCenter       registry center
+     * @param producerManager producer manager
+     */
+    public static void init(final CoordinatorRegistryCenter regCenter, final ProducerManager producerManager) {
+        CloudJobController.regCenter = regCenter;
+        CloudJobController.producerManager = producerManager;
+        Optional<TracingConfiguration> tracingConfiguration = BootstrapEnvironment.getInstance().getTracingConfiguration();
+        jobEventRdbSearch = tracingConfiguration.map(tracingConfiguration1 -> new JobEventRdbSearch((DataSource) tracingConfiguration1.getStorage())).orElse(null);
+    }
+    
+    /**
+     * Register cloud job.
+     * @param cloudJobConfig cloud job configuration
+     */
+    @PostMapping("/register")
+    public void register(@RequestBody final CloudJobConfigurationPOJO cloudJobConfig) {
+        producerManager.register(cloudJobConfig);
+    }
+    
+    /**
+     * Update cloud job.
+     * @param cloudJobConfig cloud job configuration
+     */
+    @PutMapping("/update")
+    public void update(@RequestBody final CloudJobConfigurationPOJO cloudJobConfig) {
+        producerManager.update(cloudJobConfig);
+    }
+    
+    /**
+     * Deregister cloud job.
+     * @param jobName job name
+     */
+    @DeleteMapping("/{jobName}/deregister")
+    public void deregister(@PathVariable final String jobName) {
+        producerManager.deregister(jobName);
+    }
+    
+    /**
+     * Check whether the cloud job is disabled or not.
+     * @param jobName job name
+     * @return true is disabled, otherwise not
+     */
+    @GetMapping("/{jobName}/disable")
+    public boolean isDisabled(@PathVariable("jobName") final String jobName) {
+        return facadeService.isJobDisabled(jobName);
+    }
+    
+    /**
+     * Enable cloud job.
+     * @param jobName job name
+     */
+    @PostMapping("/{jobName}/enable")
+    public void enable(@PathVariable("jobName") final String jobName) {
+        Optional<CloudJobConfigurationPOJO> configOptional = configService.load(jobName);
+        if (configOptional.isPresent()) {
+            facadeService.enableJob(jobName);
+            producerManager.reschedule(jobName);
+        }
+    }
+    
+    /**
+     * Disable cloud job.
+     * @param jobName job name
+     */
+    @PostMapping("/{jobName}/disable")
+    public void disable(@PathVariable("jobName") final String jobName) {
+        if (configService.load(jobName).isPresent()) {
+            facadeService.disableJob(jobName);
+            producerManager.unschedule(jobName);
+        }
+    }
+    
+    /**
+     * Trigger job once.
+     * @param jobName job name
+     */
+    @PostMapping("/trigger")
+    public void trigger(@RequestBody final String jobName) {
+        Optional<CloudJobConfigurationPOJO> config = configService.load(jobName);
+        if (config.isPresent() && CloudJobExecutionType.DAEMON == config.get().getJobExecutionType()) {
+            throw new JobSystemException("Daemon job '%s' cannot support trigger.", jobName);
+        }
+        facadeService.addTransient(jobName);
+    }
+    
+    /**
+     * Query job detail.
+     * @param jobName job name
+     * @return the job detail
+     */
+    @GetMapping("/jobs/{jobName}")
+    public CloudJobConfigurationPOJO detail(@PathVariable("jobName") final String jobName) {
+        Optional<CloudJobConfigurationPOJO> cloudJobConfig = configService.load(jobName);
+        return cloudJobConfig.orElse(null);
+    }
+    
+    /**
+     * Find all jobs.
+     * @return all jobs
+     */
+    @GetMapping("/jobs")
+    public Collection<CloudJobConfigurationPOJO> findAllJobs() {
+        return configService.loadAll();
+    }
+    
+    /**
+     * Find all running tasks.
+     * @return all running tasks
+     */
+    @GetMapping("tasks/running")
+    public Collection<TaskContext> findAllRunningTasks() {
+        List<TaskContext> result = new LinkedList<>();
+        for (Set<TaskContext> each : facadeService.getAllRunningTasks().values()) {
+            result.addAll(each);
+        }
+        return result;
+    }
+    
+    /**
+     * Find all ready tasks.
+     * @return collection of all ready tasks
+     */
+    @GetMapping("tasks/ready")
+    public Collection<Map<String, String>> findAllReadyTasks() {
+        Map<String, Integer> readyTasks = facadeService.getAllReadyTasks();
+        List<Map<String, String>> result = new ArrayList<>(readyTasks.size());
+        for (Entry<String, Integer> each : readyTasks.entrySet()) {
+            Map<String, String> oneTask = new HashMap<>(2, 1);
+            oneTask.put("jobName", each.getKey());
+            oneTask.put("times", String.valueOf(each.getValue()));
+            result.add(oneTask);
+        }
+        return result;
+    }
+    
+    /**
+     * Find all failover tasks.
+     * @return collection of all the failover tasks
+     */
+    @GetMapping("tasks/failover")
+    public Collection<FailoverTaskInfo> findAllFailoverTasks() {
+        List<FailoverTaskInfo> result = new LinkedList<>();
+        for (Collection<FailoverTaskInfo> each : facadeService.getAllFailoverTasks().values()) {
+            result.addAll(each);
+        }
+        return result;
+    }
+    
+    /**
+     * Find job execution events.
+     * @param requestParams request params
+     * @return job execution event
+     * @throws ParseException parse exception
+     */
+    @GetMapping("events/executions")
+    public JobEventRdbSearch.Result<JobExecutionEvent> findJobExecutionEvents(@RequestParam final MultiValueMap<String, String> requestParams) throws ParseException {
+        if (!isRdbConfigured()) {
+            return new JobEventRdbSearch.Result<>(0, Collections.<JobExecutionEvent>emptyList());
+        }
+        return jobEventRdbSearch.findJobExecutionEvents(buildCondition(requestParams, new String[]{"jobName", "taskId", "ip", "isSuccess"}));
+    }
+    
+    /**
+     * Find job status trace events.
+     * @param requestParams request params
+     * @return job status trace event
+     * @throws ParseException parse exception
+     */
+    @GetMapping("events/statusTraces")
+    public JobEventRdbSearch.Result<JobStatusTraceEvent> findJobStatusTraceEvents(@RequestParam final MultiValueMap<String, String> requestParams) throws ParseException {
+        if (!isRdbConfigured()) {
+            return new JobEventRdbSearch.Result<>(0, Collections.<JobStatusTraceEvent>emptyList());
+        }
+        return jobEventRdbSearch.findJobStatusTraceEvents(buildCondition(requestParams, new String[]{"jobName", "taskId", "slaveId", "source", "executionType", "state"}));
+    }
+    
+    private boolean isRdbConfigured() {
+        return null != jobEventRdbSearch;
+    }
+    
+    private JobEventRdbSearch.Condition buildCondition(final MultiValueMap<String, String> requestParams, final String[] params) throws ParseException {
+        int perPage = 10;
+        int page = 1;
+        if (!Strings.isNullOrEmpty(requestParams.getFirst("per_page"))) {
+            perPage = Integer.parseInt(requestParams.getFirst("per_page"));
+        }
+        if (!Strings.isNullOrEmpty(requestParams.getFirst("page"))) {
+            page = Integer.parseInt(requestParams.getFirst("page"));
+        }
+        String sort = requestParams.getFirst("sort");
+        String order = requestParams.getFirst("order");
+        Date startTime = null;
+        Date endTime = null;
+        Map<String, Object> fields = getQueryParameters(requestParams, params);
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        if (!Strings.isNullOrEmpty(requestParams.getFirst("startTime"))) {
+            startTime = simpleDateFormat.parse(requestParams.getFirst("startTime"));
+        }
+        if (!Strings.isNullOrEmpty(requestParams.getFirst("endTime"))) {
+            endTime = simpleDateFormat.parse(requestParams.getFirst("endTime"));
+        }
+        return new JobEventRdbSearch.Condition(perPage, page, sort, order, startTime, endTime, fields);
+    }
+    
+    private Map<String, Object> getQueryParameters(final MultiValueMap<String, String> requestParams, final String[] params) {
+        final Map<String, Object> result = new HashMap<>();
+        for (String each : params) {
+            if (!Strings.isNullOrEmpty(requestParams.getFirst(each))) {
+                result.put(each, requestParams.getFirst(each));
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Find task result statistics.
+     * @param since time span
+     * @return task result statistics
+     */
+    @GetMapping("/statistics/tasks/results")
+    public List<TaskResultStatistics> findTaskResultStatistics(@RequestParam(value = "since", required = false) final String since) {
+        if ("last24hours".equals(since)) {
+            return statisticManager.findTaskResultStatisticsDaily();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+    
+    /**
+     * Get task result statistics.
+     * @param period time period
+     * @return task result statistics
+     */
+    @GetMapping("/statistics/tasks/results/{period}")
+    public TaskResultStatistics getTaskResultStatistics(@PathVariable(value = "period", required = false) final String period) {
+        switch (period) {
+            case "online":
+                return statisticManager.getTaskResultStatisticsSinceOnline();
+            case "lastWeek":
+                return statisticManager.getTaskResultStatisticsWeekly();
+            case "lastHour":
+                return statisticManager.findLatestTaskResultStatistics(StatisticInterval.HOUR);
+            case "lastMinute":
+                return statisticManager.findLatestTaskResultStatistics(StatisticInterval.MINUTE);
+            default:
+                return new TaskResultStatistics(0, 0, StatisticInterval.DAY, new Date());
+        }
+    }
+    
+    /**
+     * Find task running statistics.
+     * @param since time span
+     * @return task result statistics
+     */
+    @GetMapping("/statistics/tasks/running")
+    public List<TaskRunningStatistics> findTaskRunningStatistics(@RequestParam(value = "since", required = false) final String since) {
+        if ("lastWeek".equals(since)) {
+            return statisticManager.findTaskRunningStatisticsWeekly();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+    
+    /**
+     * Get job execution type statistics.
+     * @return job execution statistics
+     */
+    @GetMapping("/statistics/jobs/executionType")
+    public JobExecutionTypeStatistics getJobExecutionTypeStatistics() {
+        return statisticManager.getJobExecutionTypeStatistics();
+    }
+    
+    /**
+     * Find job running statistics in the recent week.
+     * @param since time span
+     * @return collection of job running statistics in the recent week
+     */
+    @GetMapping("/statistics/jobs/running")
+    public List<JobRunningStatistics> findJobRunningStatistics(@RequestParam(value = "since", required = false) final String since) {
+        if ("lastWeek".equals(since)) {
+            return statisticManager.findJobRunningStatisticsWeekly();
+        } else {
+            return Collections.emptyList();
+        }
+    }
+    
+    /**
+     * Find job register statistics.
+     * @return collection of job register statistics since online
+     */
+    @GetMapping("/statistics/jobs/register")
+    public List<JobRegisterStatistics> findJobRegisterStatistics() {
+        return statisticManager.findJobRegisterStatisticsSinceOnline();
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudOperationController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudOperationController.java
new file mode 100644
index 0000000..bb26629
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/CloudOperationController.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.MesosStateService;
+import org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.ReconcileService;
+import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.codehaus.jettison.json.JSONException;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Cloud operation restful api.
+ */
+@Slf4j
+@RestController
+@RequestMapping("/api/operate")
+public final class CloudOperationController {
+    
+    private static ReconcileService reconcileService;
+    
+    private static final long RECONCILE_MILLIS_INTERVAL = 10 * 1000L;
+    
+    private static MesosStateService mesosStateService;
+    
+    private static long lastReconcileTime;
+    
+    /**
+     * Init.
+     * @param regCenter        registry center
+     * @param reconcileService reconcile service
+     */
+    public static void init(final CoordinatorRegistryCenter regCenter, final ReconcileService reconcileService) {
+        CloudOperationController.reconcileService = reconcileService;
+        CloudOperationController.mesosStateService = new MesosStateService(regCenter);
+    }
+    
+    /**
+     * Explicit reconcile service.
+     */
+    @PostMapping("/reconcile/explicit")
+    public void explicitReconcile() {
+        validReconcileInterval();
+        reconcileService.explicitReconcile();
+    }
+    
+    /**
+     * Implicit reconcile service.
+     */
+    @PostMapping("/reconcile/implicit")
+    public void implicitReconcile() {
+        validReconcileInterval();
+        reconcileService.implicitReconcile();
+    }
+    
+    private void validReconcileInterval() {
+        if (System.currentTimeMillis() < lastReconcileTime + RECONCILE_MILLIS_INTERVAL) {
+            throw new RuntimeException("Repeat explicitReconcile");
+        }
+        lastReconcileTime = System.currentTimeMillis();
+    }
+    
+    /**
+     * Get sandbox of the cloud job by app name.
+     * @param appName application name
+     * @return sandbox info
+     * @throws JSONException parse json exception
+     */
+    @GetMapping("/sandbox")
+    public Collection<Map<String, String>> sandbox(@RequestParam("appName") final String appName) throws JSONException {
+        Preconditions.checkArgument(!Strings.isNullOrEmpty(appName), "Lack param 'appName'");
+        return mesosStateService.sandbox(appName);
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceDataSourceController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceDataSourceController.java
deleted file mode 100644
index e80ecd7..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceDataSourceController.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.EventTraceDataSourceFactory;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceDataSourceConfigurationService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.util.SessionEventTraceDataSourceConfiguration;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-import java.util.Collection;
-
-/**
- * Event trace data source RESTful API.
- */
-@RestController
-@RequestMapping("/api/data-source")
-public final class EventTraceDataSourceController {
-    
-    public static final String DATA_SOURCE_CONFIG_KEY = "data_source_config_key";
-    
-    private EventTraceDataSourceConfigurationService eventTraceDataSourceConfigurationService;
-    
-    @Autowired
-    public EventTraceDataSourceController(final EventTraceDataSourceConfigurationService eventTraceDataSourceConfigurationService) {
-        this.eventTraceDataSourceConfigurationService = eventTraceDataSourceConfigurationService;
-    }
-    
-    /**
-     * Judge whether event trace data source is activated.
-     *
-     * @param request HTTP request
-     * @return event trace data source is activated or not
-     */
-    @GetMapping("/activated")
-    public boolean activated(final HttpServletRequest request) {
-        return eventTraceDataSourceConfigurationService.loadActivated().isPresent();
-    }
-    
-    /**
-     * Load event trace data source configuration.
-     *
-     * @param request HTTP request
-     * @return event trace data source configurations
-     */
-    @GetMapping("/load")
-    public ResponseResult<Collection<EventTraceDataSourceConfiguration>> load(final HttpServletRequest request) {
-        eventTraceDataSourceConfigurationService.loadActivated().ifPresent(eventTraceDataSourceConfig -> setDataSourceNameToSession(eventTraceDataSourceConfig, request.getSession()));
-        return ResponseResultUtil.build(eventTraceDataSourceConfigurationService.loadAll().getEventTraceDataSourceConfiguration());
-    }
-    
-    /**
-     * Add event trace data source configuration.
-     *
-     * @param config event trace data source configuration
-     * @return success to added or not
-     */
-    @PostMapping("/add")
-    public ResponseResult<Boolean> add(@RequestBody final EventTraceDataSourceConfiguration config) {
-        return ResponseResultUtil.build(eventTraceDataSourceConfigurationService.add(config));
-    }
-    
-    /**
-     * Delete event trace data source configuration.
-     *
-     * @param config event trace data source configuration
-     */
-    @DeleteMapping
-    public ResponseResult delete(@RequestBody final EventTraceDataSourceConfiguration config) {
-        eventTraceDataSourceConfigurationService.delete(config.getName());
-        return ResponseResultUtil.success();
-    }
-    
-    /**
-     * Test event trace data source connection.
-     *
-     * @param config  event trace data source configuration
-     * @param request HTTP request
-     * @return success or not
-     */
-    @PostMapping(value = "/connectTest")
-    public ResponseResult<Boolean> connectTest(@RequestBody final EventTraceDataSourceConfiguration config, final HttpServletRequest request) {
-        return ResponseResultUtil.build(setDataSourceNameToSession(config, request.getSession()));
-    }
-    
-    /**
-     * Connect event trace data source.
-     *
-     * @param config  event trace data source
-     * @param request HTTP request
-     * @return success or not
-     */
-    @PostMapping(value = "/connect")
-    public ResponseResult<Boolean> connect(@RequestBody final EventTraceDataSourceConfiguration config, final HttpServletRequest request) {
-        boolean isConnected = setDataSourceNameToSession(eventTraceDataSourceConfigurationService.find(config.getName(), eventTraceDataSourceConfigurationService.loadAll()), request.getSession());
-        if (isConnected) {
-            eventTraceDataSourceConfigurationService.load(config.getName());
-        }
-        return ResponseResultUtil.build(isConnected);
-    }
-    
-    private boolean setDataSourceNameToSession(final EventTraceDataSourceConfiguration dataSourceConfig, final HttpSession session) {
-        session.setAttribute(DATA_SOURCE_CONFIG_KEY, dataSourceConfig);
-        try {
-            EventTraceDataSourceFactory.createEventTraceDataSource(dataSourceConfig.getDriver(), dataSourceConfig.getUrl(), dataSourceConfig.getUsername(), dataSourceConfig.getPassword());
-            SessionEventTraceDataSourceConfiguration.setDataSourceConfiguration((EventTraceDataSourceConfiguration) session.getAttribute(DATA_SOURCE_CONFIG_KEY));
-        // CHECKSTYLE:OFF
-        } catch (final Exception ex) {
-        // CHECKSTYLE:ON
-            return false;
-        }
-        return true;
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceHistoryController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceHistoryController.java
deleted file mode 100644
index ad61d01..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/EventTraceHistoryController.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
-
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobExecutionEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobStatusTraceEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.response.BasePageResponse;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceHistoryService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.domain.Page;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Event trace history RESTful API.
- */
-@RestController
-@RequestMapping("/api/event-trace")
-public final class EventTraceHistoryController {
-    
-    @Autowired
-    private EventTraceHistoryService eventTraceHistoryService;
-    
-    /**
-     * Find job execution events.
-     *
-     * @param requestParams query criteria
-     * @return job execution event trace result
-     */
-    @PostMapping(value = "/execution")
-    public ResponseResult<BasePageResponse<JobExecutionEvent>> findJobExecutionEvents(@RequestBody final FindJobExecutionEventsRequest requestParams) {
-        Page<JobExecutionEvent> jobExecutionEvents = eventTraceHistoryService.findJobExecutionEvents(requestParams);
-        return ResponseResultUtil.build(BasePageResponse.of(jobExecutionEvents));
-    }
-    
-    /**
-     * Find job status trace events.
-     *
-     * @param requestParams query criteria
-     * @return job status trace result
-     */
-    @PostMapping(value = "/status")
-    public ResponseResult<BasePageResponse<JobStatusTraceEvent>> findJobStatusTraceEvents(@RequestBody final FindJobStatusTraceEventsRequest requestParams) {
-        Page<JobStatusTraceEvent> jobStatusTraceEvents = eventTraceHistoryService.findJobStatusTraceEvents(requestParams);
-        return ResponseResultUtil.build(BasePageResponse.of(jobStatusTraceEvents));
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobConfigController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobConfigController.java
deleted file mode 100644
index eb97314..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobConfigController.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.JobAPIService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
-import org.apache.shardingsphere.elasticjob.infra.pojo.JobConfigurationPOJO;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * Job configuration RESTful API.
- */
-@RestController
-@RequestMapping("/api/jobs/config")
-public final class JobConfigController {
-    
-    private JobAPIService jobAPIService;
-    
-    @Autowired
-    public JobConfigController(final JobAPIService jobAPIService) {
-        this.jobAPIService = jobAPIService;
-    }
-    
-    /**
-     * Get job configuration.
-     *
-     * @param jobName job name
-     * @return job configuration
-     */
-    @GetMapping(value = "/{jobName}")
-    public ResponseResult<JobConfigurationPOJO> getJobConfig(@PathVariable("jobName") final String jobName) {
-        JobConfigurationPOJO data = jobAPIService.getJobConfigurationAPI().getJobConfiguration(jobName);
-        return ResponseResultUtil.build(data);
-    }
-    
-    /**
-     * Update job configuration.
-     *
-     * @param jobConfiguration job configuration
-     */
-    @PutMapping
-    public ResponseResult<Boolean> updateJobConfig(@RequestBody final JobConfigurationPOJO jobConfiguration) {
-        jobAPIService.getJobConfigurationAPI().updateJobConfiguration(jobConfiguration);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Remove job configuration.
-     *
-     * @param jobName job name
-     */
-    @DeleteMapping("/{jobName}")
-    public ResponseResult<Boolean> removeJob(@PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobConfigurationAPI().removeJobConfiguration(jobName);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobOperationController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobOperationController.java
deleted file mode 100644
index df618cc..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/JobOperationController.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
-
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.domain.JobBriefInfo;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.domain.ShardingInfo;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.JobAPIService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.Collection;
-
-/**
- * Job operation RESTful API.
- */
-@RestController
-@RequestMapping("/api/jobs")
-public final class JobOperationController {
-    
-    private JobAPIService jobAPIService;
-    
-    @Autowired
-    public JobOperationController(final JobAPIService jobAPIService) {
-        this.jobAPIService = jobAPIService;
-    }
-    
-    /**
-     * Get jobs total count.
-     * 
-     * @return jobs total count
-     */
-    @GetMapping("/count")
-    public int getJobsTotalCount() {
-        return jobAPIService.getJobStatisticsAPI().getJobsTotalCount();
-    }
-    
-    /**
-     * Get all jobs brief info.
-     * 
-     * @return all jobs brief info
-     */
-    @GetMapping("/getAllJobsBriefInfo")
-    public ResponseResult<Collection<JobBriefInfo>> getAllJobsBriefInfo() {
-        Collection<JobBriefInfo> data = jobAPIService.getJobStatisticsAPI().getAllJobsBriefInfo();
-        return ResponseResultUtil.build(data);
-    }
-    
-    /**
-     * Trigger job.
-     * 
-     * @param jobName job name
-     */
-    @PostMapping("/{jobName}/trigger")
-    public ResponseResult<Boolean> triggerJob(@PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().trigger(jobName);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Disable job.
-     * 
-     * @param jobName job name
-     */
-    @PostMapping(value = "/{jobName}/disable")
-    public ResponseResult<Boolean> disableJob(@PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().disable(jobName, null);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Enable job.
-     *
-     * @param jobName job name
-     */
-    @PostMapping(value = "/{jobName}/enable")
-    public ResponseResult<Boolean> enableJob(@PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().enable(jobName, null);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Shutdown job.
-     * 
-     * @param jobName job name
-     */
-    @PostMapping(value = "/{jobName}/shutdown")
-    public ResponseResult<Boolean> shutdownJob(@PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().shutdown(jobName, null);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Get sharding info.
-     * 
-     * @param jobName job name
-     * @return sharding info
-     */
-    @GetMapping(value = "/{jobName}/sharding")
-    public ResponseResult<Collection<ShardingInfo>> getShardingInfo(@PathVariable("jobName") final String jobName) {
-        Collection<ShardingInfo> data =  jobAPIService.getShardingStatisticsAPI().getShardingInfo(jobName);
-        return ResponseResultUtil.build(data);
-    }
-    
-    /**
-     * Disable sharding.
-     *
-     * @param jobName job name
-     * @param item sharding item
-     */
-    @PostMapping(value = "/{jobName}/sharding/{item}/disable")
-    public ResponseResult<Boolean> disableSharding(@PathVariable("jobName") final String jobName, @PathVariable("item") final String item) {
-        jobAPIService.getShardingOperateAPI().disable(jobName, item);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Enable sharding.
-     *
-     * @param jobName job name
-     * @param item sharding item
-     */
-    @PostMapping(value = "/{jobName}/sharding/{item}/enable")
-    public ResponseResult<Boolean> enableSharding(@PathVariable("jobName") final String jobName, @PathVariable("item") final String item) {
-        jobAPIService.getShardingOperateAPI().enable(jobName, item);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/RegistryCenterController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/RegistryCenterController.java
index 7f52a9c..a198fc8 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/RegistryCenterController.java
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/RegistryCenterController.java
@@ -17,13 +17,13 @@
 
 package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
 
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.internal.reg.RegistryCenterFactory;
-import org.apache.shardingsphere.elasticjob.reg.exception.RegException;
 import org.apache.shardingsphere.elasticjob.cloud.ui.domain.RegistryCenterConfiguration;
 import org.apache.shardingsphere.elasticjob.cloud.ui.service.RegistryCenterConfigurationService;
+import org.apache.shardingsphere.elasticjob.cloud.ui.service.RegistryCenterFactory;
 import org.apache.shardingsphere.elasticjob.cloud.ui.util.SessionRegistryCenterConfiguration;
 import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
 import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
+import org.apache.shardingsphere.elasticjob.reg.exception.RegException;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.DeleteMapping;
 import org.springframework.web.bind.annotation.GetMapping;
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/ServerOperationController.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/ServerOperationController.java
deleted file mode 100644
index 436e71c..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/ServerOperationController.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller;
-
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.domain.JobBriefInfo;
-import org.apache.shardingsphere.elasticjob.lite.lifecycle.domain.ServerBriefInfo;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.JobAPIService;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResult;
-import org.apache.shardingsphere.elasticjob.cloud.ui.web.response.ResponseResultUtil;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.util.Collection;
-
-/**
- * Server operation RESTful API.
- */
-@RestController
-@RequestMapping("/api/servers")
-public final class ServerOperationController {
-    
-    private JobAPIService jobAPIService;
-    
-    @Autowired
-    public ServerOperationController(final JobAPIService jobAPIService) {
-        this.jobAPIService = jobAPIService;
-    }
-    
-    /**
-     * Get servers total count.
-     * 
-     * @return servers total count
-     */
-    @GetMapping("/count")
-    public int getServersTotalCount() {
-        return jobAPIService.getServerStatisticsAPI().getServersTotalCount();
-    }
-    
-    /**
-     * Get all servers brief info.
-     * 
-     * @return all servers brief info
-     */
-    @GetMapping("/getAllServersBriefInfo")
-    public ResponseResult<Collection<ServerBriefInfo>> getAllServersBriefInfo() {
-        Collection<ServerBriefInfo> data = jobAPIService.getServerStatisticsAPI().getAllServersBriefInfo();
-        return ResponseResultUtil.build(data);
-    }
-    
-    /**
-     * Disable server.
-     *
-     * @param serverIp server IP address
-     */
-    @PostMapping("/{serverIp}/disable")
-    public ResponseResult<Boolean> disableServer(@PathVariable("serverIp") final String serverIp) {
-        jobAPIService.getJobOperatorAPI().disable(null, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Enable server.
-     *
-     * @param serverIp server IP address
-     */
-    @PostMapping("/{serverIp}/enable")
-    public ResponseResult<Boolean> enableServer(@PathVariable("serverIp") final String serverIp) {
-        jobAPIService.getJobOperatorAPI().enable(null, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Shutdown server.
-     *
-     * @param serverIp server IP address
-     */
-    @PostMapping("/{serverIp}/shutdown")
-    public ResponseResult<Boolean> shutdownServer(@PathVariable("serverIp") final String serverIp) {
-        jobAPIService.getJobOperatorAPI().shutdown(null, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Remove server.
-     *
-     * @param serverIp server IP address
-     */
-    @DeleteMapping("/{serverIp}")
-    public ResponseResult<Boolean> removeServer(@PathVariable("serverIp") final String serverIp) {
-        jobAPIService.getJobOperatorAPI().remove(null, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Get jobs.
-     *
-     * @param serverIp server IP address
-     * @return Job brief info
-     */
-    @GetMapping(value = "/{serverIp}/jobs")
-    public ResponseResult<Collection<JobBriefInfo>> getJobs(@PathVariable("serverIp") final String serverIp) {
-        Collection<JobBriefInfo> data = jobAPIService.getJobStatisticsAPI().getJobsBriefInfo(serverIp);
-        return ResponseResultUtil.build(data);
-    }
-    
-    /**
-     * Disable server job.
-     * 
-     * @param serverIp server IP address
-     * @param jobName job name
-     */
-    @PostMapping(value = "/{serverIp}/jobs/{jobName}/disable")
-    public ResponseResult<Boolean> disableServerJob(@PathVariable("serverIp") final String serverIp, @PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().disable(jobName, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Enable server job.
-     *
-     * @param serverIp server IP address
-     * @param jobName job name
-     */
-    @PostMapping("/{serverIp}/jobs/{jobName}/enable")
-    public ResponseResult<Boolean> enableServerJob(@PathVariable("serverIp") final String serverIp, @PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().enable(jobName, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Shutdown server job.
-     *
-     * @param serverIp server IP address
-     * @param jobName job name
-     */
-    @PostMapping("/{serverIp}/jobs/{jobName}/shutdown")
-    public ResponseResult<Boolean> shutdownServerJob(@PathVariable("serverIp") final String serverIp, @PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().shutdown(jobName, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-    
-    /**
-     * Remove server job.
-     *
-     * @param serverIp server IP address
-     * @param jobName job name
-     */
-    @DeleteMapping("/{serverIp}/jobs/{jobName}")
-    public ResponseResult<Boolean> removeServerJob(@PathVariable("serverIp") final String serverIp, @PathVariable("jobName") final String jobName) {
-        jobAPIService.getJobOperatorAPI().remove(jobName, serverIp);
-        return ResponseResultUtil.build(Boolean.TRUE);
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/search/JobEventRdbSearch.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/search/JobEventRdbSearch.java
new file mode 100644
index 0000000..2bed5d4
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/web/controller/search/JobEventRdbSearch.java
@@ -0,0 +1,297 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *  
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.elasticjob.cloud.ui.web.controller.search;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Strings;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
+import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Job event RDB search.
+ */
+@RequiredArgsConstructor
+@Slf4j
+public final class JobEventRdbSearch {
+    
+    private static final String TABLE_JOB_EXECUTION_LOG = "JOB_EXECUTION_LOG";
+    
+    private static final String TABLE_JOB_STATUS_TRACE_LOG = "JOB_STATUS_TRACE_LOG";
+    
+    private static final List<String> FIELDS_JOB_EXECUTION_LOG = 
+            Arrays.asList("id", "hostname", "ip", "task_id", "job_name", "execution_source", "sharding_item", "start_time", "complete_time", "is_success", "failure_cause");
+    
+    private static final List<String> FIELDS_JOB_STATUS_TRACE_LOG = 
+            Arrays.asList("id", "job_name", "original_task_id", "task_id", "slave_id", "source", "execution_type", "sharding_item", "state", "message", "creation_time");
+    
+    private final DataSource dataSource;
+
+    /**
+     * Find job execution events.
+     *
+     * @param condition query condition
+     * @return job execution events
+     */
+    public Result<JobExecutionEvent> findJobExecutionEvents(final Condition condition) {
+        return new Result<>(getEventCount(TABLE_JOB_EXECUTION_LOG, FIELDS_JOB_EXECUTION_LOG, condition), getJobExecutionEvents(condition));
+    }
+
+    /**
+     * Find job status trace events.
+     *
+     * @param condition query condition
+     * @return job status trace events
+     */
+    public Result<JobStatusTraceEvent> findJobStatusTraceEvents(final Condition condition) {
+        return new Result<>(getEventCount(TABLE_JOB_STATUS_TRACE_LOG, FIELDS_JOB_STATUS_TRACE_LOG, condition), getJobStatusTraceEvents(condition));
+    }
+    
+    private List<JobExecutionEvent> getJobExecutionEvents(final Condition condition) {
+        List<JobExecutionEvent> result = new LinkedList<>();
+        try (
+                Connection conn = dataSource.getConnection();
+                PreparedStatement preparedStatement = createDataPreparedStatement(conn, TABLE_JOB_EXECUTION_LOG, FIELDS_JOB_EXECUTION_LOG, condition);
+                ResultSet resultSet = preparedStatement.executeQuery()
+                ) {
+            while (resultSet.next()) {
+                JobExecutionEvent jobExecutionEvent = new JobExecutionEvent(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4),
+                        resultSet.getString(5), JobExecutionEvent.ExecutionSource.valueOf(resultSet.getString(6)), Integer.valueOf(resultSet.getString(7)),
+                        new Date(resultSet.getTimestamp(8).getTime()), resultSet.getTimestamp(9) == null ? null : new Date(resultSet.getTimestamp(9).getTime()), 
+                        resultSet.getBoolean(10), resultSet.getString(11));
+                result.add(jobExecutionEvent);
+            }
+        } catch (final SQLException ex) {
+            // TODO log failure directly to output log, consider to be configurable in the future
+            log.error("Fetch JobExecutionEvent from DB error:", ex);
+        }
+        return result;
+    }
+    
+    private List<JobStatusTraceEvent> getJobStatusTraceEvents(final Condition condition) {
+        List<JobStatusTraceEvent> result = new LinkedList<>();
+        try (
+                Connection conn = dataSource.getConnection();
+                PreparedStatement preparedStatement = createDataPreparedStatement(conn, TABLE_JOB_STATUS_TRACE_LOG, FIELDS_JOB_STATUS_TRACE_LOG, condition);
+                ResultSet resultSet = preparedStatement.executeQuery()
+                ) {
+            while (resultSet.next()) {
+                JobStatusTraceEvent jobStatusTraceEvent = new JobStatusTraceEvent(resultSet.getString(1), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4),
+                        resultSet.getString(5), JobStatusTraceEvent.Source.valueOf(resultSet.getString(6)), resultSet.getString(7), resultSet.getString(8),
+                        JobStatusTraceEvent.State.valueOf(resultSet.getString(9)), resultSet.getString(10), new Date(resultSet.getTimestamp(11).getTime()));
+                result.add(jobStatusTraceEvent);
+            }
+        } catch (final SQLException ex) {
+            // TODO log failure directly to output log, consider to be configurable in the future
+            log.error("Fetch JobStatusTraceEvent from DB error:", ex);
+        }
+        return result;
+    }
+    
+    private int getEventCount(final String tableName, final Collection<String> tableFields, final Condition condition) {
+        int result = 0;
+        try (
+                Connection conn = dataSource.getConnection();
+                PreparedStatement preparedStatement = createCountPreparedStatement(conn, tableName, tableFields, condition);
+                ResultSet resultSet = preparedStatement.executeQuery()
+                ) {
+            resultSet.next();
+            result = resultSet.getInt(1);
+        } catch (final SQLException ex) {
+            // TODO log failure directly to output log, consider to be configurable in the future
+            log.error("Fetch EventCount from DB error:", ex);
+        }
+        return result;
+    }
+    
+    private PreparedStatement createDataPreparedStatement(final Connection conn, final String tableName, final Collection<String> tableFields, final Condition condition) throws SQLException {
+        String sql = buildDataSql(tableName, tableFields, condition);
+        PreparedStatement preparedStatement = conn.prepareStatement(sql);
+        setBindValue(preparedStatement, tableFields, condition);
+        return preparedStatement;
+    }
+    
+    private PreparedStatement createCountPreparedStatement(final Connection conn, final String tableName, final Collection<String> tableFields, final Condition condition) throws SQLException {
+        String sql = buildCountSql(tableName, tableFields, condition);
+        PreparedStatement preparedStatement = conn.prepareStatement(sql);
+        setBindValue(preparedStatement, tableFields, condition);
+        return preparedStatement;
+    }
+    
+    private String buildDataSql(final String tableName, final Collection<String> tableFields, final Condition condition) {
+        StringBuilder sqlBuilder = new StringBuilder();
+        String selectSql = buildSelect(tableName, tableFields);
+        String whereSql = buildWhere(tableName, tableFields, condition);
+        String orderSql = buildOrder(tableFields, condition.getSort(), condition.getOrder());
+        String limitSql = buildLimit(condition.getPage(), condition.getPerPage());
+        sqlBuilder.append(selectSql).append(whereSql).append(orderSql).append(limitSql);
+        return sqlBuilder.toString();
+    }
+    
+    private String buildCountSql(final String tableName, final Collection<String> tableFields, final Condition condition) {
+        StringBuilder sqlBuilder = new StringBuilder();
+        String selectSql = buildSelectCount(tableName);
+        String whereSql = buildWhere(tableName, tableFields, condition);
+        sqlBuilder.append(selectSql).append(whereSql);
+        return sqlBuilder.toString();
+    }
+    
+    private String buildSelectCount(final String tableName) {
+        return String.format("SELECT COUNT(1) FROM %s", tableName);
+    }
+    
+    private String buildSelect(final String tableName, final Collection<String> tableFields) {
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append("SELECT ");
+        for (String each : tableFields) {
+            sqlBuilder.append(each).append(",");
+        }
+        sqlBuilder.deleteCharAt(sqlBuilder.length() - 1);
+        sqlBuilder.append(" FROM ").append(tableName);
+        return sqlBuilder.toString();
+    }
+    
+    private String buildWhere(final String tableName, final Collection<String> tableFields, final Condition condition) {
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append(" WHERE 1=1");
+        if (null != condition.getFields() && !condition.getFields().isEmpty()) {
+            for (Map.Entry<String, Object> entry : condition.getFields().entrySet()) {
+                String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
+                if (null != entry.getValue() && tableFields.contains(lowerUnderscore)) {
+                    sqlBuilder.append(" AND ").append(lowerUnderscore).append("=?");
+                }
+            }
+        }
+        if (null != condition.getStartTime()) {
+            sqlBuilder.append(" AND ").append(getTableTimeField(tableName)).append(">=?");
+        }
+        if (null != condition.getEndTime()) {
+            sqlBuilder.append(" AND ").append(getTableTimeField(tableName)).append("<=?");
+        }
+        return sqlBuilder.toString();
+    }
+    
+    private void setBindValue(final PreparedStatement preparedStatement, final Collection<String> tableFields, final Condition condition) throws SQLException {
+        int index = 1;
+        if (null != condition.getFields() && !condition.getFields().isEmpty()) {
+            for (Map.Entry<String, Object> entry : condition.getFields().entrySet()) {
+                String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, entry.getKey());
+                if (null != entry.getValue() && tableFields.contains(lowerUnderscore)) {
+                    preparedStatement.setString(index++, String.valueOf(entry.getValue()));
+                }
+            }
+        }
+        if (null != condition.getStartTime()) {
+            preparedStatement.setTimestamp(index++, new Timestamp(condition.getStartTime().getTime()));
+        }
+        if (null != condition.getEndTime()) {
+            preparedStatement.setTimestamp(index, new Timestamp(condition.getEndTime().getTime()));
+        }
+    }
+    
+    private String getTableTimeField(final String tableName) {
+        String result = "";
+        if (TABLE_JOB_EXECUTION_LOG.equals(tableName)) {
+            result = "start_time";
+        } else if (TABLE_JOB_STATUS_TRACE_LOG.equals(tableName)) {
+            result = "creation_time";
+        }
+        return result;
+    }
+    
+    private String buildOrder(final Collection<String> tableFields, final String sortName, final String sortOrder) {
+        if (Strings.isNullOrEmpty(sortName)) {
+            return "";
+        }
+        String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, sortName);
+        if (!tableFields.contains(lowerUnderscore)) {
+            return "";
+        }
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append(" ORDER BY ").append(lowerUnderscore);
+        switch (sortOrder.toUpperCase()) {
+            case "ASC":
+                sqlBuilder.append(" ASC");
+                break;
+            case "DESC":
+                sqlBuilder.append(" DESC");
+                break;
+            default :
+                sqlBuilder.append(" ASC");
+        }
+        return sqlBuilder.toString();
+    }
+    
+    private String buildLimit(final int page, final int perPage) {
+        StringBuilder sqlBuilder = new StringBuilder();
+        if (page > 0 && perPage > 0) {
+            sqlBuilder.append(" LIMIT ").append((page - 1) * perPage).append(",").append(perPage);
+        } else {
+            sqlBuilder.append(" LIMIT ").append(Condition.DEFAULT_PAGE_SIZE);
+        }
+        return sqlBuilder.toString();
+    }
+
+    /**
+     * Query condition.
+     */
+    @RequiredArgsConstructor
+    @Getter
+    public static class Condition {
+        
+        private static final int DEFAULT_PAGE_SIZE = 10;
+        
+        private final int perPage;
+        
+        private final int page;
+        
+        private final String sort;
+        
+        private final String order;
+        
+        private final Date startTime;
+        
+        private final Date endTime;
+        
+        private final Map<String, Object> fields;
+    }
+    
+    @RequiredArgsConstructor
+    @Getter
+    public static class Result<T> {
+        
+        private final Integer total;
+        
+        private final List<T> rows;
+    }
+}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/resources/conf/elasticjob-cloud-scheduler.properties b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/resources/conf/elasticjob-cloud-scheduler.properties
new file mode 100644
index 0000000..86a85b9
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/resources/conf/elasticjob-cloud-scheduler.properties
@@ -0,0 +1,19 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Max size of job accumulated
+job_state_queue_size=10000
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTest.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTest.java
deleted file mode 100644
index a205c93..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTest.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.search;
-
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobExecutionEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobStatusTraceEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceHistoryService;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.Import;
-import org.springframework.data.domain.Page;
-import org.springframework.test.context.junit4.SpringRunner;
-
-import java.util.Date;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertThat;
-
-@RunWith(SpringRunner.class)
-@SpringBootTest
-@Import(RDBJobEventSearchTestConfiguration.class)
-public final class RDBJobEventSearchTest {
-    
-    @Autowired
-    private EventTraceHistoryService eventTraceHistoryService;
-    
-    @Test
-    public void assertFindJobExecutionEventsWithPageSizeAndNumber() {
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest());
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(50, 1));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(50));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(100, 5));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(100));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(100, 6));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(0));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithErrorPageSizeAndNumber() {
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(-1, -1, null, null, null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithSort() {
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, "jobName", "ASC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_1"));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, "jobName", "DESC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_99"));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithErrorSort() {
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, "jobName", "ERROR_SORT", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_1"));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, "notExistField", "ASC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithTime() {
-        Date now = new Date();
-        Date tenMinutesBefore = new Date(now.getTime() - 10 * 60 * 1000);
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, null, null, tenMinutesBefore, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, null, null, now, null));
-        assertThat(result.getTotalElements(), is(0L));
-        assertThat(result.getContent().size(), is(0));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, null, null, null, tenMinutesBefore));
-        assertThat(result.getTotalElements(), is(0L));
-        assertThat(result.getContent().size(), is(0));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, null, null, null, now));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1, null, null, tenMinutesBefore, now));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithFields() {
-        FindJobExecutionEventsRequest findJobExecutionEventsRequest = new FindJobExecutionEventsRequest(10, 1, null, null, null, null);
-        findJobExecutionEventsRequest.setIsSuccess(true);
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(findJobExecutionEventsRequest);
-        assertThat(result.getTotalElements(), is(250L));
-        assertThat(result.getContent().size(), is(10));
-        findJobExecutionEventsRequest.setIsSuccess(null);
-        findJobExecutionEventsRequest.setJobName("test_job_1");
-        result = eventTraceHistoryService.findJobExecutionEvents(findJobExecutionEventsRequest);
-        assertThat(result.getTotalElements(), is(1L));
-        assertThat(result.getContent().size(), is(1));
-    }
-    
-    @Test
-    public void assertFindJobExecutionEventsWithErrorFields() {
-        Page<JobExecutionEvent> result = eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithPageSizeAndNumber() {
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(50, 1, null, null, null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(50));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(100, 5, null, null, null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(100));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(100, 6, null, null, null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(0));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithErrorPageSizeAndNumber() {
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(-1, -1));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithSort() {
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, "jobName", "ASC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_1"));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, "jobName", "DESC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_99"));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithErrorSort() {
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, "jobName", "ERROR_SORT", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        assertThat(result.getContent().get(0).getJobName(), is("test_job_1"));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, "notExistField", "ASC", null, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithTime() {
-        Date now = new Date();
-        Date tenMinutesBefore = new Date(now.getTime() - 10 * 60 * 1000);
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, tenMinutesBefore, null));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, now, null));
-        assertThat(result.getTotalElements(), is(0L));
-        assertThat(result.getContent().size(), is(0));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, null, tenMinutesBefore));
-        assertThat(result.getTotalElements(), is(0L));
-        assertThat(result.getContent().size(), is(0));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, null, now));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-        result = eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1, null, null, tenMinutesBefore, now));
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithFields() {
-        FindJobStatusTraceEventsRequest findJobStatusTraceEventsRequest = new FindJobStatusTraceEventsRequest(10, 1);
-        findJobStatusTraceEventsRequest.setJobName("test_job_1");
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(findJobStatusTraceEventsRequest);
-        assertThat(result.getTotalElements(), is(1L));
-        assertThat(result.getContent().size(), is(1));
-    }
-    
-    @Test
-    public void assertFindJobStatusTraceEventsWithErrorFields() {
-        FindJobStatusTraceEventsRequest findJobStatusTraceEventsRequest = new FindJobStatusTraceEventsRequest(10, 1);
-        Page<JobStatusTraceEvent> result = eventTraceHistoryService.findJobStatusTraceEvents(findJobStatusTraceEventsRequest);
-        assertThat(result.getTotalElements(), is(500L));
-        assertThat(result.getContent().size(), is(10));
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTestConfiguration.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTestConfiguration.java
deleted file mode 100644
index b50edd0..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/RDBJobEventSearchTestConfiguration.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.search;
-
-import org.apache.shardingsphere.elasticjob.tracing.event.JobExecutionEvent;
-import org.apache.shardingsphere.elasticjob.tracing.event.JobStatusTraceEvent;
-import org.apache.shardingsphere.elasticjob.tracing.rdb.storage.RDBJobEventStorage;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobExecutionEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dto.request.FindJobStatusTraceEventsRequest;
-import org.apache.shardingsphere.elasticjob.cloud.ui.service.EventTraceHistoryService;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.TestConfiguration;
-
-import javax.sql.DataSource;
-import java.sql.SQLException;
-
-@TestConfiguration
-public class RDBJobEventSearchTestConfiguration implements InitializingBean {
-    
-    @Autowired
-    private EventTraceHistoryService eventTraceHistoryService;
-    
-    @Autowired
-    private DataSource dataSource;
-    
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        initStorage();
-    }
-    
-    private void initStorage() throws SQLException {
-        eventTraceHistoryService.findJobExecutionEvents(new FindJobExecutionEventsRequest(10, 1));
-        eventTraceHistoryService.findJobStatusTraceEvents(new FindJobStatusTraceEventsRequest(10, 1));
-        RDBJobEventStorage storage = new RDBJobEventStorage(dataSource);
-        for (int i = 1; i <= 500L; i++) {
-            JobExecutionEvent startEvent = new JobExecutionEvent("localhost", "127.0.0.1", "fake_task_id", "test_job_" + i, JobExecutionEvent.ExecutionSource.NORMAL_TRIGGER, 0);
-            storage.addJobExecutionEvent(startEvent);
-            if (i % 2 == 0) {
-                JobExecutionEvent successEvent = startEvent.executionSuccess();
-                storage.addJobExecutionEvent(successEvent);
-            }
-            storage.addJobStatusTraceEvent(new JobStatusTraceEvent(
-                    "test_job_" + i,
-                    "fake_failed_failover_task_id",
-                    "fake_slave_id",
-                    JobStatusTraceEvent.Source.LITE_EXECUTOR,
-                    "FAILOVER",
-                    "0",
-                    JobStatusTraceEvent.State.TASK_FAILED,
-                    "message is empty."
-            ));
-        }
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/rdb/RDBStatisticRepositoryTest.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/rdb/RDBStatisticRepositoryTest.java
deleted file mode 100644
index d1e3fb6..0000000
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/test/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/statistics/rdb/RDBStatisticRepositoryTest.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *  
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.rdb;
-
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.JobRegisterStatisticsRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.JobRunningStatisticsRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.StatisticInterval;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.TaskResultStatisticsRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.dao.statistics.TaskRunningStatisticsRepository;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobRegisterStatistics;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobRunningStatistics;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.TaskResultStatistics;
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.TaskRunningStatistics;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-
-import java.util.Date;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.CoreMatchers.nullValue;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-@SpringBootTest
-@RunWith(SpringJUnit4ClassRunner.class)
-public class RDBStatisticRepositoryTest {
-    
-    @Autowired
-    private TaskResultStatisticsRepository taskResultStatisticsRepository;
-    
-    @Autowired
-    private TaskRunningStatisticsRepository taskRunningStatisticsRepository;
-    
-    @Autowired
-    private JobRegisterStatisticsRepository jobRegisterStatisticsRepository;
-    
-    @Autowired
-    private JobRunningStatisticsRepository jobRunningStatisticsRepository;
-    
-    @Test
-    public void assertAddTaskResultStatistics() {
-        for (StatisticInterval each : StatisticInterval.values()) {
-            TaskResultStatistics taskResultStatistics = new TaskResultStatistics(100L, 0L, each.name(), new Date());
-            assertTrue(taskResultStatistics.equals(taskResultStatisticsRepository.save(taskResultStatistics)));
-        }
-    }
-    
-    @Test
-    public void assertAddTaskRunningStatistics() {
-        TaskRunningStatistics taskRunningStatistics = new TaskRunningStatistics(100, new Date());
-        assertTrue(taskRunningStatistics.equals(taskRunningStatisticsRepository.save(taskRunningStatistics)));
-    }
-    
-    @Test
-    public void assertAddJobRunningStatistics() {
-        JobRunningStatistics jobRunningStatistics = new JobRunningStatistics(100, new Date());
-        assertTrue(jobRunningStatistics.equals(jobRunningStatisticsRepository.save(jobRunningStatistics)));
-    }
-    
-    @Test
-    public void assertAddJobRegisterStatistics() {
-        JobRegisterStatistics jobRegisterStatistics = new JobRegisterStatistics(100, new Date());
-        assertTrue(jobRegisterStatistics.equals(jobRegisterStatisticsRepository.save(jobRegisterStatistics)));
-    }
-    
-    @Test
-    public void assertFindTaskResultStatisticsWhenTableIsEmpty() {
-        Date now = new Date();
-        assertThat(taskResultStatisticsRepository.findTaskResultStatistics(now, StatisticInterval.MINUTE.name()).size(), is(0));
-        assertThat(taskResultStatisticsRepository.findTaskResultStatistics(now, StatisticInterval.HOUR.name()).size(), is(0));
-        assertThat(taskResultStatisticsRepository.findTaskResultStatistics(now, StatisticInterval.DAY.name()).size(), is(0));
-    }
-    
-    @Test
-    public void assertFindTaskResultStatisticsWithDifferentFromDate() {
-        Date now = new Date();
-        Date yesterday = getYesterday();
-        for (StatisticInterval each : StatisticInterval.values()) {
-            taskResultStatisticsRepository.save(new TaskResultStatistics(100L, 0L, each.name(), yesterday));
-            taskResultStatisticsRepository.save(new TaskResultStatistics(100L, 0L, each.name(), now));
-            assertThat(taskResultStatisticsRepository.findTaskResultStatistics(yesterday, each.name()).size(), is(2));
-            assertThat(taskResultStatisticsRepository.findTaskResultStatistics(now, each.name()).size(), is(1));
-        }
-    }
-    
-    @Test
-    public void assertGetSummedTaskResultStatisticsWhenTableIsEmpty() {
-        for (StatisticInterval each : StatisticInterval.values()) {
-            TaskResultStatistics po = taskResultStatisticsRepository.getSummedTaskResultStatistics(new Date(), each.name());
-            assertThat(po.getSuccessCount(), nullValue());
-            assertThat(po.getFailedCount(), nullValue());
-        }
-    }
-    
-    @Test
-    public void assertGetSummedTaskResultStatistics() {
-        for (StatisticInterval each : StatisticInterval.values()) {
-            Date date = new Date();
-            taskResultStatisticsRepository.save(new TaskResultStatistics(100L, 2L, each.name(), date));
-            taskResultStatisticsRepository.save(new TaskResultStatistics(200L, 5L, each.name(), date));
-            TaskResultStatistics po = taskResultStatisticsRepository.getSummedTaskResultStatistics(date, each.name());
-            assertThat(po.getSuccessCount(), is(300L));
-            assertThat(po.getFailedCount(), is(7L));
-        }
-    }
-
-    @Test
-    public void assertFindTaskRunningStatisticsWhenTableIsEmpty() {
-        assertThat(taskRunningStatisticsRepository.findTaskRunningStatistics(new Date()).size(), is(0));
-    }
-    
-    @Test
-    public void assertFindTaskRunningStatisticsWithDifferentFromDate() {
-        Date now = new Date();
-        Date yesterday = getYesterday();
-        taskRunningStatisticsRepository.deleteAll();
-        taskRunningStatisticsRepository.save(new TaskRunningStatistics(100, yesterday));
-        taskRunningStatisticsRepository.save(new TaskRunningStatistics(100, now));
-        assertThat(taskRunningStatisticsRepository.findTaskRunningStatistics(yesterday).size(), is(2));
-        assertThat(taskRunningStatisticsRepository.findTaskRunningStatistics(now).size(), is(1));
-    }
-    
-    @Test
-    public void assertFindJobRunningStatisticsWhenTableIsEmpty() {
-        assertThat(jobRunningStatisticsRepository.findJobRunningStatistics(new Date()).size(), is(0));
-    }
-    
-    @Test
-    public void assertFindJobRunningStatisticsWithDifferentFromDate() {
-        Date now = new Date();
-        Date yesterday = getYesterday();
-        jobRunningStatisticsRepository.deleteAll();
-        jobRunningStatisticsRepository.save(new JobRunningStatistics(100, yesterday));
-        jobRunningStatisticsRepository.save(new JobRunningStatistics(100, now));
-        assertThat(jobRunningStatisticsRepository.findJobRunningStatistics(yesterday).size(), is(2));
-        assertThat(jobRunningStatisticsRepository.findJobRunningStatistics(now).size(), is(1));
-    }
-    
-    @Test
-    public void assertFindJobRegisterStatisticsWhenTableIsEmpty() {
-        assertThat(jobRegisterStatisticsRepository.findJobRegisterStatistics(new Date()).size(), is(0));
-    }
-    
-    @Test
-    public void assertFindJobRegisterStatisticsWithDifferentFromDate() {
-        Date now = new Date();
-        Date yesterday = getYesterday();
-        jobRegisterStatisticsRepository.save(new JobRegisterStatistics(100, yesterday));
-        jobRegisterStatisticsRepository.save(new JobRegisterStatistics(100, now));
-        assertThat(jobRegisterStatisticsRepository.findJobRegisterStatistics(yesterday).size(), is(2));
-        assertThat(jobRegisterStatisticsRepository.findJobRegisterStatistics(now).size(), is(1));
-    }
-    
-    private Date getYesterday() {
-        return new Date(new Date().getTime() - 24 * 60 * 60 * 1000);
-    }
-}
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/package.json b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/package.json
index a81dfab..ba8e586 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/package.json
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/package.json
@@ -16,6 +16,7 @@
     "axios": "^0.18.0",
     "element-ui": "^2.4.9",
     "lodash": "^4.17.11",
+    "normalize.css": "^8.0.1",
     "vue": "^2.5.2",
     "vue-i18n": "^8.4.0",
     "vue-router": "^3.0.1",
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/en-US.js b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/en-US.js
index 6b4542f..4b050cc 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/en-US.js
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/en-US.js
@@ -27,21 +27,21 @@ export default {
             href: '/registry-center'
           },
           {
-            title: 'Event trace data source',
-            href: '/data-source'
+            title: 'App config',
+            href: '/app-config'
           }
         ]
       },
       {
-        title: 'Job operation',
+        title: 'Job',
         child: [
           {
-            title: 'Job dimension',
-            href: '/operation-jobs'
+            title: 'Config',
+            href: '/job-config'
           },
           {
-            title: 'Server dimension',
-            href: '/operation-servers'
+            title: 'Status',
+            href: '/job-status'
           }
         ]
       },
@@ -49,6 +49,10 @@ export default {
         title: 'Job history',
         child: [
           {
+            title: 'History dashboard',
+            href: '/history-dashboard'
+          },
+          {
             title: 'Job trace',
             href: '/history-trace'
           },
@@ -57,10 +61,6 @@ export default {
             href: '/history-status'
           }
         ]
-      },
-      {
-        title: 'Help',
-        href: '/job-help'
       }
     ],
     connected: 'Connected',
@@ -136,7 +136,7 @@ export default {
       digest: 'Please enter a digest'
     }
   },
-  dataSource: {
+  appConfig: {
     btnTxt: 'ADD',
     addDialog: {
       title: 'Add a data source',
@@ -150,11 +150,15 @@ export default {
       btnConnectTestTxt: 'Test connect'
     },
     table: {
+      appName: 'App name',
+      appUrl: 'App URL',
+      script: 'Bootstrap script',
       operate: 'Operate',
-      operateConnect: 'Connect',
-      operateConnected: 'Connected',
+      operateDetail: 'Detail',
+      operateModify: 'Update',
+      operateDisable: 'Disable',
+      operateEnable: 'Enable',
       operateDel: 'Del',
-      operateEdit: 'Edit'
     },
     rules: {
       name: 'Please enter the name of the data source',
@@ -163,134 +167,5 @@ export default {
       username: 'Please enter the username of the data source',
       password: 'Please enter the password of the data source'
     }
-  },
-  operationJobs: {
-    labelInfo: {
-      jobName: 'Job name',
-      shardingTotalCount: 'Sharding total count',
-      cron: 'Crontab',
-      description: 'Description',
-      status: 'Status',
-      jobParameter: 'Job parameter',
-      maxTimeDiffSeconds: 'Max time diff seconds',
-      reconcileIntervalMinutes: 'Reconcile interval minutes',
-      monitorExecution: 'Monitor execution',
-      failover: 'Failover',
-      misfire: 'Misfire',
-      streamingProcess: 'Streaming process',
-      shardingItemParameters: 'Sharding item parameters',
-      jobShardingStrategyType: 'Job sharding strategy type',
-      jobExecutorServiceHandlerType: 'Executor service handler',
-      jobErrorHandlerType: 'Job error handler',
-      item: 'Sharding item',
-      serverIp: 'Server IP',
-      instanceId: 'PID',
-      editTitle: 'Update job'
-    },
-    table: {
-      operate: 'Operation'
-    },
-    rules: {
-      jobName: 'Please enter the Job name',
-      shardingTotalCount: 'Please enter the Sharding total count',
-      cron: 'Please enter the Crontab',
-      description: 'Please enter the Description',
-      status: 'Please enter the Status'
-    },
-    statusText: {
-      OK: 'OK',
-      DISABLED: 'Disabled',
-      CRASHED: 'Crashed',
-      PENDING: 'Staging',
-      SHARDING_FLAG: 'SHARDING_FLAG'
-    },
-    actionText: {
-      modify: 'Update',
-      detail: 'Detail',
-      trigger: 'Trigger',
-      disable: 'Disable',
-      enable: 'Enable',
-      shutdown: 'Shutdown',
-      remove: 'Remove'
-    }
-  },
-  operationServers: {
-    labelInfo: {
-      serverIp: 'Server IP',
-      instancesNum: 'Instance count',
-      jobsNum: 'Job num',
-      disabledJobsNum: 'Disabled jobs num',
-      jobName: 'Job name',
-      status: 'Status',
-      operate: 'Operation'
-    },
-    statusText: {
-      OK: 'Enabled',
-      DISABLED: 'Disabled',
-      CRASHED: 'Crashed',
-      PENDING: 'Staging',
-      SHARDING_FLAG: 'SHARDING_FLAG'
-    },
-    actionText: {
-      detail: 'Detail',
-      disable: 'Disable',
-      enable: 'Enable',
-      shutdown: 'Shutdown',
-      remove: 'Remove'
-    }
-  },
-  historyTrace: {
-    column: {
-      jobName: 'Job name',
-      serverIp: 'Server IP',
-      shardingItem: 'Sharding item',
-      executeResult: 'Execute result',
-      failureCause: 'Failure reason',
-      startTime: 'Start time',
-      completeTime: 'Complete time'
-    },
-    searchForm: {
-      jobName: 'Job name',
-      serverIp: 'Server ip',
-      startTime: 'Start time',
-      CompleteTime: 'Complete time',
-      executeResult: 'Select execute result',
-      executeSuccess: 'Success',
-      executeFailed: 'Failure'
-    }
-  },
-  historyStatus: {
-    column: {
-      jobName: 'Job name',
-      shardingItem: 'Sharding item',
-      state: 'Status',
-      createTime: 'Creation time',
-      remark: 'Comments'
-    },
-    searchForm: {
-      jobName: 'Job name',
-      startTime: 'Creation start time',
-      CompleteTime: 'Creation end time',
-      state: 'Select state',
-      stateStaging: 'Staging',
-      stateFailed: 'Failed',
-      stateFinished: 'Finished',
-      stateRunning: 'Running',
-      stateError: 'Error',
-      stateKilled: 'Killed'
-    }
-  },
-  help: {
-    design_concept_title: 'Design concept',
-    design_concept_info_1: 'Console is not related to Elastic Job, it just reading data from registry center and showing the status of jobs, or updating data to registry center which will change the configuration.',
-    design_concept_info_2: "Console can operate lifecycle for jobs, such as enable and disable, but can not the start and stop job's process, because of console server and job servers are completely distributed, console can not control the job servers.",
-    major_features_title: 'Major features',
-    major_features_info_1: 'View status of jobs and servers',
-    major_features_info_2: 'Quick update and delete jobs',
-    major_features_info_3: 'Disable and enable Jobs',
-    major_features_info_4: 'Multiple registry centers supported',
-    major_features_info_5: 'Trace jobs execute history',
-    unsupported_title: 'Unsupported',
-    unsupported_info: 'Add job. Because of job is added at first running time automatically, it is unnecessary to add job from console. So just start the job app.'
   }
 }
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/zh-CN.js b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/zh-CN.js
index 24d69c6..5f04b26 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/zh-CN.js
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/lang/zh-CN.js
@@ -27,21 +27,21 @@ export default {
             href: '/registry-center'
           },
           {
-            title: '事件追踪数据源配置',
-            href: '/data-source'
+            title: '应用配置',
+            href: '/app-config'
           }
         ]
       },
       {
-        title: '作业操作',
+        title: '作业',
         child: [
           {
-            title: '作业维度',
-            href: '/operation-jobs'
+            title: '配置',
+            href: '/job-config'
           },
           {
-            title: '服务器维度',
-            href: '/operation-servers'
+            title: '状态',
+            href: '/job-status'
           }
         ]
       },
@@ -49,18 +49,18 @@ export default {
         title: '作业历史',
         child: [
           {
-            title: '历史轨迹',
+            title: '历史dashboard',
+            href: '/history-dashboard'
+          },
+          {
+            title: '作业历史轨迹',
             href: '/history-trace'
           },
           {
-            title: '历史状态',
+            title: '作业运行状态',
             href: '/history-status'
           }
         ]
-      },
-      {
-        title: '帮助',
-        href: '/job-help'
       }
     ],
     connect: '已连接',
@@ -136,7 +136,7 @@ export default {
       digest: '请输入登录凭证'
     }
   },
-  dataSource: {
+  appConfig: {
     btnTxt: '添加',
     addDialog: {
       title: '添加事件追踪数据源',
@@ -150,11 +150,15 @@ export default {
       btnConnectTestTxt: '测试连接'
     },
     table: {
+      appName: '应用名称',
+      appUrl: '应用所在路径',
+      script: '启动脚本',
       operate: '操作',
-      operateConnect: '连接',
-      operateConnected: '已连接',
+      operateDetail: '详情',
+      operateModify: '修改',
       operateDel: '删除',
-      operateEdit: '编辑'
+      operateDisable: '失效',
+      operateEnable: '生效'
     },
     rules: {
       name: '请输入数据源名称',
@@ -163,135 +167,5 @@ export default {
       username: '请输入数据源用户名',
       password: '请输入数据源密码'
     }
-  },
-  operationJobs: {
-    labelInfo: {
-      jobName: '作业名称',
-      shardingTotalCount: '作业分片总数',
-      cron: 'Cron表达式',
-      description: '作业描述信息',
-      status: '状态',
-      jobParameter: '自定义参数',
-      maxTimeDiffSeconds: '最大容忍本机与注册中心的时间误差秒数',
-      reconcileIntervalMinutes: '作业服务器状态修复周期',
-      monitorExecution: '监控作业执行时状态',
-      failover: '支持自动失效转移',
-      misfire: '支持错过重执行',
-      streamingProcess: '是否流式处理数据',
-      shardingItemParameters: '分片序列号/参数对照表',
-      jobShardingStrategyType: '作业分片策略类型',
-      jobExecutorServiceHandlerType: '定制线程池全路径',
-      jobErrorHandlerType: '定制异常处理类全路径',
-      item: '分片项',
-      serverIp: '服务器IP',
-      instanceId: '进程ID',
-      editTitle: '修改作业'
-    },
-    table: {
-      operate: '操作'
-    },
-    rules: {
-      jobName: '请输入作业名称',
-      shardingTotalCount: '请输入作业分片总数',
-      cron: '请输入Cron表达式',
-      description: '请输入作业描述信息',
-      status: '请选择作业状态'
-    },
-    statusText: {
-      OK: '正常',
-      DISABLED: '已失效',
-      CRASHED: '已下线',
-      PENDING: '等待运行',
-      SHARDING_FLAG: '分片待调整'
-    },
-    actionText: {
-      modify: '修改',
-      detail: '详情',
-      trigger: '触发',
-      disable: '失效',
-      enable: '生效',
-      shutdown: '终止',
-      remove: '删除'
-    }
-  },
-  operationServers: {
-    labelInfo: {
-      serverIp: '服务器IP',
-      instancesNum: '运行实例数',
-      instanceCount: '运行实例数',
-      jobsNum: '作业总数',
-      disabledJobsNum: '禁用作业数',
-      jobName: '作业名称',
-      status: '状态',
-      operate: '操作'
-    },
-    statusText: {
-      OK: '已启用',
-      DISABLED: '已失效',
-      CRASHED: '已下线',
-      PENDING: '等待运行',
-      SHARDING_FLAG: '分片待调整'
-    },
-    actionText: {
-      detail: '详情',
-      disable: '失效',
-      enable: '生效',
-      shutdown: '终止',
-      remove: '删除'
-    }
-  },
-  historyTrace: {
-    column: {
-      jobName: '作业名称',
-      serverIp: '服务器IP',
-      shardingItem: '分片项',
-      executeResult: '执行结果',
-      failureCause: '失败原因',
-      startTime: '开始时间',
-      completeTime: '完成时间'
-    },
-    searchForm: {
-      jobName: '请输入作业名称',
-      serverIp: '请输入服务器IP',
-      startTime: '请输入开始时间',
-      CompleteTime: '请输入完成时间',
-      executeResult: '请选择执行结果',
-      executeSuccess: '成功',
-      executeFailed: '失败'
-    }
-  },
-  historyStatus: {
-    column: {
-      jobName: '作业名称',
-      shardingItem: '分片项',
-      state: '状态',
-      createTime: '创建时间',
-      remark: '备注'
-    },
-    searchForm: {
-      jobName: '请输入作业名称',
-      startTime: '请输入创建开始时间',
-      CompleteTime: '请输入创建结束时间',
-      state: '选择状态',
-      stateStaging: '等待运行',
-      stateFailed: '运行失败',
-      stateFinished: '已完成',
-      stateRunning: '运行中',
-      stateError: '启动失败',
-      stateKilled: '主动终止'
-    }
-  },
-  help: {
-    design_concept_title: '设计理念',
-    design_concept_info_1: '本控制台和Elastic Job并无直接关系,是通过读取Elastic Job的注册中心数据展现作业状态,或更新注册中心数据修改全局配置。',
-    design_concept_info_2: '控制台只能控制作业本身是否运行,但不能控制作业进程的启停,因为控制台和作业本身服务器是完全分布式的,控制台并不能控制作业服务器。',
-    major_features_title: '主要功能',
-    major_features_info_1: '查看作业以及服务器状态',
-    major_features_info_2: '快捷的修改以及删除作业设置',
-    major_features_info_3: '启用和禁用作业',
-    major_features_info_4: '跨注册中心查看作业',
-    major_features_info_5: '查看作业运行轨迹和运行状态',
-    unsupported_title: '不支持项',
-    unsupported_info: '添加作业。因为作业都是在首次运行时自动添加,使用控制台添加作业并无必要。直接在作业服务器启动包含Elastic Job的作业进程即可。',
   }
 }
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/router/index.js b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/router/index.js
index 1551af0..e54b932 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/router/index.js
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/router/index.js
@@ -25,7 +25,19 @@ export const constantRouterMap = [
     path: '/login',
     component: () => import('@/views/login'),
     hidden: true
-  }
+  },
+  {
+    path: '/registry-center',
+    component: () => import('@/views/registry-center'),
+    hidden: true,
+    name: 'Registry center'
+  },
+  {
+    path: '/app-config',
+    component: () => import('@/views/app-config'),
+    hidden: true,
+    name: 'App config'
+  },
 ]
 
 export default new Router({
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobExecutionLogRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/api.js
similarity index 64%
rename from shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobExecutionLogRepository.java
rename to shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/api.js
index f8381b5..3aaa256 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobExecutionLogRepository.java
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/api.js
@@ -15,11 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.search;
+import API from '@/utils/api'
 
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobExecutionLog;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-
-public interface JobExecutionLogRepository extends JpaRepository<JobExecutionLog, String>, JpaSpecificationExecutor<JobExecutionLog> {
+export default {
+  getApp: (params = {}) => API.get(`/api/app/list`, params),
+  deleteRegCenter: (params = {}) => API.delete(`/api/registry-center`, params),
+  postRegCenter: (params = {}) => API.post(`/api/registry-center/add`, params),
+  getRegCenterActivated: (params = {}) => API.get(`/api/registry-center/activated`, params),
+  postRegCenterConnect: (params = {}) => API.post(`/api/registry-center/connect`, params)
 }
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/index.vue b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/index.vue
new file mode 100644
index 0000000..392ebbf
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/index.vue
@@ -0,0 +1,33 @@
+<!--
+  - Licensed to the Apache Software Foundation (ASF) under one or more
+  - contributor license agreements.  See the NOTICE file distributed with
+  - this work for additional information regarding copyright ownership.
+  - The ASF licenses this file to You under the Apache License, Version 2.0
+  - (the "License"); you may not use this file except in compliance with
+  - the License.  You may obtain a copy of the License at
+  -
+  -     http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing, software
+  - distributed under the License is distributed on an "AS IS" BASIS,
+  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  - See the License for the specific language governing permissions and
+  - limitations under the License.
+  -->
+
+<template>
+  <s-app-config />
+</template>
+
+<script>
+import SAppConfig from './module/appConfig'
+export default {
+  name: 'AppConfig',
+  components: {
+    SAppConfig
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/module/appConfig.vue b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/module/appConfig.vue
new file mode 100644
index 0000000..f542380
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/app-config/module/appConfig.vue
@@ -0,0 +1,283 @@
+<!--
+  - Licensed to the Apache Software Foundation (ASF) under one or more
+  - contributor license agreements.  See the NOTICE file distributed with
+  - this work for additional information regarding copyright ownership.
+  - The ASF licenses this file to You under the Apache License, Version 2.0
+  - (the "License"); you may not use this file except in compliance with
+  - the License.  You may obtain a copy of the License at
+  -
+  -     http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing, software
+  - distributed under the License is distributed on an "AS IS" BASIS,
+  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  - See the License for the specific language governing permissions and
+  - limitations under the License.
+  -->
+
+<template>
+  <el-row class="box-card">
+    <div class="btn-group">
+      <el-button
+        :disabled="isGuest"
+        class="btn-plus"
+        type="primary"
+        icon="el-icon-plus"
+        @click="add"
+      >{{ $t("registryCenter.btnTxt") }}</el-button>
+    </div>
+    <div class="table-wrap">
+      <el-table :data="tableData" border style="width: 100%">
+        <el-table-column
+          v-for="(item, index) in column"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          :width="item.width"
+        />
+        <el-table-column :label="$t('appConfig.table.operate')" fixed="right" width="300">
+          <template slot-scope="scope">
+            <el-button-group>
+            <el-button
+              size="mini"
+              type="primary"
+              :disabled="isGuest"
+              @click="handleModify(scope.row)"
+              plain>{{ $t("appConfig.table.operateDetail") }}</el-button>
+            <el-button
+              size="mini"
+              type="primary"
+              :disabled="isGuest"
+              @click="handleModify(scope.row)"
+              plain>{{ $t("appConfig.table.operateModify") }}</el-button>
+            <el-button
+              size="mini"
+              type="primary"
+              :disabled="isGuest"
+              @click="handleModify(scope.row)"
+              plain>{{ $t("appConfig.table.operateDel") }}</el-button>
+            <el-button
+              size="mini"
+              type="primary"
+              :disabled="isGuest"
+              @click="handleModify(scope.row)"
+              plain>{{ $t("appConfig.table.operateDisable") }}</el-button>
+            </el-button-group>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination">
+        <el-pagination
+          :total="total"
+          :current-page="currentPage"
+          background
+          layout="prev, pager, next"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+    <el-dialog
+      :title="$t('appConfig.registDialog.title')"
+      :visible.sync="addDialogVisible"
+      width="1010px"
+    >
+      <el-form ref="form" :model="form" :rules="rules" label-width="170px">
+        <el-form-item :label="$t('appConfig.registDialog.name')" prop="name">
+          <el-input :placeholder="$t('appConfig.rules.name')" v-model="form.name" autocomplete="off" />
+        </el-form-item>
+        <el-form-item :label="$t('appConfig.registDialog.address')" prop="zkAddressList">
+          <el-input
+            :placeholder="$t('appConfig.rules.address')"
+            v-model="form.zkAddressList"
+            autocomplete="off"
+          />
+        </el-form-item>
+        <el-form-item :label="$t('appConfig.registDialog.namespaces')" prop="namespace">
+          <el-input
+            :placeholder="$t('appConfig.rules.namespaces')"
+            v-model="form.namespace"
+            autocomplete="off"
+          />
+        </el-form-item>
+        <el-form-item :label="$t('appConfig.registDialog.digest')">
+          <el-input
+            :placeholder="$t('appConfig.rules.digest')"
+            v-model="form.digest"
+            autocomplete="off"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="regustDialogVisible = false">{{ $t("appConfig.registDialog.btnCancelTxt") }}</el-button>
+        <el-button
+          type="primary"
+          @click="onConfirm('form')"
+        >{{ $t("appConfig.registDialog.btnConfirmTxt") }}</el-button>
+      </div>
+    </el-dialog>
+  </el-row>
+</template>
+<script>
+import { mapActions } from 'vuex'
+import clone from 'lodash/clone'
+import API from '../api'
+export default {
+  name: 'AppConfig',
+  data() {
+    return {
+      addDialogVisible: false,
+      isGuest: window.localStorage.getItem('isGuest') === 'true',
+      column: [
+        {
+          label: this.$t('appConfig').table.appName,
+          prop: 'appName'
+        },
+        {
+          label: this.$t('appConfig').table.appUrl,
+          prop: 'appURL'
+        },
+        {
+          label: this.$t('appConfig').table.script,
+          prop: 'bootstrapScript'
+        }
+      ],
+      form: {
+        name: '',
+        zkAddressList: '',
+        namespace: '',
+        digest: ''
+      },
+      rules: {
+        name: [
+          {
+            required: true,
+            message: this.$t('appConfig').rules.name,
+            trigger: 'change'
+          }
+        ],
+        zkAddressList: [
+          {
+            required: true,
+            message: this.$t('appConfig').rules.address,
+            trigger: 'change'
+          }
+        ],
+        namespace: [
+          {
+            required: true,
+            message: this.$t('appConfig').rules.namespaces,
+            trigger: 'change'
+          }
+        ],
+        instanceType: [
+          {
+            required: true,
+            message: this.$t('appConfig').rules.centerType,
+            trigger: 'change'
+          }
+        ],
+        orchestrationName: [
+          {
+            required: true,
+            message: this.$t('appConfig').rules.orchestrationName,
+            trigger: 'change'
+          }
+        ]
+      },
+      tableData: [],
+      cloneTableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: null
+    }
+  },
+  created() {
+    this.getApp()
+  },
+  methods: {
+    ...mapActions(['setRegCenterActivated']),
+    handleCurrentChange(val) {
+      const data = clone(this.cloneTableData)
+      this.tableData = data.splice(val - 1, this.pageSize)
+    },
+    getApp() {
+      API.getApp().then(res => {
+        const data = res.model
+        this.total = data.length
+        this.cloneTableData = clone(res.model)
+        this.tableData = data.splice(0, this.pageSize)
+      })
+      this.getRegCenterActivated()
+    },
+    getRegCenterActivated() {
+      API.getRegCenterActivated().then(res => {
+        this.setRegCenterActivated(res.model.name)
+      })
+    },
+    handleConnect(row) {
+      if (row.activated) {
+        this.$notify({
+          title: this.$t('common').notify.title,
+          message: this.$t('common').connected,
+          type: 'success'
+        })
+      } else {
+        const params = {
+          name: row.name
+        }
+        API.postRegCenterConnect(params).then(res => {
+          this.$notify({
+            title: this.$t('common').notify.title,
+            message: this.$t('common').notify.conSucMessage,
+            type: 'success'
+          })
+          this.getRegCenter()
+        })
+      }
+    },
+    handlerDel(row) {
+      const params = {
+        name: row.name
+      }
+      API.deleteRegCenter(params).then(res => {
+        this.$notify({
+          title: this.$t('common').notify.title,
+          message: this.$t('common').notify.delSucMessage,
+          type: 'success'
+        })
+        this.getRegCenter()
+      })
+    },
+    onConfirm(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          API.postRegCenter(this.form).then(res => {
+            this.addDialogVisible = false
+            this.$notify({
+              title: this.$t('common').notify.title,
+              message: this.$t('common').notify.addSucMessage,
+              type: 'success'
+            })
+            this.getRegCenter()
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    add() {
+      this.addDialogVisible = true
+    }
+  }
+}
+</script>
+<style lang='scss' scoped>
+.btn-group {
+  margin-bottom: 20px;
+}
+.pagination {
+  float: right;
+  margin: 10px -10px 10px 0;
+}
+</style>
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobStatusTraceLogRepository.java b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/api.js
similarity index 63%
rename from shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobStatusTraceLogRepository.java
rename to shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/api.js
index e67fbde..db972ca 100644
--- a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-backend/src/main/java/org/apache/shardingsphere/elasticjob/cloud/ui/dao/search/JobStatusTraceLogRepository.java
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/api.js
@@ -15,11 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.elasticjob.cloud.ui.dao.search;
+import API from '@/utils/api'
 
-import org.apache.shardingsphere.elasticjob.cloud.ui.domain.JobStatusTraceLog;
-import org.springframework.data.jpa.repository.JpaRepository;
-import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
-
-public interface JobStatusTraceLogRepository extends JpaRepository<JobStatusTraceLog, String>, JpaSpecificationExecutor<JobStatusTraceLog> {
+export default {
+  getRegCenter: (params = {}) => API.get(`/api/registry-center/load`, params),
+  deleteRegCenter: (params = {}) => API.delete(`/api/registry-center`, params),
+  postRegCenter: (params = {}) => API.post(`/api/registry-center/add`, params),
+  getRegCenterActivated: (params = {}) => API.get(`/api/registry-center/activated`, params),
+  postRegCenterConnect: (params = {}) => API.post(`/api/registry-center/connect`, params)
 }
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/index.vue b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/index.vue
new file mode 100644
index 0000000..45d61d4
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/index.vue
@@ -0,0 +1,33 @@
+<!--
+  - Licensed to the Apache Software Foundation (ASF) under one or more
+  - contributor license agreements.  See the NOTICE file distributed with
+  - this work for additional information regarding copyright ownership.
+  - The ASF licenses this file to You under the Apache License, Version 2.0
+  - (the "License"); you may not use this file except in compliance with
+  - the License.  You may obtain a copy of the License at
+  -
+  -     http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing, software
+  - distributed under the License is distributed on an "AS IS" BASIS,
+  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  - See the License for the specific language governing permissions and
+  - limitations under the License.
+  -->
+
+<template>
+  <s-registry-center />
+</template>
+
+<script>
+import SRegistryCenter from './module/registryCenter'
+export default {
+  name: 'RegistryCenter',
+  components: {
+    SRegistryCenter
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+</style>
diff --git a/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/module/registryCenter.vue b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/module/registryCenter.vue
new file mode 100644
index 0000000..ce9540f
--- /dev/null
+++ b/shardingsphere-elasticjob-cloud-ui/shardingsphere-elasticjob-cloud-ui-frontend/src/views/registry-center/module/registryCenter.vue
@@ -0,0 +1,285 @@
+<!--
+  - Licensed to the Apache Software Foundation (ASF) under one or more
+  - contributor license agreements.  See the NOTICE file distributed with
+  - this work for additional information regarding copyright ownership.
+  - The ASF licenses this file to You under the Apache License, Version 2.0
+  - (the "License"); you may not use this file except in compliance with
+  - the License.  You may obtain a copy of the License at
+  -
+  -     http://www.apache.org/licenses/LICENSE-2.0
+  -
+  - Unless required by applicable law or agreed to in writing, software
+  - distributed under the License is distributed on an "AS IS" BASIS,
+  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  - See the License for the specific language governing permissions and
+  - limitations under the License.
+  -->
+
+<template>
+  <el-row class="box-card">
+    <div class="btn-group">
+      <el-button
+        :disabled="isGuest"
+        class="btn-plus"
+        type="primary"
+        icon="el-icon-plus"
+        @click="add"
+      >{{ $t("registryCenter.btnTxt") }}</el-button>
+    </div>
+    <div class="table-wrap">
+      <el-table :data="tableData" border style="width: 100%">
+        <el-table-column
+          v-for="(item, index) in column"
+          :key="index"
+          :prop="item.prop"
+          :label="item.label"
+          :width="item.width"
+        />
+        <el-table-column :label="$t('registryCenter.table.operate')" fixed="right" width="200">
+          <template slot-scope="scope">
+            <el-tooltip
+              :content="!scope.row.activated ? $t('registryCenter.table.operateConnect'): $t('registryCenter.table.operateConnected')"
+              class="item"
+              effect="dark"
+              placement="top"
+            >
+              <el-button
+                :type="scope.row.activated ? 'success' : 'primary'"
+                :disabled="isGuest"
+                icon="el-icon-link"
+                size="small"
+                @click="handleConnect(scope.row)"
+              />
+            </el-tooltip>
+            <el-tooltip
+              :content="$t('registryCenter.table.operateDel')"
+              class="item"
+              effect="dark"
+              placement="top"
+            >
+              <el-button
+                :disabled="isGuest"
+                size="small"
+                type="danger"
+                icon="el-icon-delete"
+                @click="handlerDel(scope.row)"
+              />
+            </el-tooltip>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination">
+        <el-pagination
+          :total="total"
+          :current-page="currentPage"
+          background
+          layout="prev, pager, next"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </div>
+    <el-dialog
+      :title="$t('registryCenter.registDialog.title')"
+      :visible.sync="addDialogVisible"
+      width="1010px"
+    >
+      <el-form ref="form" :model="form" :rules="rules" label-width="170px">
+        <el-form-item :label="$t('registryCenter.registDialog.name')" prop="name">
+          <el-input :placeholder="$t('registryCenter.rules.name')" v-model="form.name" autocomplete="off" />
+        </el-form-item>
+        <el-form-item :label="$t('registryCenter.registDialog.address')" prop="zkAddressList">
+          <el-input
+            :placeholder="$t('registryCenter.rules.address')"
+            v-model="form.zkAddressList"
+            autocomplete="off"
+          />
+        </el-form-item>
+        <el-form-item :label="$t('registryCenter.registDialog.namespaces')" prop="namespace">
+          <el-input
+            :placeholder="$t('registryCenter.rules.namespaces')"
+            v-model="form.namespace"
+            autocomplete="off"
+          />
+        </el-form-item>
+        <el-form-item :label="$t('registryCenter.registDialog.digest')">
+          <el-input
+            :placeholder="$t('registryCenter.rules.digest')"
+            v-model="form.digest"
+            autocomplete="off"
+          />
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="regustDialogVisible = false">{{ $t("registryCenter.registDialog.btnCancelTxt") }}</el-button>
+        <el-button
+          type="primary"
+          @click="onConfirm('form')"
+        >{{ $t("registryCenter.registDialog.btnConfirmTxt") }}</el-button>
+      </div>
+    </el-dialog>
+  </el-row>
+</template>
+<script>
+import { mapActions } from 'vuex'
+import clone from 'lodash/clone'
+import API from '../api'
+export default {
+  name: 'RegistryCenter',
+  data() {
+    return {
+      addDialogVisible: false,
+      isGuest: window.localStorage.getItem('isGuest') === 'true',
+      column: [
+        {
+          label: this.$t('registryCenter').registDialog.name,
+          prop: 'name'
+        },
+        {
+          label: this.$t('registryCenter').registDialog.address,
+          prop: 'zkAddressList'
+        },
+        {
+          label: this.$t('registryCenter').registDialog.namespaces,
+          prop: 'namespace'
+        }
+      ],
+      form: {
+        name: '',
+        zkAddressList: '',
+        namespace: '',
+        digest: ''
+      },
+      rules: {
+        name: [
+          {
+            required: true,
+            message: this.$t('registryCenter').rules.name,
+            trigger: 'change'
+          }
+        ],
+        zkAddressList: [
+          {
+            required: true,
+            message: this.$t('registryCenter').rules.address,
+            trigger: 'change'
+          }
+        ],
+        namespace: [
+          {
+            required: true,
+            message: this.$t('registryCenter').rules.namespaces,
+            trigger: 'change'
+          }
+        ],
+        instanceType: [
+          {
+            required: true,
+            message: this.$t('registryCenter').rules.centerType,
+            trigger: 'change'
+          }
+        ],
+        orchestrationName: [
+          {
+            required: true,
+            message: this.$t('registryCenter').rules.orchestrationName,
+            trigger: 'change'
+          }
+        ]
+      },
+      tableData: [],
+      cloneTableData: [],
+      currentPage: 1,
+      pageSize: 10,
+      total: null
+    }
+  },
+  created() {
+    this.getRegCenter()
+  },
+  methods: {
+    ...mapActions(['setRegCenterActivated']),
+    handleCurrentChange(val) {
+      const data = clone(this.cloneTableData)
+      this.tableData = data.splice(val - 1, this.pageSize)
+    },
+    getRegCenter() {
+      API.getRegCenter().then(res => {
+        const data = res.model
+        this.total = data.length
+        this.cloneTableData = clone(res.model)
+        this.tableData = data.splice(0, this.pageSize)
+      })
+      this.getRegCenterActivated()
+    },
+    getRegCenterActivated() {
+      API.getRegCenterActivated().then(res => {
+        this.setRegCenterActivated(res.model.name)
+      })
+    },
+    handleConnect(row) {
+      if (row.activated) {
+        this.$notify({
+          title: this.$t('common').notify.title,
+          message: this.$t('common').connected,
+          type: 'success'
+        })
+      } else {
+        const params = {
+          name: row.name
+        }
+        API.postRegCenterConnect(params).then(res => {
+          this.$notify({
+            title: this.$t('common').notify.title,
+            message: this.$t('common').notify.conSucMessage,
+            type: 'success'
+          })
+          this.getRegCenter()
+        })
+      }
+    },
+    handlerDel(row) {
+      const params = {
+        name: row.name
+      }
+      API.deleteRegCenter(params).then(res => {
+        this.$notify({
+          title: this.$t('common').notify.title,
+          message: this.$t('common').notify.delSucMessage,
+          type: 'success'
+        })
+        this.getRegCenter()
+      })
+    },
+    onConfirm(formName) {
+      this.$refs[formName].validate(valid => {
+        if (valid) {
+          API.postRegCenter(this.form).then(res => {
+            this.addDialogVisible = false
+            this.$notify({
+              title: this.$t('common').notify.title,
+              message: this.$t('common').notify.addSucMessage,
+              type: 'success'
+            })
+            this.getRegCenter()
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    add() {
+      this.addDialogVisible = true
+    }
+  }
+}
+</script>
+<style lang='scss' scoped>
+.btn-group {
+  margin-bottom: 20px;
+}
+.pagination {
+  float: right;
+  margin: 10px -10px 10px 0;
+}
+</style>