1 package io.apicurio.registry.maven;
2
3 import com.fasterxml.jackson.databind.JsonNode;
4 import com.fasterxml.jackson.databind.ObjectMapper;
5 import io.apicurio.registry.content.ContentHandle;
6 import io.apicurio.registry.content.TypedContent;
7 import io.apicurio.registry.rest.client.RegistryClient;
8 import io.apicurio.registry.rest.client.models.ArtifactReference;
9 import io.apicurio.registry.rest.client.models.CreateArtifact;
10 import io.apicurio.registry.rest.client.models.CreateArtifactResponse;
11 import io.apicurio.registry.rest.client.models.CreateVersion;
12 import io.apicurio.registry.rest.client.models.IfArtifactExists;
13 import io.apicurio.registry.rest.client.models.ProblemDetails;
14 import io.apicurio.registry.rest.client.models.VersionContent;
15 import io.apicurio.registry.types.ContentTypes;
16 import io.apicurio.registry.utils.IoUtil;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
19
20 import java.io.File;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.charset.StandardCharsets;
25 import java.nio.file.Files;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.concurrent.ExecutionException;
29 import java.util.stream.Collectors;
30
31 public abstract class AbstractDirectoryParser<Schema> {
32
33 private final RegistryClient client;
34
35 public AbstractDirectoryParser(RegistryClient client) {
36 this.client = client;
37 }
38
39 private static final Logger log = LoggerFactory.getLogger(AbstractDirectoryParser.class);
40
41 public abstract ParsedDirectoryWrapper<Schema> parse(File rootSchema);
42
43 public abstract List<ArtifactReference> handleSchemaReferences(RegisterArtifact rootArtifact,
44 Schema schema, Map<String, TypedContent> fileContents)
45 throws FileNotFoundException, ExecutionException, InterruptedException;
46
47 protected ContentHandle readSchemaContent(File schemaFile) {
48 try {
49 return ContentHandle.create(Files.readAllBytes(schemaFile.toPath()));
50 } catch (IOException e) {
51 throw new RuntimeException("Failed to read schema file: " + schemaFile, e);
52 }
53 }
54
55 protected RegisterArtifact buildFromRoot(RegisterArtifact rootArtifact, String artifactId) {
56 RegisterArtifact nestedSchema = new RegisterArtifact();
57 nestedSchema.setCanonicalize(rootArtifact.getCanonicalize());
58 nestedSchema.setArtifactId(artifactId);
59 nestedSchema.setGroupId(rootArtifact.getGroupId());
60 nestedSchema.setContentType(rootArtifact.getContentType());
61 nestedSchema.setArtifactType(rootArtifact.getArtifactType());
62 nestedSchema.setMinify(rootArtifact.getMinify());
63 nestedSchema.setContentType(rootArtifact.getContentType());
64 nestedSchema.setIfExists(rootArtifact.getIfExists());
65 return nestedSchema;
66 }
67
68 protected ArtifactReference registerNestedSchema(String referenceName,
69 List<ArtifactReference> nestedArtifactReferences, RegisterArtifact nestedSchema,
70 String artifactContent) throws FileNotFoundException, ExecutionException, InterruptedException {
71 CreateArtifactResponse car = registerArtifact(nestedSchema, IoUtil.toStream(artifactContent),
72 nestedArtifactReferences);
73 ArtifactReference referencedArtifact = new ArtifactReference();
74 referencedArtifact.setName(referenceName);
75 referencedArtifact.setArtifactId(car.getArtifact().getArtifactId());
76 referencedArtifact.setGroupId(car.getArtifact().getGroupId());
77 referencedArtifact.setVersion(car.getVersion().getVersion());
78 return referencedArtifact;
79 }
80
81 private CreateArtifactResponse registerArtifact(RegisterArtifact artifact, InputStream artifactContent,
82 List<ArtifactReference> references) throws ExecutionException, InterruptedException {
83 String groupId = artifact.getGroupId();
84 String artifactId = artifact.getArtifactId();
85 String version = artifact.getVersion();
86 String type = artifact.getArtifactType();
87 Boolean canonicalize = artifact.getCanonicalize();
88 String ct = artifact.getContentType() == null ? ContentTypes.APPLICATION_JSON
89 : artifact.getContentType();
90 String data = null;
91 try {
92 if (artifact.getMinify() != null && artifact.getMinify()) {
93 ObjectMapper objectMapper = new ObjectMapper();
94 JsonNode jsonNode = objectMapper.readValue(artifactContent, JsonNode.class);
95 data = jsonNode.toString();
96 } else {
97 data = new String(artifactContent.readAllBytes(), StandardCharsets.UTF_8);
98 }
99 } catch (IOException e) {
100 throw new RuntimeException(e);
101 }
102
103 CreateArtifact createArtifact = new CreateArtifact();
104 createArtifact.setArtifactId(artifactId);
105 createArtifact.setArtifactType(type);
106
107 CreateVersion createVersion = new CreateVersion();
108 createVersion.setVersion(version);
109 createArtifact.setFirstVersion(createVersion);
110
111 VersionContent content = new VersionContent();
112 content.setContent(data);
113 content.setContentType(ct);
114 content.setReferences(references.stream().map(r -> {
115 ArtifactReference ref = new ArtifactReference();
116 ref.setArtifactId(r.getArtifactId());
117 ref.setGroupId(r.getGroupId());
118 ref.setVersion(r.getVersion());
119 ref.setName(r.getName());
120 return ref;
121 }).collect(Collectors.toList()));
122 createVersion.setContent(content);
123
124 try {
125 var amd = client.groups().byGroupId(groupId).artifacts().post(createArtifact, config -> {
126 config.queryParameters.ifExists = IfArtifactExists.forValue(artifact.getIfExists().value());
127 config.queryParameters.canonical = canonicalize;
128 });
129
130
131
132 log.info(String.format("Successfully registered artifact [%s] / [%s]. GlobalId is [%d]", groupId,
133 artifactId, amd.getVersion().getGlobalId()));
134
135 return amd;
136
137 } catch (ProblemDetails e) {
138 throw new RuntimeException(e.getDetail());
139 }
140 }
141 }