Skip to content

Commit cb45f89

Browse files
horozalreimer-atb
andauthored
Pattern Application controller (#14)
* C:/Program Files/Git/application endpoint using external project importer * project template URLs JSON file added * project template URLs JSON file added * project template URLs JSON updated * pattern application controller updated * fix query string and rename * update POST request query parameters * update POST request query * structure PatternApplicationController class * structure PatternApplicationController class * add value to application properties file * print error message * Update pom.xml Reverting back to main pom.xml * update post mapping specification for PatternApplicationController * add logging for PatternApplicationController * Update src/main/java/org/eclipse/opensmartclide/architecturalpatterns/application/PatternApplicationController.java Co-authored-by: philipreimer <5737222+philipreimer@users.noreply.github.com> * Update src/main/java/org/eclipse/opensmartclide/architecturalpatterns/application/PatternApplicationController.java Co-authored-by: philipreimer <5737222+philipreimer@users.noreply.github.com> * Update src/main/java/org/eclipse/opensmartclide/architecturalpatterns/application/PatternApplicationController.java Co-authored-by: philipreimer <5737222+philipreimer@users.noreply.github.com> --------- Co-authored-by: philipreimer <5737222+philipreimer@users.noreply.github.com>
1 parent 24474da commit cb45f89

7 files changed

Lines changed: 162 additions & 21 deletions

File tree

Lines changed: 112 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,120 @@
11
package org.eclipse.opensmartclide.architecturalpatterns.application;
22

3-
import org.springframework.http.MediaType;
4-
import org.springframework.web.bind.annotation.GetMapping;
3+
import org.eclipse.opensmartclide.architecturalpatterns.service.ArchitecturalPatternsJsonHandler;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import java.lang.IllegalArgumentException;
8+
import org.springframework.beans.factory.annotation.Value;
9+
import org.springframework.http.HttpEntity;
10+
import org.springframework.http.HttpHeaders;
11+
import org.springframework.http.HttpStatus;
12+
import org.springframework.lang.Nullable;
13+
import org.springframework.util.LinkedMultiValueMap;
14+
import org.springframework.util.MultiValueMap;
15+
import org.springframework.web.bind.annotation.PostMapping;
16+
import org.springframework.web.bind.annotation.RequestHeader;
17+
import org.springframework.web.bind.annotation.RequestParam;
518
import org.springframework.web.bind.annotation.RestController;
19+
import org.springframework.web.client.RestClientException;
20+
import org.springframework.web.client.RestTemplate;
21+
import org.springframework.web.server.ResponseStatusException;
22+
import org.springframework.web.util.UriComponentsBuilder;
23+
import com.fasterxml.jackson.databind.JsonNode;
624

725
@RestController
826
public class PatternApplicationController {
9-
@GetMapping(value = "/application", produces = MediaType.APPLICATION_JSON_VALUE)
10-
public String setupPattern() {
11-
// TODO
12-
return "TODO: Architectural Pattern is being set up.";
27+
28+
@Value("${IMPORT_PROJECT_URL}")
29+
private String importProjectURL;
30+
private static final Logger logger = LoggerFactory.getLogger(PatternApplicationController.class);
31+
32+
private final ArchitecturalPatternsJsonHandler projectJsonHandler;
33+
34+
public PatternApplicationController(final ArchitecturalPatternsJsonHandler jsonHandler) {
35+
this.projectJsonHandler = jsonHandler;
36+
37+
}
38+
39+
@PostMapping(value = "/application")
40+
public String applyPattern(@RequestParam("framework") String framework, @RequestParam("pattern") String pattern,
41+
@Nullable @RequestParam("name") String projName, @Nullable @RequestParam("visibility") String visibility,
42+
@RequestHeader String gitLabServerURL, @RequestHeader String gitlabToken) {
43+
44+
try {
45+
46+
String repoUrl = getProjectURL(framework, pattern);
47+
48+
if (repoUrl == null) {
49+
throw new NullPointerException("Repository URL is not found.");
50+
}
51+
String response = createProject(repoUrl, projName, visibility, gitLabServerURL, gitlabToken);
52+
logger.info("Pattern application succeeded!");
53+
54+
return response;
55+
56+
} catch (IllegalArgumentException e) {
57+
logger.error("Exception during pattern application.", e);
58+
throw new ResponseStatusException(HttpStatus.BAD_REQUEST,
59+
"Problem with either project template resource or input parameters: " + e.getMessage());
60+
}
61+
}
62+
63+
public String getProjectURL(String framework, String pattern) {
64+
final JsonNode projUrlsJsonNode = projectJsonHandler.getProjectUrlsNode();
65+
66+
JsonNode frameworkNode = projUrlsJsonNode.get(framework);
67+
68+
if (frameworkNode == null) {
69+
throw new IllegalArgumentException(
70+
"Invalid framework received: " + framework + " is not a valid framework.");
71+
}
72+
73+
JsonNode patternNode = frameworkNode.get(pattern);
74+
75+
if (frameworkNode.get(pattern) == null) {
76+
throw new IllegalArgumentException("Invalid pattern received: " + pattern + " is not a valid pattern.");
77+
}
78+
79+
return patternNode.asText();
80+
}
81+
82+
public String createProject(String repoUrl, String projName, String visibility, String gitLabServerURL,
83+
String gitlabToken) {
84+
85+
// Creating URL with parameters
86+
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<>();
87+
parameters.add("repoUrl", repoUrl);
88+
89+
if (projName != null) {
90+
parameters.add("name", projName);
91+
}
92+
93+
if (visibility != null) {
94+
parameters.add("visibility", visibility);
95+
}
96+
97+
UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl(importProjectURL)
98+
.queryParams(parameters);
99+
String url = uriComponentsBuilder.build().encode().toUriString();
100+
101+
// Setting headers
102+
HttpHeaders headers = new HttpHeaders();
103+
headers.set("gitLabServerURL", gitLabServerURL);
104+
headers.set("gitlabToken", gitlabToken);
105+
106+
// Creating POST request query
107+
HttpEntity<String> request = new HttpEntity<>(url, headers);
108+
109+
try {
110+
111+
// Make POST request to external project importer
112+
RestTemplate restTemplate = new RestTemplate();
113+
return restTemplate.postForObject(importProjectURL, request, String.class);
114+
115+
} catch (RestClientException e) {
116+
logger.error("Problem encountered while sending POST request: " + url);
117+
throw new IllegalStateException(e.getMessage());
118+
}
13119
}
14120
}

src/main/java/org/eclipse/opensmartclide/architecturalpatterns/selection/PatternSelectionController.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package org.eclipse.opensmartclide.architecturalpatterns.selection;
22

33
import com.fasterxml.jackson.databind.JsonNode;
4-
import org.eclipse.opensmartclide.architecturalpatterns.service.SurveyJsonHandler;
4+
import org.eclipse.opensmartclide.architecturalpatterns.service.ArchitecturalPatternsJsonHandler;
55
import org.eclipse.opensmartclide.architecturalpatterns.supportedpatterns.ArchitecturalPatterns;
66
import org.springframework.http.MediaType;
77
import org.springframework.web.bind.annotation.PostMapping;
88
import org.springframework.web.bind.annotation.RequestBody;
99
import org.springframework.web.bind.annotation.RestController;
10-
1110
import java.util.HashMap;
1211
import java.util.List;
1312
import java.util.Map;
1413

1514
@RestController
1615
public class PatternSelectionController {
17-
private final SurveyJsonHandler surveyJsonHandler;
16+
private final ArchitecturalPatternsJsonHandler surveyJsonHandler;
1817

19-
public PatternSelectionController(final SurveyJsonHandler surveyJsonHandler) {
18+
public PatternSelectionController(final ArchitecturalPatternsJsonHandler surveyJsonHandler) {
2019
this.surveyJsonHandler = surveyJsonHandler;
2120
}
2221

src/main/java/org/eclipse/opensmartclide/architecturalpatterns/selection/SurveyController.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package org.eclipse.opensmartclide.architecturalpatterns.selection;
22

3-
import org.eclipse.opensmartclide.architecturalpatterns.service.SurveyJsonHandler;
3+
import org.eclipse.opensmartclide.architecturalpatterns.service.ArchitecturalPatternsJsonHandler;
44
import org.springframework.http.MediaType;
55
import org.springframework.web.bind.annotation.GetMapping;
66
import org.springframework.web.bind.annotation.RestController;
77

88
@RestController
99
public class SurveyController {
10-
private final SurveyJsonHandler surveyJsonHandler;
10+
private final ArchitecturalPatternsJsonHandler surveyJsonHandler;
1111

12-
public SurveyController(final SurveyJsonHandler surveyJsonHandler) {
12+
public SurveyController(final ArchitecturalPatternsJsonHandler surveyJsonHandler) {
1313
this.surveyJsonHandler = surveyJsonHandler;
1414
}
1515

src/main/java/org/eclipse/opensmartclide/architecturalpatterns/service/SurveyJsonHandler.java renamed to src/main/java/org/eclipse/opensmartclide/architecturalpatterns/service/ArchitecturalPatternsJsonHandler.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,21 @@
1414
import java.util.Objects;
1515

1616
@Component
17-
public class SurveyJsonHandler {
17+
public class ArchitecturalPatternsJsonHandler {
1818
private static final String SURVEY_JSON_FILE_PATH = "/jsonfiles/survey.json";
1919
private static final String SURVEY_EVALUATION_JSON_PATH = "/jsonfiles/surveyEvaluation.json";
20-
private static final Logger logger = LoggerFactory.getLogger(SurveyJsonHandler.class);
20+
private static final String PROJECT_URLS_JSON_PATH = "/jsonfiles/projectURLs.json";
21+
private static final Logger logger = LoggerFactory.getLogger(ArchitecturalPatternsJsonHandler.class);
2122
private final ObjectMapper mapper;
2223
private final String survey;
2324
private final JsonNode surveyEvaluationNode;
25+
private final JsonNode projectUrlsNode;
2426

25-
public SurveyJsonHandler(final ObjectMapper mapper) {
27+
public ArchitecturalPatternsJsonHandler(final ObjectMapper mapper) {
2628
this.mapper = mapper;
2729
this.survey = readJsonFileIntoString(SURVEY_JSON_FILE_PATH);
2830
this.surveyEvaluationNode = readJsonFileIntoJsonNode(SURVEY_EVALUATION_JSON_PATH);
31+
this.projectUrlsNode = readJsonFileIntoJsonNode(PROJECT_URLS_JSON_PATH);
2932
}
3033

3134
public String getSurvey() {
@@ -36,14 +39,18 @@ public JsonNode getSurveyEvaluationNode() {
3639
return surveyEvaluationNode;
3740
}
3841

42+
public JsonNode getProjectUrlsNode() {
43+
return projectUrlsNode;
44+
}
45+
3946
private String readJsonFileIntoString(final String pathToFile) {
4047
logger.info("Reading file: {}", pathToFile);
4148
try {
42-
final URL jsonUrl = SurveyJsonHandler.class.getResource(pathToFile);
49+
final URL jsonUrl = ArchitecturalPatternsJsonHandler.class.getResource(pathToFile);
4350
final Path path = Path.of(Objects.requireNonNull(jsonUrl).toURI());
4451
return Files.readString(path);
4552
} catch (URISyntaxException | IOException e) {
46-
throw new RuntimeException(String.format("Failed to read survey file: %s!", pathToFile), e);
53+
throw new RuntimeException(String.format("Failed to read file: %s!", pathToFile), e);
4754
}
4855
}
4956

@@ -52,7 +59,7 @@ private JsonNode readJsonFileIntoJsonNode(@SuppressWarnings("SameParameterValue"
5259
final String jsonStr = readJsonFileIntoString(pathToFile);
5360
return mapper.readValue(jsonStr, JsonNode.class);
5461
} catch (IOException e) {
55-
throw new RuntimeException(String.format("Failed to read survey evaluation file: %s!", pathToFile), e);
62+
throw new RuntimeException(String.format("Failed to read file: %s!", pathToFile), e);
5663
}
5764
}
5865
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1+
IMPORT_PROJECT_URL = https://api.dev.smartclide.eu/external-project-importer/importProject
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"Java with Spring Boot and MySQL": {
3+
"Layered": "https://github.com/che-samples/web-java-spring-boot",
4+
"Event-driven": "https://github.com/spring-projects/spring-kafka",
5+
"Microkernel": "https://github.com/devexpress-albania/microkernel",
6+
"Microservices": "https://github.com/che-samples/web-java-spring-boot",
7+
"Service-oriented": "https://github.com/che-samples/web-java-spring-boot",
8+
"Space-based": "https://github.com/che-samples/web-java-spring-boot"
9+
},
10+
"Node.js": {
11+
"Layered": "https://github.com/che-samples/web-nodejs-sample",
12+
"Event-driven":"https://github.com/che-samples/web-nodejs-sample",
13+
"Microkernel": "https://github.com/rse/microkernel",
14+
"Microservices": "https://github.com/che-samples/web-nodejs-sample",
15+
"Service-oriented": "https://github.com/che-samples/web-nodejs-sample",
16+
"Space-based": "https://github.com/che-samples/web-nodejs-sample"
17+
},
18+
"Python": {
19+
"Layered": "https://github.com/che-samples/python-hello-world",
20+
"Event-driven": "https://github.com/che-samples/python-hello-world",
21+
"Microkernel": "https://github.com/che-samples/python-hello-world",
22+
"Microservices": "https://github.com/che-samples/python-hello-world",
23+
"Service-oriented": "https://github.com/che-samples/python-hello-world",
24+
"Space-based": "https://github.com/che-samples/python-hello-world"
25+
}
26+
}

src/test/resources/test-requests.http

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
GET http://localhost:8080/supported-patterns
33

44
###
5-
GET http://localhost:8080/application
5+
POST http://localhost:8080/application?framework=Python&pattern=Layered&name=LayeredTestProject&visibility=2
6+
Content-Type: application/json
7+
gitLabServerURL: https://gitlab.com
8+
gitlabToken: <gitLabToken>
69

710
###
811
GET http://localhost:8080/survey

0 commit comments

Comments
 (0)