Skip to content

Commit b896864

Browse files
authored
Merge pull request #1190 from Backbase/feature/add_webhooks_implementation
Added code related to generate webhook endpoints with different goal
2 parents a0684d2 + 10743e9 commit b896864

File tree

54 files changed

+2394
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2394
-0
lines changed

boat-maven-plugin/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,36 @@ Same with `generate` but with opinionated defaults for Spring
6060
</configOptions>
6161
</configuration>
6262

63+
## boat:generate-spring-boot-embedded-webhooks
64+
65+
Same with `generate-spring-boot-embedded` but with opinionated defaults for Webhooks
66+
It will generate webhook interfaces with prehook and posthook request mapping for each endpoint in the OpenAPI Specs.
67+
68+
<configuration>
69+
<output>${project.build.directory}/generated-sources/openapi</output>
70+
<generateSupportingFiles>true</generateSupportingFiles>
71+
<generatorName>boat-webhooks</generatorName>
72+
<strictSpec>true</strictSpec>
73+
<generateApiTests>false</generateApiTests>
74+
<generateModelTests>false</generateModelTests>
75+
<inputSpec>${project.basedir}/../api/product-service-api/src/main/resources/openapi.yaml</inputSpec>
76+
<configOptions>
77+
<dateLibrary>java8</dateLibrary>
78+
<interfaceOnly>true</interfaceOnly>
79+
<skipDefaultInterface>true</skipDefaultInterface>
80+
<useBeanValidation>true</useBeanValidation>
81+
<useClassLevelBeanValidation>false</useClassLevelBeanValidation>
82+
<useTags>true</useTags>
83+
<java8>true</java8>
84+
<useOptional>false</useOptional>
85+
<apiPackage>com.backbase.product.api.service.v2</apiPackage>
86+
<modelPackage>com.backbase.product.api.service.v2.model</modelPackage>
87+
<useJakartaEe>true</useJakartaEe>
88+
<useSpringBoot3>true</useSpringBoot3>
89+
<containerDefaultToNull>false</containerDefaultToNull>
90+
</configOptions>
91+
</configuration>
92+
6393
## boat:generate-rest-template-embedded
6494

6595
Same with `generate` but with opinionated defaults for Rest Template Client
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.backbase.oss.boat;
2+
3+
import org.apache.maven.plugin.MojoExecutionException;
4+
import org.apache.maven.plugin.MojoFailureException;
5+
import org.apache.maven.plugins.annotations.Mojo;
6+
7+
import java.util.Collection;
8+
import java.util.Set;
9+
10+
/**
11+
* Generating Server Stubs using Spring Boot.
12+
*/
13+
@Mojo(name = "generate-spring-boot-embedded-webhooks", threadSafe = true)
14+
public class GenerateSpringBootEmbeddedWebhookMojo extends AbstractGenerateMojo {
15+
16+
@Override
17+
public void execute() throws MojoExecutionException, MojoFailureException {
18+
getLog().info("Generating Server Stubs using Spring Boot Webhooks");
19+
execute("boat-webhooks", "boat-webhooks", true, false, false);
20+
}
21+
22+
@Override
23+
protected Collection<String> getGeneratorSpecificSupportingFiles() {
24+
return Set.of("BigDecimalCustomSerializer.java", "WebhookResponse.java", "ServletContent.java", "PosthookRequest.java", "PrehookRequest.java");
25+
}
26+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package com.backbase.oss.codegen.java;
2+
3+
import io.swagger.v3.oas.models.Operation;
4+
import io.swagger.v3.oas.models.servers.Server;
5+
import lombok.extern.slf4j.Slf4j;
6+
import org.openapitools.codegen.CliOption;
7+
import org.openapitools.codegen.CodegenOperation;
8+
import org.openapitools.codegen.SupportingFile;
9+
10+
import java.io.File;
11+
import java.util.List;
12+
13+
import static org.openapitools.codegen.utils.StringUtils.camelize;
14+
15+
@Slf4j
16+
public class BoatWebhooksCodeGen extends BoatSpringCodeGen {
17+
public static final String NAME = "boat-webhooks";
18+
19+
public static final String USE_CLASS_LEVEL_BEAN_VALIDATION = "useClassLevelBeanValidation";
20+
public static final String ADD_SERVLET_REQUEST = "addServletRequest";
21+
public static final String ADD_BINDING_RESULT = "addBindingResult";
22+
public static final String USE_LOMBOK_ANNOTATIONS = "useLombokAnnotations";
23+
public static final String USE_WITH_MODIFIERS = "useWithModifiers";
24+
public static final String USE_PROTECTED_FIELDS = "useProtectedFields";
25+
public static final String MUSTACHE_EXTENSION =".mustache";
26+
public static final String JAVA_EXTENSION =".java";
27+
28+
29+
public BoatWebhooksCodeGen() {
30+
super();
31+
log.info("BoatWebhooksCodeGen constructor called. NAME: {}", NAME);
32+
this.embeddedTemplateDir = this.templateDir = NAME;
33+
this.openapiNormalizer.put("REF_AS_PARENT_IN_ALLOF", "true");
34+
35+
this.cliOptions.add(CliOption.newBoolean(USE_CLASS_LEVEL_BEAN_VALIDATION,
36+
"Add @Validated to class-level Api interfaces.", this.useClassLevelBeanValidation));
37+
this.cliOptions.add(CliOption.newBoolean(ADD_SERVLET_REQUEST,
38+
"Adds a HttpServletRequest object to the API definition method.", this.addServletRequest));
39+
this.cliOptions.add(CliOption.newBoolean(ADD_BINDING_RESULT,
40+
"Adds a Binding result as method perimeter. Only implemented if @validate is being used.",
41+
this.addBindingResult));
42+
this.cliOptions.add(CliOption.newBoolean(USE_LOMBOK_ANNOTATIONS,
43+
"Add Lombok to class-level Api models. Defaults to false.", this.useLombokAnnotations));
44+
this.cliOptions.add(CliOption.newBoolean(USE_WITH_MODIFIERS,
45+
"Whether to use \"with\" prefix for POJO modifiers.", this.useWithModifiers));
46+
this.cliOptions.add(CliOption.newString(USE_PROTECTED_FIELDS,
47+
"Whether to use protected visibility for model fields"));
48+
supportedLibraries.put(NAME, "Boat Webhooks codegen");
49+
this.apiNameSuffix = "Api";
50+
this.apiNamePrefix = "Webhook";
51+
}
52+
53+
@Override
54+
public String getName() {
55+
return NAME;
56+
}
57+
58+
@Override
59+
public String toApiName(String name) {
60+
if (name.isEmpty()) {
61+
name = "default";
62+
}
63+
64+
name = sanitizeName(name);
65+
66+
return camelize(this.apiNamePrefix + "_" + name + "_" + this.apiNameSuffix);
67+
}
68+
69+
@Override
70+
public void processOpts() {
71+
super.processOpts();
72+
log.info("BoatWebhooksCodeGen processOpts called. Adding supporting files and properties.");
73+
final var webhookResponseTemplate = "WebhookResponse";
74+
this.supportingFiles.add(new SupportingFile(webhookResponseTemplate + MUSTACHE_EXTENSION,
75+
(sourceFolder + File.separator + modelPackage).replace(".", File.separator),
76+
webhookResponseTemplate + JAVA_EXTENSION));
77+
final var servletContentTemplate = "ServletContent";
78+
this.supportingFiles.add(new SupportingFile(servletContentTemplate + MUSTACHE_EXTENSION,
79+
(sourceFolder + File.separator + modelPackage).replace(".", File.separator),
80+
servletContentTemplate + JAVA_EXTENSION));
81+
final var posthookRequestTemplate = "PosthookRequest";
82+
this.supportingFiles.add(new SupportingFile(posthookRequestTemplate + MUSTACHE_EXTENSION,
83+
(sourceFolder + File.separator + modelPackage).replace(".", File.separator),
84+
posthookRequestTemplate + JAVA_EXTENSION));
85+
final var prehookRequestTemplate = "PrehookRequest";
86+
this.supportingFiles.add(new SupportingFile(prehookRequestTemplate + MUSTACHE_EXTENSION,
87+
(sourceFolder + File.separator + modelPackage).replace(".", File.separator),
88+
prehookRequestTemplate + JAVA_EXTENSION));
89+
}
90+
91+
92+
@Override
93+
public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List<Server> servers) {
94+
CodegenOperation codegenOperation = super.fromOperation(path, httpMethod, operation, servers);
95+
// Remove the standard body parameter (if it exists) ---
96+
// This prevents the generator's default logic from inserting its own request body.
97+
codegenOperation.allParams.removeIf(p -> p.isBodyParam);
98+
return codegenOperation;
99+
}
100+
101+
}

boat-scaffold/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ com.backbase.oss.codegen.angular.BoatAngularGenerator
55
com.backbase.oss.codegen.marina.BoatMarinaGenerator
66
org.openapitools.codegen.languages.BoatSwift5Codegen
77
org.openapitools.codegen.languages.BoatAndroidClientCodegen
8+
com.backbase.oss.codegen.java.BoatWebhooksCodeGen
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package {{modelPackage}};
2+
3+
import com.fasterxml.jackson.databind.ser.std.ToStringSerializerBase;
4+
import java.math.BigDecimal;
5+
6+
public class BigDecimalCustomSerializer extends ToStringSerializerBase {
7+
8+
public BigDecimalCustomSerializer() {
9+
super(BigDecimal.class);
10+
}
11+
12+
@Override
13+
public String valueToString(Object value) {
14+
if (value instanceof BigDecimal) {
15+
return ((BigDecimal) value).toPlainString();
16+
}
17+
return (value == null) ? null : value.toString();
18+
}
19+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package {{modelPackage}};
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.Objects;
6+
7+
/**
8+
* Predefined request object for posthook endpoints containing API response and the request details.
9+
*/
10+
public class PosthookRequest extends ServletContent {
11+
12+
private PrehookRequest requestDetails;
13+
14+
public PosthookRequest body(String body) {
15+
this.setBody(body);
16+
return this;
17+
}
18+
19+
public PosthookRequest headers(Map<String, List<String>> headers) {
20+
this.setHeaders(headers);
21+
return this;
22+
}
23+
24+
public PosthookRequest parameters(Map<String, String[]> parameters) {
25+
this.setParameters(parameters);
26+
return this;
27+
}
28+
29+
public PosthookRequest requestDetails(PrehookRequest requestDetails) {
30+
this.requestDetails = requestDetails;
31+
return this;
32+
}
33+
34+
public PrehookRequest getRequestDetails() {
35+
return requestDetails;
36+
}
37+
38+
public void setRequestDetails(PrehookRequest requestDetails) {
39+
this.requestDetails = requestDetails;
40+
}
41+
42+
@Override
43+
public boolean equals(Object o) {
44+
if (this == o) {
45+
return true;
46+
}
47+
if (o == null || getClass() != o.getClass()) {
48+
return false;
49+
}
50+
PosthookRequest posthookRequest = (PosthookRequest) o;
51+
return super.equals(o) && Objects.equals(this.requestDetails, posthookRequest.requestDetails);
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return super.hashCode() + Objects.hash(requestDetails);
57+
}
58+
59+
@Override
60+
public String toString() {
61+
StringBuilder sb = new StringBuilder();
62+
sb.append("class PosthookRequest {\n");
63+
sb.append(" body: ").append(toIndentedString(getBody())).append("\n");
64+
sb.append(" headers: ").append(toIndentedString(getHeaders())).append("\n");
65+
sb.append(" parameters: ").append(toIndentedString(getParameters())).append("\n");
66+
sb.append(" requestDetails: ").append(toIndentedString(requestDetails)).append("\n");
67+
sb.append("}");
68+
return sb.toString();
69+
}
70+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package {{modelPackage}};
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
import java.util.Objects;
6+
7+
/**
8+
* Predefined request object for prehook endpoints.
9+
*/
10+
public class PrehookRequest extends ServletContent {
11+
12+
private Map<String, String> pathVariables;
13+
14+
public PrehookRequest body(String body) {
15+
this.setBody(body);
16+
return this;
17+
}
18+
19+
public PrehookRequest headers(Map<String, List<String>> headers) {
20+
this.setHeaders(headers);
21+
return this;
22+
}
23+
24+
public PrehookRequest parameters(Map<String, String[]> parameters) {
25+
this.setParameters(parameters);
26+
return this;
27+
}
28+
29+
public PrehookRequest pathVariables(Map<String, String> pathVariables) {
30+
this.pathVariables = pathVariables;
31+
return this;
32+
}
33+
34+
public Map<String, String> getPathVariables() {
35+
return pathVariables;
36+
}
37+
38+
public void setPathVariables(Map<String, String> pathVariables) {
39+
this.pathVariables = pathVariables;
40+
}
41+
42+
@Override
43+
public boolean equals(Object o) {
44+
if (this == o) {
45+
return true;
46+
}
47+
if (o == null || getClass() != o.getClass()) {
48+
return false;
49+
}
50+
PrehookRequest prehookRequest = (PrehookRequest) o;
51+
return super.equals(o) && Objects.equals(this.pathVariables, prehookRequest.pathVariables);
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return super.hashCode() + Objects.hash(pathVariables);
57+
}
58+
59+
@Override
60+
public String toString() {
61+
StringBuilder sb = new StringBuilder();
62+
sb.append("class PrehookRequest {\n");
63+
sb.append(" body: ").append(toIndentedString(getBody())).append("\n");
64+
sb.append(" headers: ").append(toIndentedString(getHeaders())).append("\n");
65+
sb.append(" parameters: ").append(toIndentedString(getParameters())).append("\n");
66+
sb.append(" pathVariables: ").append(toIndentedString(pathVariables)).append("\n");
67+
sb.append("}");
68+
return sb.toString();
69+
}
70+
}

0 commit comments

Comments
 (0)