add spring actuator, and api version and prefix support
This commit is contained in:
parent
3b75eb6ed6
commit
6b65fa8e20
10
doc-gitlab-runner.md
Normal file
10
doc-gitlab-runner.md
Normal file
@ -0,0 +1,10 @@
|
||||
# gitlab runner
|
||||
|
||||
command used to register new runner
|
||||
|
||||
```shell script
|
||||
$ docker run -d --name gitlab-runner --restart always -v /var/run/docker.sock:/var/run/docker.sock -v gitlab-runner-config:/etc/gitlab-runner gitlab/gitlab-runner:latest
|
||||
|
||||
$ gitlab-runner register -non-interactive --description "manualy registered gitlab runner" --url "http://172.17.0.1
|
||||
:8080/" --registration-token "registration_token" --tag-list "docker,manual"
|
||||
```
|
4
pom.xml
4
pom.xml
@ -54,6 +54,10 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
11
src/main/java/tk/antoine_roux/wiki/Constant.java
Normal file
11
src/main/java/tk/antoine_roux/wiki/Constant.java
Normal file
@ -0,0 +1,11 @@
|
||||
package tk.antoine_roux.wiki;
|
||||
|
||||
/**
|
||||
* Application level constant
|
||||
*/
|
||||
public final class Constant {
|
||||
public static final String API_PREFIX = "/api";
|
||||
public static final String API_NAME = "gitlab-runner-gateway";
|
||||
public static final String API_VERSION = "4";
|
||||
public static final String VERSION_PREFIX = "v";
|
||||
}
|
58
src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java
Normal file
58
src/main/java/tk/antoine_roux/wiki/ControllerHandlers.java
Normal file
@ -0,0 +1,58 @@
|
||||
package tk.antoine_roux.wiki;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import tk.antoine_roux.wiki.annotation.ApiPrefix;
|
||||
import tk.antoine_roux.wiki.annotation.ApiVersion;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
import static tk.antoine_roux.wiki.Constant.*;
|
||||
|
||||
@RestController
|
||||
@ApiPrefix(API_PREFIX)
|
||||
public class ControllerHandlers {
|
||||
|
||||
private RunnerRegistrar runnerRegistrar;
|
||||
|
||||
@Autowired
|
||||
public ControllerHandlers(RunnerRegistrar runnerRegistrar) {
|
||||
this.runnerRegistrar = runnerRegistrar;
|
||||
}
|
||||
|
||||
/**
|
||||
* add register new runners
|
||||
*
|
||||
* @param body
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@ApiVersion({API_VERSION})
|
||||
@PostMapping(value = "/runners", produces = APPLICATION_JSON_VALUE)
|
||||
public static ResponseEntity<String> addRunner(@RequestBody String body) {
|
||||
System.out.println(body);
|
||||
return ResponseEntity.ok(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* hello test endpoint
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@ResponseBody
|
||||
@GetMapping("/info")
|
||||
public static ResponseEntity<TreeMap<String, String>> info() {
|
||||
return ResponseEntity.ok(
|
||||
// sort attribute by key name
|
||||
new TreeMap<>(
|
||||
Map.of(
|
||||
"api-version", VERSION_PREFIX + API_VERSION,
|
||||
"api-name", API_NAME
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -1,9 +1,7 @@
|
||||
package tk.antoine_roux.wiki;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.servlet.function.RouterFunction;
|
||||
import org.springframework.web.servlet.function.RouterFunctions;
|
||||
import org.springframework.web.servlet.function.ServerResponse;
|
||||
@ -15,9 +13,6 @@ import org.springframework.web.servlet.function.ServerResponse;
|
||||
@SpringBootApplication(proxyBeanMethods = false)
|
||||
public class MainLauncher {
|
||||
|
||||
@Value("${wikiproject.basePath}")
|
||||
private String basePath;
|
||||
|
||||
/**
|
||||
* Entrypoint for application
|
||||
*/
|
||||
@ -28,11 +23,11 @@ public class MainLauncher {
|
||||
/**
|
||||
* Routing declaration
|
||||
*/
|
||||
@Bean
|
||||
// @Bean
|
||||
public RouterFunction<ServerResponse> routes() {
|
||||
return RouterFunctions.route()
|
||||
.GET(this.basePath + "/hello", serverRequest ->
|
||||
ServerResponse.ok().body("Hello world !")
|
||||
).build();
|
||||
// .POST("/runners", accept(APPLICATION_FORM_URLENCODED), ControllerHandlers::addRunner)
|
||||
// .GET("/hello", ControllerHandlers::hello)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
41
src/main/java/tk/antoine_roux/wiki/RunnerRegistrar.java
Normal file
41
src/main/java/tk/antoine_roux/wiki/RunnerRegistrar.java
Normal file
@ -0,0 +1,41 @@
|
||||
package tk.antoine_roux.wiki;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Class use to perist registered gitlab runner
|
||||
*/
|
||||
@Service
|
||||
public class RunnerRegistrar {
|
||||
private final List<Runner> runners = new ArrayList<>();
|
||||
|
||||
public List<Runner> getRunners() {
|
||||
return this.runners;
|
||||
}
|
||||
|
||||
public void addRunner(Runner r) {
|
||||
this.runners.add(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* in memory representation of gitlab runner
|
||||
*/
|
||||
public static class Runner {
|
||||
private static final String TAG_SEPARATOR = ",";
|
||||
|
||||
public String id;
|
||||
public String description;
|
||||
public String[] tags;
|
||||
public String registrationToken;
|
||||
|
||||
public Runner(String id, String description, String tags, String registrationToken) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
this.tags = tags.split(TAG_SEPARATOR);
|
||||
this.registrationToken = registrationToken;
|
||||
}
|
||||
}
|
||||
}
|
12
src/main/java/tk/antoine_roux/wiki/annotation/ApiPrefix.java
Normal file
12
src/main/java/tk/antoine_roux/wiki/annotation/ApiPrefix.java
Normal file
@ -0,0 +1,12 @@
|
||||
package tk.antoine_roux.wiki.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ApiPrefix {
|
||||
String value() default "";
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package tk.antoine_roux.wiki.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ApiVersion {
|
||||
String[] value() default {""};
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package tk.antoine_roux.wiki.configuration;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.web.servlet.mvc.condition.*;
|
||||
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import tk.antoine_roux.wiki.annotation.ApiPrefix;
|
||||
import tk.antoine_roux.wiki.annotation.ApiVersion;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* create custom {@link org.springframework.web.bind.annotation.RequestMapping} Handler to add versioning into uri
|
||||
*/
|
||||
public class ApiVersionRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
|
||||
|
||||
private final String versionPrefix;
|
||||
|
||||
/**
|
||||
* create @{@link org.springframework.web.bind.annotation.RequestMapping} handler classe
|
||||
* this class add some prefix to uri
|
||||
*
|
||||
* @param versionPrefix
|
||||
*/
|
||||
public ApiVersionRequestMappingHandlerMapping(String versionPrefix) {
|
||||
this.versionPrefix = versionPrefix;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
RequestMappingInfo info = super.getMappingForMethod(method, handlerType);
|
||||
if (info == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ApiVersion methodAnnotation = AnnotationUtils.findAnnotation(method, ApiVersion.class);
|
||||
if (methodAnnotation != null) {
|
||||
RequestCondition<?> methodCondition = this.getCustomMethodCondition(method);
|
||||
// Concatenate our ApiVersion with the usual request mapping
|
||||
info = this.createApiVersionInfo(methodAnnotation, methodCondition).combine(info);
|
||||
} else {
|
||||
ApiVersion typeAnnotation = AnnotationUtils.findAnnotation(handlerType, ApiVersion.class);
|
||||
if (typeAnnotation != null) {
|
||||
RequestCondition<?> typeCondition = this.getCustomTypeCondition(handlerType);
|
||||
// Concatenate our ApiVersion with the usual request mapping
|
||||
info = this.createApiVersionInfo(typeAnnotation, typeCondition).combine(info);
|
||||
}
|
||||
}
|
||||
|
||||
ApiPrefix annotationApiPrefix = AnnotationUtils.findAnnotation(handlerType, ApiPrefix.class);
|
||||
if (annotationApiPrefix != null) {
|
||||
RequestMappingInfo requestMappingInfo = new RequestMappingInfo(
|
||||
new PatternsRequestCondition(
|
||||
new String[]{annotationApiPrefix.value()},
|
||||
this.getUrlPathHelper(), this.getPathMatcher(),
|
||||
false
|
||||
),
|
||||
new RequestMethodsRequestCondition(),
|
||||
new ParamsRequestCondition(),
|
||||
new HeadersRequestCondition(),
|
||||
new ConsumesRequestCondition(),
|
||||
new ProducesRequestCondition(),
|
||||
null);
|
||||
info = requestMappingInfo.combine(info);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private RequestMappingInfo createApiVersionInfo(ApiVersion annotation, RequestCondition<?> customCondition) {
|
||||
String[] values = annotation.value();
|
||||
String[] patterns = new String[values.length];
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
// Build the URL prefix
|
||||
patterns[i] = this.versionPrefix + values[i];
|
||||
}
|
||||
|
||||
return new RequestMappingInfo(
|
||||
new PatternsRequestCondition(
|
||||
patterns, this.getUrlPathHelper(), this.getPathMatcher(),
|
||||
false
|
||||
// , this.useTrailingSlashMatch(), this.getFileExtensions()
|
||||
),
|
||||
new RequestMethodsRequestCondition(),
|
||||
new ParamsRequestCondition(),
|
||||
new HeadersRequestCondition(),
|
||||
new ConsumesRequestCondition(),
|
||||
new ProducesRequestCondition(),
|
||||
customCondition);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package tk.antoine_roux.wiki.configuration;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceUrlProvider;
|
||||
import tk.antoine_roux.wiki.Constant;
|
||||
|
||||
/**
|
||||
* spring web configuration
|
||||
*/
|
||||
@Configuration
|
||||
public class WebConfiguration extends WebMvcConfigurationSupport {
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping(ContentNegotiationManager contentNegotiationManager,
|
||||
FormattingConversionService conversionService,
|
||||
ResourceUrlProvider resourceUrlProvider) {
|
||||
return new ApiVersionRequestMappingHandlerMapping(Constant.VERSION_PREFIX);
|
||||
}
|
||||
}
|
@ -1,7 +1,15 @@
|
||||
spring.main.banner-mode=off
|
||||
spring.main.lazy-initialization=true
|
||||
spring.main.lazy-initialization=false
|
||||
spring.output.ansi.enabled=ALWAYS
|
||||
|
||||
server.port=^application.port^
|
||||
|
||||
wikiproject.basePath=/wikiproject
|
||||
# wikiproject.basePath=/api
|
||||
|
||||
logging.level.root=INFO
|
||||
|
||||
# spring boot actuator
|
||||
management.server.port=8080
|
||||
info.name=gitlab-runner-gateway
|
||||
info.more.detail=This is a REST API use to gateway gitlab runner call to gitlab instance
|
||||
management.endpoints.web.exposure.include=mappings
|
||||
|
Loading…
Reference in New Issue
Block a user