This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch restful-api
in repository https://gitbox.apache.org/repos/asf/shardingsphere-elasticjob.git
The following commit(s) were added to refs/heads/restful-api by this push:
new 04aadb3 Refactor cloud-scheduler with elasticjob-restful. (#1395)
04aadb3 is described below
commit 04aadb39bee3920c6d26df615b48f612b935f0a5
Author: 吴伟杰 <[email protected]>
AuthorDate: Sat Aug 22 14:33:01 2020 +0800
Refactor cloud-scheduler with elasticjob-restful. (#1395)
---
.../elasticjob-cloud-scheduler/pom.xml | 38 +-----
.../elasticjob/cloud/console/ConsoleBootstrap.java | 52 ++------
.../cloud/console/config/FilterRegisterConfig.java | 59 ---------
.../ConsoleExceptionHandler.java} | 25 ++--
.../config/advice/ConsoleRestControllerAdvice.java | 66 ---------
.../JsonResponseBodySerializer.java} | 35 +++--
.../console/controller/CloudAppController.java | 65 +++++----
.../console/controller/CloudJobController.java | 147 ++++++++++++---------
.../controller/CloudOperationController.java | 39 +++---
.../console/security/AuthenticationResult.java | 35 -----
.../security/UserAuthenticationService.java | 57 --------
.../cloud/console/security/WwwAuthFilter.java | 89 -------------
...cjob.restful.serializer.ResponseBodySerializer} | 4 +-
.../cloud/console/AbstractCloudControllerTest.java | 32 +++--
.../console/controller/CloudJobControllerTest.java | 5 +-
.../fixture/master/MesosMasterServerMock.java | 15 +--
.../master/MesosMasterServerMockConfiguration.java | 38 ------
.../mesos/fixture/slave/MesosSlaveServerMock.java | 15 +--
.../slave/MesosSlaveServerMockConfiguration.java | 38 ------
19 files changed, 227 insertions(+), 627 deletions(-)
diff --git a/elasticjob-cloud/elasticjob-cloud-scheduler/pom.xml
b/elasticjob-cloud/elasticjob-cloud-scheduler/pom.xml
index 1cdf6e8..fdad952 100755
--- a/elasticjob-cloud/elasticjob-cloud-scheduler/pom.xml
+++ b/elasticjob-cloud/elasticjob-cloud-scheduler/pom.xml
@@ -57,41 +57,9 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-web</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>${springframework.version}</version>
- <scope>compile</scope>
- <exclusions>
- <exclusion>
- <artifactId>spring-web</artifactId>
- <groupId>org.springframework</groupId>
- </exclusion>
- <exclusion>
- <artifactId>spring-context</artifactId>
- <groupId>org.springframework</groupId>
- </exclusion>
- </exclusions>
+ <groupId>org.apache.shardingsphere.elasticjob</groupId>
+ <artifactId>elasticjob-restful</artifactId>
+ <version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/ConsoleBootstrap.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/ConsoleBootstrap.java
index 9c8af86..663ce34 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/ConsoleBootstrap.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/ConsoleBootstrap.java
@@ -17,8 +17,7 @@
package org.apache.shardingsphere.elasticjob.cloud.console;
-import lombok.Setter;
-import org.apache.commons.lang3.ArrayUtils;
+import
org.apache.shardingsphere.elasticjob.cloud.console.config.advice.ConsoleExceptionHandler;
import
org.apache.shardingsphere.elasticjob.cloud.console.controller.CloudAppController;
import
org.apache.shardingsphere.elasticjob.cloud.console.controller.CloudJobController;
import
org.apache.shardingsphere.elasticjob.cloud.console.controller.CloudOperationController;
@@ -26,67 +25,38 @@ import
org.apache.shardingsphere.elasticjob.cloud.scheduler.env.RestfulServerCon
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.ReconcileService;
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.producer.ProducerManager;
import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.builder.SpringApplicationBuilder;
-import org.springframework.boot.web.server.WebServerFactoryCustomizer;
-import
org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.apache.shardingsphere.elasticjob.restful.NettyRestfulService;
+import
org.apache.shardingsphere.elasticjob.restful.NettyRestfulServiceConfiguration;
+import org.apache.shardingsphere.elasticjob.restful.RestfulService;
/**
* Console bootstrap for Cloud.
*/
public class ConsoleBootstrap {
- private ConfigurableApplicationContext context;
+ private final RestfulService restfulService;
public ConsoleBootstrap(final CoordinatorRegistryCenter regCenter, final
RestfulServerConfiguration config, final ProducerManager producerManager, final
ReconcileService reconcileService) {
- ConsoleApplication.port = config.getPort();
CloudJobController.init(regCenter, producerManager);
CloudAppController.init(regCenter, producerManager);
CloudOperationController.init(regCenter, reconcileService);
+ NettyRestfulServiceConfiguration restfulServiceConfiguration = new
NettyRestfulServiceConfiguration(config.getPort());
+ restfulServiceConfiguration.addControllerInstance(new
CloudJobController(), new CloudAppController(), new CloudOperationController());
+ restfulServiceConfiguration.addExceptionHandler(Exception.class, new
ConsoleExceptionHandler());
+ restfulService = new NettyRestfulService(restfulServiceConfiguration);
}
/**
* Startup RESTful server.
*/
public void start() {
- context = ConsoleApplication.start();
+ restfulService.startup();
}
/**
* Stop RESTful server.
*/
public void stop() {
- context.close();
- }
-
- @SpringBootApplication
- public static class ConsoleApplication implements
WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
-
- @Setter
- private static int port;
-
- @Setter
- private static Class<?>[] extraSources;
-
- /**
- * Startup RESTful server.
- * @return ConfigurableApplicationContext
- */
- public static ConfigurableApplicationContext start() {
- SpringApplicationBuilder applicationBuilder = new
SpringApplicationBuilder(ConsoleApplication.class);
- if (ArrayUtils.isNotEmpty(extraSources)) {
- applicationBuilder.sources(extraSources);
- }
- return applicationBuilder.build().run();
- }
-
- @Override
- public void customize(final ConfigurableServletWebServerFactory
factory) {
- if (port <= 0) {
- return;
- }
- factory.setPort(port);
- }
+ restfulService.shutdown();
}
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/FilterRegisterConfig.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/FilterRegisterConfig.java
deleted file mode 100644
index e1b1229..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/FilterRegisterConfig.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.console.config;
-
-import
org.apache.shardingsphere.elasticjob.cloud.console.security.UserAuthenticationService;
-import
org.apache.shardingsphere.elasticjob.cloud.console.security.WwwAuthFilter;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import javax.servlet.DispatcherType;
-import java.util.EnumSet;
-
-/**
- * Filter register config.
- **/
-@Configuration
-public class FilterRegisterConfig {
-
- private final UserAuthenticationService userAuthenticationService;
-
- @Autowired
- public FilterRegisterConfig(final UserAuthenticationService
userAuthenticationService) {
- this.userAuthenticationService = userAuthenticationService;
- }
-
- /**
- * register www auth filter.
- *
- * @return www auth filter bean
- */
- @Bean
- public FilterRegistrationBean<WwwAuthFilter> wwwAuthFilter() {
- WwwAuthFilter wwwAuthFilter = new WwwAuthFilter();
- wwwAuthFilter.setUserAuthenticationService(userAuthenticationService);
- FilterRegistrationBean<WwwAuthFilter> registration = new
FilterRegistrationBean<>();
- registration.setFilter(wwwAuthFilter);
- registration.addUrlPatterns("/");
- registration.addUrlPatterns("*.html");
- registration.setDispatcherTypes(EnumSet.of(DispatcherType.REQUEST));
- return registration;
- }
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleExceptionHandler.java
similarity index 57%
copy from
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
copy to
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleExceptionHandler.java
index 0a595e0..6055c31 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleExceptionHandler.java
@@ -15,23 +15,24 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.elasticjob.cloud.console.config;
+package org.apache.shardingsphere.elasticjob.cloud.console.config.advice;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.method.HandlerTypePredicate;
-import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import lombok.extern.slf4j.Slf4j;
+import
org.apache.shardingsphere.elasticjob.restful.handler.ExceptionHandleResult;
+import org.apache.shardingsphere.elasticjob.restful.handler.ExceptionHandler;
/**
- * Web mvc config.
+ * A default exception handler for restful service.
**/
-@Configuration
-public class WebMvcConfig implements WebMvcConfigurer {
+@Slf4j
+public final class ConsoleExceptionHandler implements
ExceptionHandler<Exception> {
@Override
- public void configurePathMatch(final PathMatchConfigurer configurer) {
- HandlerTypePredicate handlerTypePredicate =
HandlerTypePredicate.forAnnotation(RestController.class);
- configurer.addPathPrefix("/api", handlerTypePredicate);
+ public ExceptionHandleResult handleException(final Exception ex) {
+ return ExceptionHandleResult.builder()
+ .statusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code())
+ .result(ex.getLocalizedMessage())
+ .build();
}
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleRestControllerAdvice.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleRestControllerAdvice.java
deleted file mode 100644
index 8015ab1..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/advice/ConsoleRestControllerAdvice.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.console.config.advice;
-
-import lombok.extern.slf4j.Slf4j;
-import org.apache.shardingsphere.elasticjob.infra.exception.ExceptionUtils;
-import org.springframework.core.MethodParameter;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.http.converter.HttpMessageConverter;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.http.server.ServerHttpResponse;
-import org.springframework.web.bind.annotation.ExceptionHandler;
-import org.springframework.web.bind.annotation.RestControllerAdvice;
-import
org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
-
-/**
- * Console rest controller advice.
- **/
-@RestControllerAdvice
-@Slf4j
-public final class ConsoleRestControllerAdvice implements
ResponseBodyAdvice<Object> {
-
- @Override
- public boolean supports(final MethodParameter returnType, final Class<?
extends HttpMessageConverter<?>> converterType) {
- //only advice return void method.
- if (null == returnType.getMethod()) {
- return false;
- }
- return
void.class.isAssignableFrom(returnType.getMethod().getReturnType());
- }
-
- @Override
- public Object beforeBodyWrite(final Object body, final MethodParameter
returnType, final MediaType selectedContentType,
- final Class<? extends
HttpMessageConverter<?>> selectedConverterType, final ServerHttpRequest
request, final ServerHttpResponse response) {
- //if the method return void, then the value is true and returns.
- return null == body ? true : body;
- }
-
- /**
- * Handle exception.
- *
- * @param ex exception
- * @return response result
- */
- @ExceptionHandler(Exception.class)
- public ResponseEntity<String> toResponse(final Exception ex) {
- return
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(ExceptionUtils.transform(ex));
- }
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/serializer/JsonResponseBodySerializer.java
similarity index 50%
rename from
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
rename to
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/serializer/JsonResponseBodySerializer.java
index 0a595e0..26d48ee 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/WebMvcConfig.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/config/serializer/JsonResponseBodySerializer.java
@@ -15,23 +15,32 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.elasticjob.cloud.console.config;
+package org.apache.shardingsphere.elasticjob.cloud.console.config.serializer;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.method.HandlerTypePredicate;
-import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import io.netty.handler.codec.http.HttpHeaderValues;
+import
org.apache.shardingsphere.elasticjob.restful.serializer.ResponseBodySerializer;
+
+import java.nio.charset.StandardCharsets;
/**
- * Web mvc config.
- **/
-@Configuration
-public class WebMvcConfig implements WebMvcConfigurer {
+ * Json response body serializer. Serialize object to json byte except String.
+ */
+public class JsonResponseBodySerializer implements ResponseBodySerializer {
+
+ private final Gson gson = new GsonBuilder().serializeNulls().create();
+
+ @Override
+ public String mimeType() {
+ return HttpHeaderValues.APPLICATION_JSON.toString();
+ }
@Override
- public void configurePathMatch(final PathMatchConfigurer configurer) {
- HandlerTypePredicate handlerTypePredicate =
HandlerTypePredicate.forAnnotation(RestController.class);
- configurer.addPathPrefix("/api", handlerTypePredicate);
+ public byte[] serialize(final Object responseBody) {
+ if (responseBody instanceof String) {
+ return ((String) responseBody).getBytes(StandardCharsets.UTF_8);
+ }
+ return gson.toJson(responseBody).getBytes(StandardCharsets.UTF_8);
}
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudAppController.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudAppController.java
index 0c3d5b0..8c15369 100755
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudAppController.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudAppController.java
@@ -18,8 +18,6 @@
package org.apache.shardingsphere.elasticjob.cloud.console.controller;
import com.google.gson.JsonParseException;
-import java.util.Collection;
-import java.util.Optional;
import org.apache.mesos.Protos.ExecutorID;
import org.apache.mesos.Protos.SlaveID;
import
org.apache.shardingsphere.elasticjob.cloud.config.pojo.CloudJobConfigurationPOJO;
@@ -33,21 +31,22 @@ import
org.apache.shardingsphere.elasticjob.cloud.scheduler.producer.ProducerMan
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.state.disable.app.DisableAppService;
import org.apache.shardingsphere.elasticjob.infra.exception.JobSystemException;
import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
-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 org.apache.shardingsphere.elasticjob.restful.Http;
+import org.apache.shardingsphere.elasticjob.restful.RestfulController;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ContextPath;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Mapping;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Param;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ParamSource;
+import org.apache.shardingsphere.elasticjob.restful.annotation.RequestBody;
+
+import java.util.Collection;
+import java.util.Optional;
/**
* Cloud app controller.
*/
-@RestController
-@RequestMapping("/app")
-public final class CloudAppController {
+@ContextPath("/api/app")
+public final class CloudAppController implements RestfulController {
private static CoordinatorRegistryCenter regCenter;
@@ -83,24 +82,28 @@ public final class CloudAppController {
* Register app config.
*
* @param appConfig cloud app config
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping
- public void register(@RequestBody final CloudAppConfigurationPOJO
appConfig) {
+ @Mapping(method = Http.POST)
+ public boolean register(@RequestBody final CloudAppConfigurationPOJO
appConfig) {
Optional<CloudAppConfigurationPOJO> appConfigFromZk =
appConfigService.load(appConfig.getAppName());
if (appConfigFromZk.isPresent()) {
throw new AppConfigurationException("app '%s' already existed.",
appConfig.getAppName());
}
appConfigService.add(appConfig);
+ return true;
}
/**
* Update app config.
*
* @param appConfig cloud app config
+ * @return <tt>true</tt> for operation finished.
*/
- @PutMapping
- public void update(@RequestBody final CloudAppConfigurationPOJO appConfig)
{
+ @Mapping(method = Http.PUT)
+ public boolean update(@RequestBody final CloudAppConfigurationPOJO
appConfig) {
appConfigService.update(appConfig);
+ return true;
}
/**
@@ -109,8 +112,8 @@ public final class CloudAppController {
* @param appName app name
* @return cloud app config
*/
- @GetMapping("/{appName}")
- public CloudAppConfigurationPOJO detail(@PathVariable("appName") final
String appName) {
+ @Mapping(method = Http.GET, path = "/{appName}")
+ public CloudAppConfigurationPOJO detail(@Param(name = "appName", source =
ParamSource.PATH) final String appName) {
Optional<CloudAppConfigurationPOJO> appConfig =
appConfigService.load(appName);
return appConfig.orElse(null);
}
@@ -120,7 +123,7 @@ public final class CloudAppController {
*
* @return collection of registered app configs
*/
- @GetMapping("/list")
+ @Mapping(method = Http.GET, path = "/list")
public Collection<CloudAppConfigurationPOJO> findAllApps() {
return appConfigService.loadAll();
}
@@ -131,8 +134,8 @@ public final class CloudAppController {
* @param appName app name
* @return true is disabled, otherwise not
*/
- @GetMapping("/{appName}/disable")
- public boolean isDisabled(@PathVariable("appName") final String appName) {
+ @Mapping(method = Http.GET, path = "/{appName}/disable")
+ public boolean isDisabled(@Param(name = "appName", source =
ParamSource.PATH) final String appName) {
return disableAppService.isDisabled(appName);
}
@@ -140,9 +143,10 @@ public final class CloudAppController {
* Disable app config.
*
* @param appName app name
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/{appName}/disable")
- public void disable(@PathVariable("appName") final String appName) {
+ @Mapping(method = Http.POST, path = "/{appName}/disable")
+ public boolean disable(@Param(name = "appName", source = ParamSource.PATH)
final String appName) {
if (appConfigService.load(appName).isPresent()) {
disableAppService.add(appName);
for (CloudJobConfigurationPOJO each : jobConfigService.loadAll()) {
@@ -151,15 +155,17 @@ public final class CloudAppController {
}
}
}
+ return true;
}
/**
* Enable app.
*
* @param appName app name
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/{appName}/enable")
- public void enable(@PathVariable("appName") final String appName) {
+ @Mapping(method = Http.POST, path = "/{appName}/enable")
+ public boolean enable(@Param(name = "appName", source = ParamSource.PATH)
final String appName) {
if (appConfigService.load(appName).isPresent()) {
disableAppService.remove(appName);
for (CloudJobConfigurationPOJO each : jobConfigService.loadAll()) {
@@ -168,19 +174,22 @@ public final class CloudAppController {
}
}
}
+ return true;
}
/**
* Deregister app.
*
* @param appName app name
+ * @return <tt>true</tt> for operation finished.
*/
- @DeleteMapping("/{appName}")
- public void deregister(@PathVariable("appName") final String appName) {
+ @Mapping(method = Http.DELETE, path = "/{appName}")
+ public boolean deregister(@Param(name = "appName", source =
ParamSource.PATH) final String appName) {
if (appConfigService.load(appName).isPresent()) {
removeAppAndJobConfigurations(appName);
stopExecutors(appName);
}
+ return true;
}
private void removeAppAndJobConfigurations(final String appName) {
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobController.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobController.java
index ce357b1..f5919aa 100755
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobController.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobController.java
@@ -38,19 +38,17 @@ import
org.apache.shardingsphere.elasticjob.cloud.statistics.type.task.TaskRunni
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.restful.Http;
+import org.apache.shardingsphere.elasticjob.restful.wrapper.QueryParameterMap;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ParamSource;
+import org.apache.shardingsphere.elasticjob.restful.RestfulController;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ContextPath;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Mapping;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Param;
+import org.apache.shardingsphere.elasticjob.restful.annotation.RequestBody;
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;
@@ -71,9 +69,8 @@ import java.util.Set;
* Cloud job restful api.
*/
@Slf4j
-@RestController
-@RequestMapping("/job")
-public final class CloudJobController {
+@ContextPath("/api/job")
+public final class CloudJobController implements RestfulController {
private static CoordinatorRegistryCenter regCenter;
@@ -108,86 +105,106 @@ public final class CloudJobController {
/**
* Register cloud job.
+ *
* @param cloudJobConfig cloud job configuration
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/register")
- public void register(@RequestBody final CloudJobConfigurationPOJO
cloudJobConfig) {
+ @Mapping(method = Http.POST, path = "/register")
+ public boolean register(@RequestBody final CloudJobConfigurationPOJO
cloudJobConfig) {
producerManager.register(cloudJobConfig);
+ return true;
}
/**
* Update cloud job.
+ *
* @param cloudJobConfig cloud job configuration
+ * @return <tt>true</tt> for operation finished.
*/
- @PutMapping("/update")
- public void update(@RequestBody final CloudJobConfigurationPOJO
cloudJobConfig) {
+ @Mapping(method = Http.PUT, path = "/update")
+ public boolean update(@RequestBody final CloudJobConfigurationPOJO
cloudJobConfig) {
producerManager.update(cloudJobConfig);
+ return true;
}
/**
* Deregister cloud job.
+ *
* @param jobName job name
+ * @return <tt>true</tt> for operation finished.
*/
- @DeleteMapping("/{jobName}/deregister")
- public void deregister(@PathVariable final String jobName) {
+ @Mapping(method = Http.DELETE, path = "/{jobName}/deregister")
+ public boolean deregister(@Param(name = "jobName", source =
ParamSource.PATH) final String jobName) {
producerManager.deregister(jobName);
+ return true;
}
/**
* 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) {
+ @Mapping(method = Http.GET, path = "/{jobName}/disable")
+ public boolean isDisabled(@Param(name = "jobName", source =
ParamSource.PATH) final String jobName) {
return facadeService.isJobDisabled(jobName);
}
/**
* Enable cloud job.
+ *
* @param jobName job name
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/{jobName}/enable")
- public void enable(@PathVariable("jobName") final String jobName) {
+ @Mapping(method = Http.POST, path = "/{jobName}/enable")
+ public boolean enable(@Param(name = "jobName", source = ParamSource.PATH)
final String jobName) {
Optional<CloudJobConfigurationPOJO> configOptional =
configService.load(jobName);
if (configOptional.isPresent()) {
facadeService.enableJob(jobName);
producerManager.reschedule(jobName);
}
+ return true;
}
/**
* Disable cloud job.
+ *
* @param jobName job name
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/{jobName}/disable")
- public void disable(@PathVariable("jobName") final String jobName) {
+ @Mapping(method = Http.POST, path = "/{jobName}/disable")
+ public boolean disable(@Param(name = "jobName", source = ParamSource.PATH)
final String jobName) {
if (configService.load(jobName).isPresent()) {
facadeService.disableJob(jobName);
producerManager.unschedule(jobName);
}
+ return true;
}
/**
* Trigger job once.
+ *
* @param jobName job name
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/trigger")
- public void trigger(@RequestBody final String jobName) {
+ @Mapping(method = Http.POST, path = "/trigger")
+ public boolean 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);
+ return true;
}
/**
* Query job detail.
+ *
* @param jobName job name
* @return the job detail
*/
- @GetMapping("/jobs/{jobName}")
- public CloudJobConfigurationPOJO detail(@PathVariable("jobName") final
String jobName) {
+ @Mapping(method = Http.GET, path = "/jobs/{jobName}")
+ public CloudJobConfigurationPOJO detail(@Param(name = "jobName", source =
ParamSource.PATH) final String jobName) {
Optional<CloudJobConfigurationPOJO> cloudJobConfig =
configService.load(jobName);
return cloudJobConfig.orElse(null);
}
@@ -196,7 +213,7 @@ public final class CloudJobController {
* Find all jobs.
* @return all jobs
*/
- @GetMapping("/jobs")
+ @Mapping(method = Http.GET, path = "/jobs")
public Collection<CloudJobConfigurationPOJO> findAllJobs() {
return configService.loadAll();
}
@@ -205,7 +222,7 @@ public final class CloudJobController {
* Find all running tasks.
* @return all running tasks
*/
- @GetMapping("tasks/running")
+ @Mapping(method = Http.GET, path = "/tasks/running")
public Collection<TaskContext> findAllRunningTasks() {
List<TaskContext> result = new LinkedList<>();
for (Set<TaskContext> each :
facadeService.getAllRunningTasks().values()) {
@@ -218,7 +235,7 @@ public final class CloudJobController {
* Find all ready tasks.
* @return collection of all ready tasks
*/
- @GetMapping("tasks/ready")
+ @Mapping(method = Http.GET, path = "/tasks/ready")
public Collection<Map<String, String>> findAllReadyTasks() {
Map<String, Integer> readyTasks = facadeService.getAllReadyTasks();
List<Map<String, String>> result = new ArrayList<>(readyTasks.size());
@@ -235,7 +252,7 @@ public final class CloudJobController {
* Find all failover tasks.
* @return collection of all the failover tasks
*/
- @GetMapping("tasks/failover")
+ @Mapping(method = Http.GET, path = "/tasks/failover")
public Collection<FailoverTaskInfo> findAllFailoverTasks() {
List<FailoverTaskInfo> result = new LinkedList<>();
for (Collection<FailoverTaskInfo> each :
facadeService.getAllFailoverTasks().values()) {
@@ -250,12 +267,12 @@ public final class CloudJobController {
* @return job execution event
* @throws ParseException parse exception
*/
- @GetMapping("events/executions")
- public JobEventRdbSearch.Result<JobExecutionEvent>
findJobExecutionEvents(@RequestParam final MultiValueMap<String, String>
requestParams) throws ParseException {
+ @Mapping(method = Http.GET, path = "/events/executions")
+ public JobEventRdbSearch.Result<JobExecutionEvent>
findJobExecutionEvents(final QueryParameterMap requestParams) throws
ParseException {
if (!isRdbConfigured()) {
return new JobEventRdbSearch.Result<>(0, Collections.emptyList());
}
- return
jobEventRdbSearch.findJobExecutionEvents(buildCondition(requestParams, new
String[]{"jobName", "taskId", "ip", "isSuccess"}));
+ return
jobEventRdbSearch.findJobExecutionEvents(buildCondition(requestParams.toSingleValueMap(),
new String[]{"jobName", "taskId", "ip", "isSuccess"}));
}
/**
@@ -264,47 +281,47 @@ public final class CloudJobController {
* @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 {
+ @Mapping(method = Http.GET, path = "/events/statusTraces")
+ public JobEventRdbSearch.Result<JobStatusTraceEvent>
findJobStatusTraceEvents(final QueryParameterMap requestParams) throws
ParseException {
if (!isRdbConfigured()) {
return new JobEventRdbSearch.Result<>(0, Collections.emptyList());
}
- return
jobEventRdbSearch.findJobStatusTraceEvents(buildCondition(requestParams, new
String[]{"jobName", "taskId", "slaveId", "source", "executionType", "state"}));
+ return
jobEventRdbSearch.findJobStatusTraceEvents(buildCondition(requestParams.toSingleValueMap(),
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 {
+ private JobEventRdbSearch.Condition buildCondition(final Map<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.get("per_page"))) {
+ perPage = Integer.parseInt(requestParams.get("per_page"));
}
- if (!Strings.isNullOrEmpty(requestParams.getFirst("page"))) {
- page = Integer.parseInt(requestParams.getFirst("page"));
+ if (!Strings.isNullOrEmpty(requestParams.get("page"))) {
+ page = Integer.parseInt(requestParams.get("page"));
}
- String sort = requestParams.getFirst("sort");
- String order = requestParams.getFirst("order");
+ String sort = requestParams.get("sort");
+ String order = requestParams.get("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.get("startTime"))) {
+ startTime = simpleDateFormat.parse(requestParams.get("startTime"));
}
- if (!Strings.isNullOrEmpty(requestParams.getFirst("endTime"))) {
- endTime =
simpleDateFormat.parse(requestParams.getFirst("endTime"));
+ if (!Strings.isNullOrEmpty(requestParams.get("endTime"))) {
+ endTime = simpleDateFormat.parse(requestParams.get("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) {
+ private Map<String, Object> getQueryParameters(final Map<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));
+ if (!Strings.isNullOrEmpty(requestParams.get(each))) {
+ result.put(each, requestParams.get(each));
}
}
return result;
@@ -312,11 +329,12 @@ public final class CloudJobController {
/**
* 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) {
+ @Mapping(method = Http.GET, path = "/statistics/tasks/results")
+ public List<TaskResultStatistics> findTaskResultStatistics(@Param(name =
"since", source = ParamSource.QUERY, required = false) final String since) {
if ("last24hours".equals(since)) {
return statisticManager.findTaskResultStatisticsDaily();
} else {
@@ -326,11 +344,12 @@ public final class CloudJobController {
/**
* 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) {
+ @Mapping(method = Http.GET, path = "/statistics/tasks/results/{period}")
+ public TaskResultStatistics getTaskResultStatistics(@Param(name =
"period", source = ParamSource.PATH, required = false) final String period) {
switch (period) {
case "online":
return statisticManager.getTaskResultStatisticsSinceOnline();
@@ -347,11 +366,12 @@ public final class CloudJobController {
/**
* 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) {
+ @Mapping(method = Http.GET, path = "/statistics/tasks/running")
+ public List<TaskRunningStatistics> findTaskRunningStatistics(@Param(name =
"since", source = ParamSource.QUERY, required = false) final String since) {
if ("lastWeek".equals(since)) {
return statisticManager.findTaskRunningStatisticsWeekly();
} else {
@@ -363,18 +383,19 @@ public final class CloudJobController {
* Get job execution type statistics.
* @return job execution statistics
*/
- @GetMapping("/statistics/jobs/executionType")
+ @Mapping(method = Http.GET, path = "/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) {
+ @Mapping(method = Http.GET, path = "/statistics/jobs/running")
+ public List<JobRunningStatistics> findJobRunningStatistics(@Param(name =
"since", source = ParamSource.QUERY, required = false) final String since) {
if ("lastWeek".equals(since)) {
return statisticManager.findJobRunningStatisticsWeekly();
} else {
@@ -386,7 +407,7 @@ public final class CloudJobController {
* Find job register statistics.
* @return collection of job register statistics since online
*/
- @GetMapping("/statistics/jobs/register")
+ @Mapping(method = Http.GET, path = "/statistics/jobs/register")
public List<JobRegisterStatistics> findJobRegisterStatistics() {
return statisticManager.findJobRegisterStatisticsSinceOnline();
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudOperationController.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudOperationController.java
index a638a8a..85f4837 100755
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudOperationController.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudOperationController.java
@@ -20,25 +20,26 @@ package
org.apache.shardingsphere.elasticjob.cloud.console.controller;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.gson.JsonParseException;
-import java.util.Collection;
-import java.util.Map;
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.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 org.apache.shardingsphere.elasticjob.restful.Http;
+import org.apache.shardingsphere.elasticjob.restful.RestfulController;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ContextPath;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Mapping;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Param;
+import org.apache.shardingsphere.elasticjob.restful.annotation.ParamSource;
+
+import java.util.Collection;
+import java.util.Map;
/**
* Cloud operation restful api.
*/
@Slf4j
-@RestController
-@RequestMapping("/operate")
-public final class CloudOperationController {
+@ContextPath("/api/operate")
+public final class CloudOperationController implements RestfulController {
private static ReconcileService reconcileService;
@@ -61,20 +62,26 @@ public final class CloudOperationController {
/**
* Explicit reconcile service.
+ *
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/reconcile/explicit")
- public void explicitReconcile() {
+ @Mapping(method = Http.POST, path = "/reconcile/explicit")
+ public boolean explicitReconcile() {
validReconcileInterval();
reconcileService.explicitReconcile();
+ return true;
}
/**
* Implicit reconcile service.
+ *
+ * @return <tt>true</tt> for operation finished.
*/
- @PostMapping("/reconcile/implicit")
- public void implicitReconcile() {
+ @Mapping(method = Http.POST, path = "/reconcile/implicit")
+ public boolean implicitReconcile() {
validReconcileInterval();
reconcileService.implicitReconcile();
+ return true;
}
private void validReconcileInterval() {
@@ -91,8 +98,8 @@ public final class CloudOperationController {
* @return sandbox info
* @throws JsonParseException parse json exception
*/
- @GetMapping("/sandbox")
- public Collection<Map<String, String>> sandbox(@RequestParam("appName")
final String appName) throws JsonParseException {
+ @Mapping(method = Http.GET, path = "/sandbox")
+ public Collection<Map<String, String>> sandbox(@Param(name = "appName",
source = ParamSource.QUERY) final String appName) throws JsonParseException {
Preconditions.checkArgument(!Strings.isNullOrEmpty(appName), "Lack
param 'appName'");
return mesosStateService.sandbox(appName);
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/AuthenticationResult.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/AuthenticationResult.java
deleted file mode 100644
index 6467a5a..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/AuthenticationResult.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.console.security;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.Setter;
-
-/**
- * Authentication result.
- **/
-@Getter
-@Setter
-@RequiredArgsConstructor
-public final class AuthenticationResult {
-
- private final boolean success;
-
- private final boolean isGuest;
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/UserAuthenticationService.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/UserAuthenticationService.java
deleted file mode 100644
index c9132db..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/UserAuthenticationService.java
+++ /dev/null
@@ -1,57 +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.console.security;
-
-import lombok.Getter;
-import lombok.Setter;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-/**
- * User authentication service.
- **/
-@Component
-@ConfigurationProperties(prefix = "auth")
-@Getter
-@Setter
-public class UserAuthenticationService {
-
- private String rootUsername;
-
- private String rootPassword;
-
- private String guestUsername;
-
- private String guestPassword;
-
- /**
- * Check user.
- *
- * @param authorization authorization
- * @return authorization result
- */
- public AuthenticationResult checkUser(final String authorization) {
- if ((rootUsername + ":" + rootPassword).equals(authorization)) {
- return new AuthenticationResult(true, false);
- } else if ((guestUsername + ":" +
guestPassword).equals(authorization)) {
- return new AuthenticationResult(true, true);
- } else {
- return new AuthenticationResult(false, false);
- }
- }
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/WwwAuthFilter.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/WwwAuthFilter.java
deleted file mode 100755
index a7a4a59..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/java/org/apache/shardingsphere/elasticjob/cloud/console/security/WwwAuthFilter.java
+++ /dev/null
@@ -1,89 +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.console.security;
-
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.codec.binary.Base64;
-
-/**
- * WWW auth filter.
- */
-@Slf4j
-public final class WwwAuthFilter implements Filter {
-
- private static final String AUTH_PREFIX = "Basic ";
-
- private static final String ROOT_IDENTIFY = "root";
-
- private static final String GUEST_IDENTIFY = "guest";
-
- @Setter
- private UserAuthenticationService userAuthenticationService;
-
- @Override
- public void init(final FilterConfig filterConfig) {
- }
-
- @Override
- public void doFilter(final ServletRequest request, final ServletResponse
response, final FilterChain chain) throws IOException, ServletException {
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- String authorization = httpRequest.getHeader("authorization");
- if (null != authorization && authorization.length() >
AUTH_PREFIX.length()) {
- authorization = new
String(Base64.decodeBase64(authorization.substring(AUTH_PREFIX.length())));
- AuthenticationResult authenticationResult =
userAuthenticationService.checkUser(authorization);
- if (authenticationResult.isSuccess()) {
- authenticateSuccess(httpResponse,
authenticationResult.isGuest());
- chain.doFilter(httpRequest, httpResponse);
- } else {
- needAuthenticate(httpResponse);
- }
- } else {
- needAuthenticate(httpResponse);
- }
- }
-
- private void authenticateSuccess(final HttpServletResponse response, final
boolean isGuest) {
- response.setStatus(200);
- response.setHeader("Pragma", "No-cache");
- response.setHeader("Cache-Control", "no-store");
- response.setDateHeader("Expires", 0);
- response.setHeader("identify", isGuest ? GUEST_IDENTIFY :
ROOT_IDENTIFY);
- }
-
- private void needAuthenticate(final HttpServletResponse response) {
- response.setStatus(401);
- response.setHeader("Cache-Control", "no-store");
- response.setDateHeader("Expires", 0);
- response.setHeader("WWW-authenticate", AUTH_PREFIX + "Realm=\"Elastic
Job Console Auth\"");
- }
-
- @Override
- public void destroy() {
- }
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/application.properties
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/META-INF/services/org.apache.shardingsphere.elasticjob.restful.serializer.ResponseBodySerializer
similarity index 89%
rename from
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/application.properties
rename to
elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/META-INF/services/org.apache.shardingsphere.elasticjob.restful.serializer.ResponseBodySerializer
index b750ea0..d640130 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/application.properties
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/main/resources/META-INF/services/org.apache.shardingsphere.elasticjob.restful.serializer.ResponseBodySerializer
@@ -14,5 +14,5 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-# Default web server port
-server.port=8899
+
+org.apache.shardingsphere.elasticjob.cloud.console.config.serializer.JsonResponseBodySerializer
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/AbstractCloudControllerTest.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/AbstractCloudControllerTest.java
index 28cfd78..882867c 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/AbstractCloudControllerTest.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/AbstractCloudControllerTest.java
@@ -25,16 +25,18 @@ import
org.apache.shardingsphere.elasticjob.cloud.scheduler.env.RestfulServerCon
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.FacadeService;
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.MesosStateService;
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.ReconcileService;
-import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.master.MesosMasterServerMockConfiguration;
-import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.slave.MesosSlaveServerMockConfiguration;
+import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.master.MesosMasterServerMock;
+import
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.slave.MesosSlaveServerMock;
import
org.apache.shardingsphere.elasticjob.cloud.scheduler.producer.ProducerManager;
import org.apache.shardingsphere.elasticjob.reg.base.CoordinatorRegistryCenter;
+import org.apache.shardingsphere.elasticjob.restful.NettyRestfulService;
+import
org.apache.shardingsphere.elasticjob.restful.NettyRestfulServiceConfiguration;
+import org.apache.shardingsphere.elasticjob.restful.RestfulService;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
-import org.springframework.context.ConfigurableApplicationContext;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@@ -50,12 +52,12 @@ public abstract class AbstractCloudControllerTest {
private static ConsoleBootstrap consoleBootstrap;
- private static ConfigurableApplicationContext masterServer;
+ private static RestfulService masterServer;
- private static ConfigurableApplicationContext slaveServer;
+ private static RestfulService slaveServer;
@BeforeClass
- public static void setUpClass() throws Exception {
+ public static void setUpClass() {
initRestfulServer();
initMesosServer();
}
@@ -73,19 +75,21 @@ public abstract class AbstractCloudControllerTest {
private static void initMesosServer() {
MesosStateService.register("127.0.0.1", 9050);
- ConsoleBootstrap.ConsoleApplication.setPort(9050);
- ConsoleBootstrap.ConsoleApplication.setExtraSources(new
Class[]{MesosMasterServerMockConfiguration.class});
- masterServer = ConsoleBootstrap.ConsoleApplication.start();
- ConsoleBootstrap.ConsoleApplication.setPort(9051);
- ConsoleBootstrap.ConsoleApplication.setExtraSources(new
Class[]{MesosSlaveServerMockConfiguration.class});
- slaveServer = ConsoleBootstrap.ConsoleApplication.start();
+ NettyRestfulServiceConfiguration masterServerConfiguration = new
NettyRestfulServiceConfiguration(9050);
+ masterServerConfiguration.addControllerInstance(new
MesosMasterServerMock());
+ masterServer = new NettyRestfulService(masterServerConfiguration);
+ masterServer.startup();
+ NettyRestfulServiceConfiguration slaveServerConfiguration = new
NettyRestfulServiceConfiguration(9051);
+ slaveServerConfiguration.addControllerInstance(new
MesosSlaveServerMock());
+ slaveServer = new NettyRestfulService(slaveServerConfiguration);
+ slaveServer.startup();
}
@AfterClass
public static void tearDown() {
consoleBootstrap.stop();
- masterServer.stop();
- slaveServer.stop();
+ masterServer.shutdown();
+ slaveServer.shutdown();
MesosStateService.deregister();
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobControllerTest.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobControllerTest.java
index d635240..ba5ad70 100644
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobControllerTest.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/console/controller/CloudJobControllerTest.java
@@ -189,7 +189,10 @@ public class CloudJobControllerTest extends
AbstractCloudControllerTest {
@Test
public void assertFindJobExecutionEventsWhenNotConfigRDB() {
ReflectionUtils.setStaticFieldValue(CloudJobController.class,
"jobEventRdbSearch", null);
-
assertThat(HttpTestUtil.get("http://127.0.0.1:19000/api/job/events/executions"),
is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0,
+ Map<String, String> query = new HashMap<>();
+ query.put("per_page", "10");
+ query.put("page", "1");
+
assertThat(HttpTestUtil.get("http://127.0.0.1:19000/api/job/events/executions",
query), is(GsonFactory.getGson().toJson(new JobEventRdbSearch.Result<>(0,
Collections.<JobExecutionEvent>emptyList()))));
}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMock.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMock.java
index c9a53fc..f794e65 100755
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMock.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMock.java
@@ -17,23 +17,18 @@
package
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.master;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.apache.shardingsphere.elasticjob.restful.Http;
+import org.apache.shardingsphere.elasticjob.restful.RestfulController;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Mapping;
-@Controller
-@RequestMapping("/")
-public class MesosMasterServerMock {
+public class MesosMasterServerMock implements RestfulController {
/**
* Check master server state.
*
* @return json object
*/
- @ResponseBody
- @GetMapping(value = "/state", produces = MediaType.APPLICATION_JSON_VALUE)
+ @Mapping(method = Http.GET, path = "/state")
public String state() {
return "{\"version\":\"1.1.0\",\"build_date\":\"2017-02-27
10:51:31\",\"build_time\":1488163891.0,\"build_user\":\"user\",\"start_time\""
+
":1488179758.62289,\"elected_time\":1488179758.69795,\"id\":\"d8701508-41b7-471e-9b32-61cf824a660d\",\"pid\":\"[email protected]:9050\",\"hostname\":\"127.0.0.1\","
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMockConfiguration.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMockConfiguration.java
deleted file mode 100644
index be34e49..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/master/MesosMasterServerMockConfiguration.java
+++ /dev/null
@@ -1,38 +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.scheduler.mesos.fixture.master;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Mesos master server configuration.
- **/
-@Configuration
-public class MesosMasterServerMockConfiguration {
-
- /**
- * inject mesos master server mock.
- *
- * @return mesos master server mock.
- */
- @Bean
- public MesosMasterServerMock mesosMasterServerMock() {
- return new MesosMasterServerMock();
- }
-}
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMock.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMock.java
index 9de423d..800ed86 100755
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMock.java
+++
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMock.java
@@ -17,23 +17,18 @@
package
org.apache.shardingsphere.elasticjob.cloud.scheduler.mesos.fixture.slave;
-import org.springframework.http.MediaType;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.ResponseBody;
+import org.apache.shardingsphere.elasticjob.restful.Http;
+import org.apache.shardingsphere.elasticjob.restful.RestfulController;
+import org.apache.shardingsphere.elasticjob.restful.annotation.Mapping;
-@Controller
-@RequestMapping("/")
-public class MesosSlaveServerMock {
+public class MesosSlaveServerMock implements RestfulController {
/**
* Check slave server state.
*
* @return json object
*/
- @ResponseBody
- @GetMapping(value = "/state", produces = MediaType.APPLICATION_JSON_VALUE)
+ @Mapping(method = Http.GET, path = "/state")
public String state() {
return "{\"version\":\"1.1.0\",\"build_date\":\"2017-02-27
10:51:31\",\"build_time\":1488163891.0,\"build_user\":\"gaohon"
+
"gtao\",\"start_time\":1488179767.60204,\"id\":\"d8701508-41b7-471e-9b32-61cf824a660d-S0\",\"pid\":\"slave(1)@"
diff --git
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMockConfiguration.java
b/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMockConfiguration.java
deleted file mode 100644
index 4db6590..0000000
---
a/elasticjob-cloud/elasticjob-cloud-scheduler/src/test/java/org/apache/shardingsphere/elasticjob/cloud/scheduler/mesos/fixture/slave/MesosSlaveServerMockConfiguration.java
+++ /dev/null
@@ -1,38 +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.scheduler.mesos.fixture.slave;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * Mesos slave server configuration.
- **/
-@Configuration
-public class MesosSlaveServerMockConfiguration {
-
- /**
- * inject mesos slave server mock.
- *
- * @return mesos slave server mock
- */
- @Bean
- public MesosSlaveServerMock mesosSlaveServerMock() {
- return new MesosSlaveServerMock();
- }
-}