I want to generate JSON and YAML files with my api spec everytime I build application (Gradle/Maven) that will be stored somewhere in project directory structure, is it possible other than by following class that I wrote ?
Is there any simple setting that will do the following ?
Class with code that catches content of DocumentationCache, converts it snd write into file:
package com.kovospace.paster.base.swagger.base;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kovospace.paster.base.swagger.documentationMapperAdapter.DocumentationMapperAdapter;
import io.swagger.v3.core.util.Json;
import io.swagger.v3.core.util.Yaml;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.util.StringUtils;
import springfox.documentation.service.Documentation;
import springfox.documentation.spring.web.DocumentationCache;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.stream.Stream;
import static com.kovospace.paster.base.utils.Utils.exceptionHandler;
//@Component
public abstract class DocumentGenerator<RESULT_OBJ> implements CommandLineRunner {
protected enum DocumentVersion {
V2, V3
}
@Value("${app.swagger.generated.files.path}")
private String storagePath;
@Autowired
private DocumentationCache documentationCache;
@Autowired
private ObjectMapper objectMapper;
protected abstract DocumentationMapperAdapter<RESULT_OBJ> getMapper();
protected abstract DocumentVersion getDocumentVersion();
@Override
public void run(String... args) throws IOException {
Optional.ofNullable(documentationCache.all())
.map(docMap -> docMap.entrySet())
.map(docEntries -> docEntries.stream())
.orElseGet(Stream::empty)
.forEach(docEntry -> generateAllexpectedDocumentTypes(docEntry));
}
private void generateAllexpectedDocumentTypes(final Map.Entry<String, Documentation> documentation) {
Arrays.stream(ExpectedDocumentType.values())
.forEach(documentType -> {
final String outputFilePath = getOutputFilePath(documentation, documentType.extension());
final String fileContent = converter.apply(documentation, documentType);
writeFile(fileContent, outputFilePath);
});
}
private String getOutputFilePath(final Map.Entry<String, Documentation> documentation, final String extension) {
return StringUtils.isEmpty(storagePath)
? String.format(
"%s-%s.%s", documentation.getKey(), getDocumentVersion().name(), extension)
: String.format(
"%s/%s-%s.%s", storagePath, documentation.getKey(), getDocumentVersion().name(), extension);
}
private void writeFile(final String document, final String filePath) {
final File outputFile = new File(filePath);
if (!outputFile.exists()) {
outputFile.getParentFile().mkdirs();
try {
outputFile.createNewFile();
} catch (IOException e) {
//TODO
throw new RuntimeException(e);
}
}
try (FileWriter fileWriter = new FileWriter(outputFile)) {
fileWriter.write(document);
} catch (Exception e) {
//TODO
}
}
private BiFunction<Map.Entry<String, Documentation>, ExpectedDocumentType, String> converter =
(documentationEntry, expectedDocumentType) -> {
final RESULT_OBJ swagger = getMapper().mapDocumentation(
documentationCache.documentationByGroup(documentationEntry.getKey()));
switch (expectedDocumentType) {
case JSON:
return exceptionHandler(() -> Json.pretty(swagger));
case YAML:
default:
return exceptionHandler(() -> Yaml.pretty().writeValueAsString(swagger));
}
};
}
SpringFox Configuration class:
package com.kovospace.paster.base.configurations;
import com.kovospace.paster.base.annotations.swagger.PublicEndpoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import java.util.HashSet;
@Configuration
public class SwaggerConfig {
//TODO do konstant alebo properties
private static final String BASE_PACKAGE = "com.kovospace.paster";
private static final String PUBLIC_API_GROUPNAME = "public-api";
private static final String PRIVATE_API_GROUPNAME = "devel-api";
private static final HashSet<String> RETURN_TYPES_POSSIBLE = new HashSet<String>() {{
add(MediaType.APPLICATION_JSON_VALUE);
}};
@Bean
public Docket publicApi() {
return new Docket(DocumentationType.OAS_30)
.groupName(PUBLIC_API_GROUPNAME)
.produces(RETURN_TYPES_POSSIBLE)
.select()
.apis(RequestHandlerSelectors.withMethodAnnotation(PublicEndpoint.class))
.paths(PathSelectors.any())
.build();
}
@Bean
public Docket developerApi() {
return new Docket(DocumentationType.OAS_30)
.groupName(PRIVATE_API_GROUPNAME)
.produces(RETURN_TYPES_POSSIBLE)
.select()
.apis(RequestHandlerSelectors.basePackage(BASE_PACKAGE))
.paths(PathSelectors.any())
.build();
}
}