1 package io.apicurio.registry.maven;
2
3 import com.fasterxml.jackson.core.JsonProcessingException;
4 import com.fasterxml.jackson.databind.JsonNode;
5 import com.fasterxml.jackson.databind.ObjectMapper;
6 import com.github.tomakehurst.wiremock.WireMockServer;
7 import com.github.tomakehurst.wiremock.common.FileSource;
8 import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
9 import com.github.tomakehurst.wiremock.extension.Parameters;
10 import com.github.tomakehurst.wiremock.extension.ResponseTransformer;
11 import com.github.tomakehurst.wiremock.http.Request;
12 import com.github.tomakehurst.wiremock.http.Response;
13 import io.apicurio.registry.rest.v3.beans.IfArtifactExists;
14 import io.apicurio.registry.types.ArtifactType;
15 import org.junit.jupiter.api.AfterEach;
16 import org.junit.jupiter.api.BeforeEach;
17 import org.junit.jupiter.api.Test;
18
19 import java.io.File;
20 import java.nio.file.Paths;
21 import java.util.HashSet;
22 import java.util.Set;
23
24 import static com.github.tomakehurst.wiremock.client.WireMock.*;
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 public class RegisterAsyncApiAvroAutoRefsTest {
29
30 private RegisterRegistryMojo mojo;
31 private final File examplesRoot = Paths.get("../../examples/").toAbsolutePath().toFile();
32 private WireMockServer wireMockServer;
33 private Set<String> registeredArtifacts = new HashSet<>();
34
35 @BeforeEach public void setup() {
36
37 wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().dynamicPort()
38 .extensions(new CaptureRequestTransformer()));
39 wireMockServer.start();
40
41
42 wireMockServer.stubFor(post(urlPathMatching("/apis/registry/v3/groups/.*/artifacts")).willReturn(
43 aResponse().withTransformers("capture-request-transformer").withStatus(200)
44 .withHeader("Content-Type", "application/json")));
45
46 mojo = new RegisterRegistryMojo();
47 mojo.setRegistryUrl(wireMockServer.baseUrl() + "/apis/registry/v3");
48
49
50 registeredArtifacts.clear();
51 }
52
53 @AfterEach public void tearDown() {
54 if (wireMockServer != null) {
55 wireMockServer.stop();
56 }
57 }
58
59 @Test public void testAsyncApiWithAvroAutoRefs() throws Exception {
60 File exampleDir = new File(examplesRoot, "asyncapi-avro-maven-with-references-auto");
61 File asyncApiFile = new File(exampleDir, "src/main/resources/schemas/asyncapi-avro-refs.yml");
62
63
64 RegisterArtifact artifact = new RegisterArtifact();
65 artifact.setGroupId("asyncapi-avro-maven-with-references-auto");
66 artifact.setArtifactId("CustomersExample");
67 artifact.setVersion("1.0.0");
68 artifact.setArtifactType(ArtifactType.ASYNCAPI);
69 artifact.setFile(asyncApiFile);
70 artifact.setIfExists(IfArtifactExists.FIND_OR_CREATE_VERSION);
71 artifact.setCanonicalize(true);
72 artifact.setAutoRefs(true);
73
74 mojo.setArtifacts(java.util.Collections.singletonList(artifact));
75 mojo.execute();
76
77 assertEquals(6, registeredArtifacts.size());
78 assertTrue(registeredArtifacts.contains("asyncapi-avro-maven-with-references-auto:CustomersExample"));
79 assertTrue(registeredArtifacts.contains(
80 "asyncapi-avro-maven-with-references-auto:io.example.api.dtos.CustomerEvent"));
81 assertTrue(registeredArtifacts.contains(
82 "asyncapi-avro-maven-with-references-auto:io.example.api.dtos.Address"));
83 assertTrue(registeredArtifacts.contains(
84 "asyncapi-avro-maven-with-references-auto:io.example.api.dtos.PaymentMethod"));
85 assertTrue(registeredArtifacts.contains(
86 "asyncapi-avro-maven-with-references-auto:io.example.api.dtos.PaymentMethodType"));
87 assertTrue(registeredArtifacts.contains(
88 "asyncapi-avro-maven-with-references-auto:io.example.api.dtos.CustomerDeletedEvent"));
89
90 }
91
92 @Test public void testAvroAutoRefs() throws Exception {
93 File exampleDir = new File(examplesRoot, "avro-maven-with-references-auto");
94 File avroFile = new File(exampleDir, "src/main/resources/schemas/TradeRaw.avsc");
95
96
97 RegisterArtifact artifact = new RegisterArtifact();
98 artifact.setGroupId("com.kubetrade.schema.trade");
99 artifact.setArtifactId("TradeRaw");
100 artifact.setVersion("2.0");
101 artifact.setArtifactType(ArtifactType.AVRO);
102 artifact.setFile(avroFile);
103 artifact.setIfExists(IfArtifactExists.FIND_OR_CREATE_VERSION);
104 artifact.setCanonicalize(true);
105 artifact.setAutoRefs(true);
106
107 mojo.setArtifacts(java.util.Collections.singletonList(artifact));
108 mojo.execute();
109
110 assertEquals(4, registeredArtifacts.size());
111 assertTrue(registeredArtifacts.contains("com.kubetrade.schema.trade:TradeRaw"));
112 assertTrue(registeredArtifacts.contains("com.kubetrade.schema.trade:TradeKey"));
113 assertTrue(registeredArtifacts.contains("com.kubetrade.schema.trade:TradeValue"));
114 assertTrue(registeredArtifacts.contains("com.kubetrade.schema.common:Exchange"));
115 }
116
117
118 class CaptureRequestTransformer extends ResponseTransformer {
119
120 @Override public String getName() {
121 return "capture-request-transformer";
122 }
123
124 @Override public Response transform(Request request, Response response, FileSource fileSource,
125 Parameters parameters) {
126 try {
127 String responseBody = generateResponseBasedOnRequest(request);
128 return Response.Builder.like(response).but().body(responseBody).build();
129 } catch (JsonProcessingException e) {
130 throw new RuntimeException(e);
131 }
132
133 }
134
135 private String generateResponseBasedOnRequest(Request request) throws JsonProcessingException {
136 String url = request.getUrl();
137 String body = request.getBodyAsString();
138
139 String groupId = extractGroupIdFromUrl(url);
140 String artifactId = extractArtifactIdFromBody(body);
141
142 registeredArtifacts.add(groupId + ":" + artifactId);
143
144 return """
145 {
146 "version": {
147 "version": "1",
148 "globalId": 12345,
149 "contentId": 67890
150 },
151 "artifact": {
152 "groupId": "%s",
153 "artifactId": "%s"
154 }
155 }
156 """.formatted(groupId, artifactId);
157 }
158
159 private String extractGroupIdFromUrl(String url) {
160
161 String[] parts = url.split("/");
162 for (int i = 0; i < parts.length - 1; i++) {
163 if ("groups".equals(parts[i]) && i + 1 < parts.length) {
164 return parts[i + 1];
165 }
166 }
167 return "default";
168 }
169
170 private String extractArtifactIdFromBody(String body) throws JsonProcessingException {
171 ObjectMapper mapper = new ObjectMapper();
172 JsonNode jsonNode = mapper.readTree(body);
173
174 JsonNode artifactIdNode = jsonNode.get("artifactId");
175 if (artifactIdNode != null && !artifactIdNode.isNull()) {
176 return artifactIdNode.asText();
177 }
178 throw new RuntimeException("ArtifactId not found in request body");
179 }
180
181 }
182 }
183