Skip to content

Commit aa701b0

Browse files
committed
Move Public API to top of Class
The structure of code should be ordered, so that the more abstract API is at the top and the more nitty gritty details are below. This has the advantage that one interested in an quick overview need not to scroll up and down. You only need to scroll down for details. Also add some null-checks and missing API doc. Signed-off-by: Sven Strittmatter <sven.strittmatter@iteratec.com>
1 parent f197035 commit aa701b0

15 files changed

+100
-70
lines changed

src/main/java/io/securecodebox/persistence/defectdojo/service/EndpointService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.Endpoint;
1111
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
12+
import lombok.NonNull;
1213

1314
public class EndpointService extends GenericDefectDojoService<Endpoint> {
1415
public EndpointService(Config config) {
@@ -26,7 +27,7 @@ protected Class<Endpoint> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<Endpoint> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<Endpoint> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

src/main/java/io/securecodebox/persistence/defectdojo/service/EngagementService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.Engagement;
1111
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
12+
import lombok.NonNull;
1213

1314
public class EngagementService extends GenericDefectDojoService<Engagement> {
1415
public EngagementService(Config config) {
@@ -26,7 +27,7 @@ protected Class<Engagement> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<Engagement> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<Engagement> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

src/main/java/io/securecodebox/persistence/defectdojo/service/FindingService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.Finding;
1111
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
12+
import lombok.NonNull;
1213

1314
import java.net.URISyntaxException;
1415
import java.util.List;
@@ -30,7 +31,7 @@ protected Class<Finding> getModelClass() {
3031
}
3132

3233
@Override
33-
protected PaginatedResult<Finding> deserializeList(String response) throws JsonProcessingException {
34+
protected PaginatedResult<Finding> deserializeList(@NonNull String response) throws JsonProcessingException {
3435
return this.objectMapper.readValue(response, new TypeReference<>() {
3536
});
3637
}

src/main/java/io/securecodebox/persistence/defectdojo/service/GenericDefectDojoService.java

Lines changed: 72 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
// TODO: Remove JsonProcessingException, URISyntaxException from public API and use a own runtime exception type bc these checked exceptions clutter the client coe.
4040
@Slf4j
41-
abstract class GenericDefectDojoService<T extends Model> implements DefectDojoService<T>{
41+
abstract class GenericDefectDojoService<T extends Model> implements DefectDojoService<T> {
4242
private static final String API_PREFIX = "/api/v2/";
4343
private static final long DEFECT_DOJO_OBJET_LIMIT = 100L;
4444
protected Config config;
@@ -66,33 +66,6 @@ public GenericDefectDojoService(@NonNull Config config) {
6666
this.restTemplate = this.setupRestTemplate();
6767
}
6868

69-
70-
/**
71-
* @return The DefectDojo Authentication Header
72-
*/
73-
private HttpHeaders getDefectDojoAuthorizationHeaders() {
74-
return new Foo(config, new ProxyConfigFactory().create()).generateAuthorizationHeaders();
75-
}
76-
77-
private RestTemplate setupRestTemplate() {
78-
RestTemplate restTemplate = new Foo(config, new ProxyConfigFactory().create()).createRestTemplate();
79-
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
80-
converter.setObjectMapper(this.objectMapper);
81-
restTemplate.setMessageConverters(List.of(
82-
new FormHttpMessageConverter(),
83-
new ResourceHttpMessageConverter(),
84-
new StringHttpMessageConverter(),
85-
converter
86-
));
87-
return restTemplate;
88-
}
89-
90-
protected abstract String getUrlPath();
91-
92-
protected abstract Class<T> getModelClass();
93-
94-
protected abstract PaginatedResult<T> deserializeList(String response) throws JsonProcessingException;
95-
9669
@Override
9770
public final T get(long id) {
9871
var restTemplate = this.getRestTemplate();
@@ -110,34 +83,6 @@ public final T get(long id) {
11083
return response.getBody();
11184
}
11285

113-
protected PaginatedResult<T> internalSearch(Map<String, Object> queryParams, long limit, long offset) throws JsonProcessingException, URISyntaxException {
114-
var restTemplate = this.getRestTemplate();
115-
HttpEntity<String> payload = new HttpEntity<>(getDefectDojoAuthorizationHeaders());
116-
117-
var mutableQueryParams = new HashMap<>(queryParams);
118-
119-
mutableQueryParams.put("limit", String.valueOf(limit));
120-
mutableQueryParams.put("offset", String.valueOf(offset));
121-
122-
var multiValueMap = new LinkedMultiValueMap<String, String>();
123-
for (var entry : mutableQueryParams.entrySet()) {
124-
multiValueMap.set(entry.getKey(), String.valueOf(entry.getValue()));
125-
}
126-
127-
var url = new URI(this.config.getUrl() + API_PREFIX + this.getUrlPath() + "/");
128-
log.debug("Requesting URL: " + url);
129-
var uriBuilder = UriComponentsBuilder.fromUri(url).queryParams(multiValueMap);
130-
131-
ResponseEntity<String> responseString = restTemplate.exchange(
132-
uriBuilder.build(mutableQueryParams),
133-
HttpMethod.GET,
134-
payload,
135-
String.class
136-
);
137-
138-
return deserializeList(responseString.getBody());
139-
}
140-
14186
@Override
14287
public final List<T> search(Map<String, Object> queryParams) throws URISyntaxException, JsonProcessingException {
14388
List<T> objects = new LinkedList<>();
@@ -208,4 +153,75 @@ public final T update(T object, long objectId) {
208153
ResponseEntity<T> response = restTemplate.exchange(this.config.getUrl() + API_PREFIX + getUrlPath() + "/" + objectId + "/", HttpMethod.PUT, payload, getModelClass());
209154
return response.getBody();
210155
}
156+
157+
/**
158+
* Get the URL path for the REST endpoint relative to {@link #API_PREFIX}
159+
*
160+
* @return not {@code null}, not empty
161+
*/
162+
protected abstract String getUrlPath();
163+
164+
/**
165+
* Get the model type the service handles
166+
*
167+
* @return not {@code null}
168+
*/
169+
protected abstract Class<T> getModelClass();
170+
171+
/**
172+
* Deserializes the response JSON string
173+
*
174+
* @param response not {@code null}, maybe empty
175+
* @return not {@code null}
176+
* @throws JsonProcessingException if string is not parsable as JSON
177+
*/
178+
protected abstract PaginatedResult<T> deserializeList(@NonNull String response) throws JsonProcessingException;
179+
180+
/**
181+
* @return The DefectDojo Authentication Header
182+
*/
183+
private HttpHeaders getDefectDojoAuthorizationHeaders() {
184+
return new Foo(config, new ProxyConfigFactory().create()).generateAuthorizationHeaders();
185+
}
186+
187+
private RestTemplate setupRestTemplate() {
188+
RestTemplate restTemplate = new Foo(config, new ProxyConfigFactory().create()).createRestTemplate();
189+
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
190+
converter.setObjectMapper(this.objectMapper);
191+
restTemplate.setMessageConverters(List.of(
192+
new FormHttpMessageConverter(),
193+
new ResourceHttpMessageConverter(),
194+
new StringHttpMessageConverter(),
195+
converter
196+
));
197+
return restTemplate;
198+
}
199+
200+
protected PaginatedResult<T> internalSearch(Map<String, Object> queryParams, long limit, long offset) throws JsonProcessingException, URISyntaxException {
201+
var restTemplate = this.getRestTemplate();
202+
HttpEntity<String> payload = new HttpEntity<>(getDefectDojoAuthorizationHeaders());
203+
204+
var mutableQueryParams = new HashMap<>(queryParams);
205+
206+
mutableQueryParams.put("limit", String.valueOf(limit));
207+
mutableQueryParams.put("offset", String.valueOf(offset));
208+
209+
var multiValueMap = new LinkedMultiValueMap<String, String>();
210+
for (var entry : mutableQueryParams.entrySet()) {
211+
multiValueMap.set(entry.getKey(), String.valueOf(entry.getValue()));
212+
}
213+
214+
var url = new URI(this.config.getUrl() + API_PREFIX + this.getUrlPath() + "/");
215+
log.debug("Requesting URL: " + url);
216+
var uriBuilder = UriComponentsBuilder.fromUri(url).queryParams(multiValueMap);
217+
218+
ResponseEntity<String> responseString = restTemplate.exchange(
219+
uriBuilder.build(mutableQueryParams),
220+
HttpMethod.GET,
221+
payload,
222+
String.class
223+
);
224+
225+
return deserializeList(responseString.getBody());
226+
}
211227
}

src/main/java/io/securecodebox/persistence/defectdojo/service/GroupMemberService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.GroupMember;
1111
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
12+
import lombok.NonNull;
1213

1314
public class GroupMemberService extends GenericDefectDojoService<GroupMember> {
1415
public GroupMemberService(Config config) {
@@ -26,7 +27,7 @@ protected Class<GroupMember> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<GroupMember> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<GroupMember> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

src/main/java/io/securecodebox/persistence/defectdojo/service/GroupService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.Group;
1111
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
12+
import lombok.NonNull;
1213

1314
public class GroupService extends GenericDefectDojoService<Group> {
1415
public GroupService(Config config) {
@@ -26,7 +27,7 @@ protected Class<Group> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<Group> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<Group> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

src/main/java/io/securecodebox/persistence/defectdojo/service/ProductGroupService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
1111
import io.securecodebox.persistence.defectdojo.model.ProductGroup;
12+
import lombok.NonNull;
1213

1314
public class ProductGroupService extends GenericDefectDojoService<ProductGroup> {
1415
public ProductGroupService(Config config) {
@@ -26,7 +27,7 @@ protected Class<ProductGroup> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<ProductGroup> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<ProductGroup> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

src/main/java/io/securecodebox/persistence/defectdojo/service/ProductService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
1111
import io.securecodebox.persistence.defectdojo.model.Product;
12+
import lombok.NonNull;
1213

1314
public class ProductService extends GenericDefectDojoService<Product> {
1415

@@ -27,7 +28,7 @@ protected Class<Product> getModelClass() {
2728
}
2829

2930
@Override
30-
protected PaginatedResult<Product> deserializeList(String response) throws JsonProcessingException {
31+
protected PaginatedResult<Product> deserializeList(@NonNull String response) throws JsonProcessingException {
3132
return this.objectMapper.readValue(response, new TypeReference<>() {
3233
});
3334
}

src/main/java/io/securecodebox/persistence/defectdojo/service/ProductTypeService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
1111
import io.securecodebox.persistence.defectdojo.model.ProductType;
12+
import lombok.NonNull;
1213

1314
public final class ProductTypeService extends GenericDefectDojoService<ProductType> {
1415

@@ -27,7 +28,7 @@ protected Class<ProductType> getModelClass() {
2728
}
2829

2930
@Override
30-
protected PaginatedResult<ProductType> deserializeList(String response) throws JsonProcessingException {
31+
protected PaginatedResult<ProductType> deserializeList(@NonNull String response) throws JsonProcessingException {
3132
return this.objectMapper.readValue(response, new TypeReference<>() {
3233
});
3334
}

src/main/java/io/securecodebox/persistence/defectdojo/service/TestService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.securecodebox.persistence.defectdojo.config.Config;
1010
import io.securecodebox.persistence.defectdojo.model.PaginatedResult;
1111
import io.securecodebox.persistence.defectdojo.model.Test;
12+
import lombok.NonNull;
1213

1314
public class TestService extends GenericDefectDojoService<Test> {
1415
public TestService(Config config) {
@@ -26,7 +27,7 @@ protected Class<Test> getModelClass() {
2627
}
2728

2829
@Override
29-
protected PaginatedResult<Test> deserializeList(String response) throws JsonProcessingException {
30+
protected PaginatedResult<Test> deserializeList(@NonNull String response) throws JsonProcessingException {
3031
return this.objectMapper.readValue(response, new TypeReference<>() {
3132
});
3233
}

0 commit comments

Comments
 (0)