Skip to content

Commit 6009719

Browse files
Easy startup (elemental-source#24)
* Startup * Update version * Example webclient * Fix test
1 parent aba7748 commit 6009719

File tree

11 files changed

+166
-105
lines changed

11 files changed

+166
-105
lines changed

.docker-ignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
Dockerfile
2+
docker-compose.yml
3+
out
4+
.gradle
5+
.idea
6+
build
7+
out
8+
.gitignore
9+
.travis.yml
10+
CONTRIBUTING.md
11+
LICENSE
12+
README.md

Dockerfile

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
FROM openjdk:8-jdk as build
2+
3+
ENV BUILD_PATH /building
4+
WORKDIR $BUILD_PATH
5+
6+
COPY gradlew $BUILD_PATH/
7+
COPY gradle $BUILD_PATH/gradle
8+
# download gradle
9+
RUN ./gradlew --continue
10+
11+
COPY build.gradle $BUILD_PATH
12+
13+
# download dependencies
14+
RUN ./gradlew build; exit 0
15+
16+
COPY src $BUILD_PATH/src
17+
COPY mocks-test $BUILD_PATH/mocks-test
18+
COPY backup-temp $BUILD_PATH/backup-temp
19+
20+
RUN ./gradlew build
21+
22+
#############
23+
# Final image
24+
FROM openjdk:8-jdk
25+
MAINTAINER "elemental-source"
26+
27+
VOLUME /config
28+
VOLUME /mocks-test
29+
VOLUME /backup-temp
30+
31+
WORKDIR /
32+
33+
EXPOSE 5000
34+
EXPOSE 9090
35+
36+
ENV APP_PARAMS "--spring.config.location=file:/config/application.yml"
37+
38+
COPY --from=build /building/build/libs/*.jar app.jar
39+
ENTRYPOINT ["java", \
40+
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5000 -Djava.security.egd=file:/dev/./urandom", \
41+
"-jar", \
42+
"/app.jar", \
43+
"$APP_PARAMS"]

README.md

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -115,24 +115,27 @@ Port `9090` exposes the service while port `5000` can be used to debug the appli
115115

116116
You can check application logs from the container: `docker logs -f mock-api`
117117

118-
Example:
119-
120-
```shell
121-
docker run --rm --name mock-api \
122-
-p 9090:9090 \
123-
-p 5000:5000 \
124-
-v $(pwd)/src/test/resources:/config \
125-
-v $(pwd)/src/test/mocks-test:/data \
126-
elemental-source/mock-api:4.0.0-SNAPSHOT
127-
```
128-
129-
And then get results: `curl -X GET 'http://localhost:9090/guests/132'`
130-
131118
You can configure your program arguments in your IDE:
132119
```
133120
--spring.config.location=file/name/example/application.yml
134121
```
135122

123+
#### Using docker-compose
124+
125+
Run `docker-compose up --build`
126+
127+
Get results: `curl -X GET 'http://localhost:9090/guests/132'`
128+
129+
Look `api.host` property at `src/main/resources/application.yml` file.
130+
The value is http://www.mocky.io, the host that will be called if there is no file that dont match with request.
131+
If you create a new mock, you can call directly. Concat `localhost:9090` with the generated link, like this:
132+
133+
```shell
134+
curl -X GET 'http://localhost:9090/v2/5b4bbb0c3100003503a7de45'
135+
```
136+
137+
The response will not found at mock files and then, the external host will be called.
138+
136139
## TODO
137140

138141
- [X] Fix code Style

build.gradle

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
buildscript {
22
ext {
3-
springBootVersion = '1.5.4.RELEASE'
3+
springBootVersion = '2.0.3.RELEASE'
44
}
55
repositories {
66
mavenCentral()
@@ -14,10 +14,11 @@ buildscript {
1414
apply plugin: 'java'
1515
apply plugin: 'eclipse'
1616
apply plugin: 'org.springframework.boot'
17+
apply plugin: 'io.spring.dependency-management'
1718
apply plugin: 'jacoco'
1819
apply plugin: 'docker'
1920
apply plugin: 'findbugs'
20-
apply plugin: 'checkstyle'
21+
//apply plugin: 'checkstyle'
2122

2223
findbugs {
2324
sourceSets = [sourceSets.main]
@@ -26,11 +27,11 @@ findbugs {
2627
reportLevel = "high"
2728
}
2829

29-
checkstyle {
30-
toolVersion = '8.3'
31-
sourceSets= [sourceSets.main]
32-
ignoreFailures = true
33-
}
30+
//checkstyle {
31+
// toolVersion = '8.3'
32+
// sourceSets= [sourceSets.main]
33+
// ignoreFailures = true
34+
//}
3435

3536
version = '4.0.0-SNAPSHOT'
3637
sourceCompatibility = 1.8
@@ -40,10 +41,9 @@ repositories {
4041
}
4142

4243
dependencies {
43-
compile('org.springframework.boot:spring-boot-starter')
44-
compile 'org.springframework.boot:spring-boot-starter-undertow'
45-
compile 'org.springframework.boot:spring-boot-starter-web'
4644
compile 'org.springframework.boot:spring-boot-starter-hateoas'
45+
compile 'org.springframework.boot:spring-boot-starter-webflux'
46+
4747
compile 'com.google.code.gson:gson'
4848
compile 'javax.ws.rs:javax.ws.rs-api:2.0'
4949
compile 'net.minidev:json-smart:1.0.8'
@@ -52,7 +52,9 @@ dependencies {
5252
compile 'commons-io:commons-io:2.5'
5353
compile 'org.apache.httpcomponents:httpclient:4.4.1'
5454
compile 'com.squareup.okhttp3:okhttp:3.8.1'
55+
5556
testCompile 'org.springframework.boot:spring-boot-starter-test'
57+
testCompile 'io.projectreactor:reactor-test'
5658
testCompile 'br.com.six2six:fixture-factory:3.1.0'
5759
}
5860

docker-compose.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: '3.6'
2+
3+
services:
4+
mock_api:
5+
build: .
6+
image: elemental-source/mock-api:latest
7+
container_name: mock_api
8+
ports:
9+
- 9090:9090
10+
- 5000:5000
11+
environment:
12+
SERVER_PORT: 9090
13+
FILE_BASE: "/data"
14+
FILE_BACKUP_PATH: "/data-cache"
15+
volumes:
16+
- ./src/main/resources/application.yml:/config/application.yml
17+
- ./mocks-test:/data
18+
- ./backup-temp:/data-cache

src/main/docker/Dockerfile

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/main/java/br/com/elementalsource/mock/generic/service/impl/GenericApiServiceImpl.java

Lines changed: 42 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
import br.com.elementalsource.mock.configuration.service.CaptureExecutor;
44
import br.com.elementalsource.mock.generic.model.Endpoint;
55
import br.com.elementalsource.mock.generic.model.Request;
6+
import br.com.elementalsource.mock.generic.repository.EndpointRepository;
7+
import br.com.elementalsource.mock.generic.service.GenericApiService;
68
import br.com.elementalsource.mock.infra.component.ExternalApi;
79
import br.com.elementalsource.mock.infra.component.JsonValueCompiler;
810
import br.com.elementalsource.mock.infra.property.ApiProperty;
9-
import br.com.elementalsource.mock.generic.repository.EndpointRepository;
10-
import br.com.elementalsource.mock.generic.service.GenericApiService;
1111
import org.springframework.beans.factory.annotation.Autowired;
1212
import org.springframework.beans.factory.annotation.Qualifier;
1313
import org.springframework.http.HttpStatus;
@@ -46,66 +46,50 @@ private Optional<Endpoint> getEndpoint(Request request) {
4646
// TODO refatorar esse método
4747
@Override
4848
public Optional<ResponseEntity<String>> genericResponseEntity(Request request) {
49-
final Endpoint endpointNotSafe = getEndpoint(request).orElse(null);
50-
51-
final Optional<ResponseEntity<String>> apiResult;
52-
53-
// TODO refatorar: esta no if porque estava dando problema ao colocar
54-
// dentro do orElse()
55-
if (endpointNotSafe == null) {
56-
apiResult = externalApi.execute(request).map(r -> {
57-
captureExecutor.execute(r, new Endpoint.Builder(request, r.getApiResult()).build());
58-
return r.getApiResult();
59-
});
60-
} else {
61-
final String body = jsonValueCompiler.compile(endpointNotSafe.getResponse().getBody());
62-
apiResult = Optional.of(
63-
new ResponseEntity<>(body, endpointNotSafe.getResponse().getHttpStatus().orElse(HttpStatus.OK)));
64-
}
65-
66-
return apiResult.map(responseEntity -> {
67-
final ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.status(responseEntity.getStatusCode());
68-
69-
apiProperty.getDefaultHeaders().forEach(header -> {
70-
final String headerName = header.getHeaderName();
71-
final String[] headerValues = header.getHeaderValues().stream().toArray(String[]::new);
72-
bodyBuilder.header(headerName, headerValues);
73-
});
74-
75-
return bodyBuilder.body(responseEntity.getBody());
76-
});
49+
final Optional<ResponseEntity<String>> apiResult = getEndpoint(request).
50+
map(endpoint -> new ResponseEntity<>(jsonValueCompiler.compile(endpoint.getResponse().getBody()), endpoint.getResponse().getHttpStatus().orElse(HttpStatus.OK))).
51+
map(Optional::of).
52+
orElseGet(() -> externalApi.execute(request).map(r -> {
53+
captureExecutor.execute(r, new Endpoint.Builder(request, r.getApiResult()).build());
54+
return r.getApiResult();
55+
}));
56+
57+
return apiResult.
58+
map(responseEntity -> {
59+
final ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.status(responseEntity.getStatusCode());
60+
61+
apiProperty.getDefaultHeaders().forEach(header -> {
62+
final String headerName = header.getHeaderName();
63+
final String[] headerValues = header.getHeaderValues().toArray(new String[0]);
64+
bodyBuilder.header(headerName, headerValues);
65+
});
66+
67+
return bodyBuilder.body(responseEntity.getBody());
68+
});
7769
}
7870

7971
@Override
8072
public Optional<ResponseEntity<String>> genericResponseEntityGET(Request request, HttpServletRequest httpServletRequest) {
81-
final Endpoint endpointNotSafe = getEndpoint(request).orElse(null);
82-
83-
final Optional<ResponseEntity<String>> apiResult;
84-
85-
// TODO refatorar: esta no if porque estava dando problema ao colocar
86-
// dentro do orElse()
87-
if (endpointNotSafe == null) {
88-
apiResult = externalApi.okHttpClientRequest(httpServletRequest, request).map(r -> {
89-
captureExecutor.execute(r, new Endpoint.Builder(request, r.getApiResult()).build());
90-
return r.getApiResult();
91-
});
92-
} else {
93-
final String body = jsonValueCompiler.compile(endpointNotSafe.getResponse().getBody());
94-
apiResult = Optional.of(
95-
new ResponseEntity<>(body, endpointNotSafe.getResponse().getHttpStatus().orElse(HttpStatus.OK)));
96-
}
97-
98-
return apiResult.map(responseEntity -> {
99-
final ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.status(responseEntity.getStatusCode());
100-
101-
apiProperty.getDefaultHeaders().forEach(header -> {
102-
final String headerName = header.getHeaderName();
103-
final String[] headerValues = header.getHeaderValues().stream().toArray(String[]::new);
104-
bodyBuilder.header(headerName, headerValues);
105-
});
106-
107-
return bodyBuilder.body(responseEntity.getBody());
108-
});
73+
final Optional<ResponseEntity<String>> apiResult = getEndpoint(request).
74+
map(endpoint -> new ResponseEntity<>(jsonValueCompiler.compile(endpoint.getResponse().getBody()), endpoint.getResponse().getHttpStatus().orElse(HttpStatus.OK))).
75+
map(Optional::of).
76+
orElseGet(() -> externalApi.okHttpClientRequest(httpServletRequest, request).map(r -> {
77+
captureExecutor.execute(r, new Endpoint.Builder(request, r.getApiResult()).build());
78+
return r.getApiResult();
79+
}));
80+
81+
return apiResult.
82+
map(responseEntity -> {
83+
final ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.status(responseEntity.getStatusCode());
84+
85+
apiProperty.getDefaultHeaders().forEach(header -> {
86+
final String headerName = header.getHeaderName();
87+
final String[] headerValues = header.getHeaderValues().toArray(new String[0]);
88+
bodyBuilder.header(headerName, headerValues);
89+
});
90+
91+
return bodyBuilder.body(responseEntity.getBody());
92+
});
10993
}
11094

11195
public Map<String, String> getHeaders(final HttpServletRequest request) {

src/main/java/br/com/elementalsource/mock/infra/component/ExternalApi.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,15 @@
1212
import org.slf4j.Logger;
1313
import org.slf4j.LoggerFactory;
1414
import org.springframework.beans.factory.annotation.Autowired;
15-
import org.springframework.http.HttpEntity;
16-
import org.springframework.http.HttpHeaders;
17-
import org.springframework.http.HttpMethod;
18-
import org.springframework.http.HttpStatus;
19-
import org.springframework.http.ResponseEntity;
15+
import org.springframework.http.*;
2016
import org.springframework.stereotype.Component;
2117
import org.springframework.web.client.RestTemplate;
18+
import org.springframework.web.reactive.function.client.WebClient;
2219

2320
import javax.servlet.http.HttpServletRequest;
2421
import java.io.IOException;
2522
import java.util.Enumeration;
23+
import java.util.Map;
2624
import java.util.Optional;
2725
import java.util.regex.Pattern;
2826

@@ -78,6 +76,14 @@ public Optional<ExternalApiResult> execute(final Request request) {
7876
.concat(parameters);
7977

8078
LOGGER.info("URL => {}", url);
79+
80+
// final WebClient.Builder webClientBuilder = WebClient
81+
// .builder()
82+
// .baseUrl(url)
83+
// .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
84+
//
85+
// webClientBuilder.build().method(HttpMethod.GET).retrieve().bodyToMono(Map.class).block();
86+
8187
final ResponseEntity<String> apiResult = restTemplate.exchange(url, HttpMethod.valueOf(request.getMethod().name().toUpperCase()), entity,
8288
String.class);
8389
return Optional.of(new ExternalApiResult(apiResult, uriConfiguration));
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
package br.com.elementalsource.mock.infra.component.file;
22

33
import br.com.elementalsource.mock.infra.property.FileProperty;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
46
import org.springframework.beans.factory.annotation.Autowired;
57
import org.springframework.beans.factory.annotation.Qualifier;
68
import org.springframework.stereotype.Component;
79

10+
import java.io.File;
11+
812
@Component("BaseFileNameBuilderModel")
913
public class BaseFileNameBuilderModel extends BaseFileNameBuilderBase implements BaseFileNameBuilder {
1014

15+
private static final Logger LOGGER = LoggerFactory.getLogger(BaseFileNameBuilderModel.class);
16+
1117
@Autowired
1218
public BaseFileNameBuilderModel(@Qualifier("FilePropertyModel") FileProperty fileProperty) {
1319
super(fileProperty);
20+
final String fileBase = fileProperty.getFileBase();
21+
final File file = new File(fileBase);
22+
LOGGER.info("Base path to files fileBase={}, exists?{}, path={}", fileBase, file.exists(), file.getAbsoluteFile());
1423
}
1524

1625
}

src/main/resources/application.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ api:
3939
# Paths of json
4040
file:
4141
# Look for this path to find json with a request
42-
base: "${MOCK_API_FILE_BASE}"
42+
base: "${FILE_BASE:mocks-test}"
4343
extension: ".json"
4444
# Save request (cache) in this path
45-
backup.path: "${MOCK_BACKUP_FILE_BASE}"
45+
backup.path: "${FILE_BACKUP_PATH:backup-temp}"
4646

4747
# Initialize app in capture mode. All requests will be saved
4848
captureState: true

0 commit comments

Comments
 (0)