SpringFox v3.0.0 get generated JSON and YAML files - store in project source (java resources)

45 Views Asked by At

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();
    }

}
0

There are 0 best solutions below