com.blackducksoftware.integration.hubdiff.HubDiff.java Source code

Java tutorial

Introduction

Here is the source code for com.blackducksoftware.integration.hubdiff.HubDiff.java

Source

/**
 * hub-model-diff-tool
 *
 * Copyright (C) 2017 Black Duck Software, Inc.
 * http://www.blackducksoftware.com/
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.blackducksoftware.integration.hubdiff;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.io.FileUtils;
import org.json.JSONException;
import org.skyscreamer.jsonassert.FieldComparisonFailure;
import org.skyscreamer.jsonassert.JSONCompareResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.blackducksoftware.integration.exception.EncryptionException;
import com.blackducksoftware.integration.hub.builder.HubServerConfigBuilder;
import com.blackducksoftware.integration.hub.exception.HubIntegrationException;
import com.blackducksoftware.integration.hub.global.HubServerConfig;
import com.blackducksoftware.integration.hub.request.HubRequest;
import com.blackducksoftware.integration.hub.rest.CredentialsRestConnection;
import com.blackducksoftware.integration.hub.rest.RestConnection;

public class HubDiff {
    private static final Logger log = LoggerFactory.getLogger("HubDiff");

    public static void main(String[] args) throws IOException, IllegalArgumentException, EncryptionException,
            HubIntegrationException, JSONException {
        Options options = new Options();
        Option optUrl1 = new Option("h1", "hub-url-1", true,
                "the base url to the hub. Example: http://int-hub01.dc1.lan:8080");
        Option optUsername1 = new Option("u1", "username-1", true, "the username for your hub instance");
        Option optPassword1 = new Option("p1", "password-1", true,
                "the password for your hub instance and username");
        Option optUrl2 = new Option("h2", "hub-url-2", true,
                "the base url to the hub. Example: http://int-auto.dc1.lan:9000");
        Option optUsername2 = new Option("u2", "username-2", true, "the username for your hub instance");
        Option optPassword2 = new Option("p2", "password-2", true,
                "the password for your hub instance and username");
        Option optOutputFile = new Option("o", "output", true, "the file path to your output file");

        optUrl1.setRequired(true);
        optUsername1.setRequired(true);
        optPassword1.setRequired(true);
        optUsername2.setRequired(true);
        optUrl1.setRequired(true);
        optPassword2.setRequired(true);
        optOutputFile.setRequired(false);

        // Add options to collection
        options.addOption(optUrl1);
        options.addOption(optUsername1);
        options.addOption(optPassword1);
        options.addOption(optUrl2);
        options.addOption(optUsername2);
        options.addOption(optPassword2);
        options.addOption(optOutputFile);

        // Parse the arguments array for the options
        CommandLineParser cliParser = new DefaultParser();
        HelpFormatter formatter = new HelpFormatter();
        CommandLine optionParser;
        try {
            optionParser = cliParser.parse(options, args);
        } catch (ParseException e) {
            formatter.printHelp("hub-model-generator", options);
            log.error(e.getMessage());
            System.exit(1);
            return;
        }

        // Read arguments
        String url1 = optionParser.getOptionValue("hub-url-1");
        String username1 = optionParser.getOptionValue("username-1");
        String password1 = optionParser.getOptionValue("password-1");
        String url2 = optionParser.getOptionValue("hub-url-2");
        String username2 = optionParser.getOptionValue("username-2");
        String password2 = optionParser.getOptionValue("password-2");
        String outputFilePath = optionParser.getOptionValue("output");

        HubServerConfigBuilder configBuilder = new HubServerConfigBuilder();
        configBuilder.setHubUrl(url1);
        configBuilder.setUsername(username1);
        configBuilder.setPassword(password1);
        HubServerConfig config1 = configBuilder.build();

        HubServerConfigBuilder configBuilder2 = new HubServerConfigBuilder();
        configBuilder2.setHubUrl(url2);
        configBuilder2.setUsername(username2);
        configBuilder2.setPassword(password2);
        HubServerConfig config2 = configBuilder2.build();

        HubDiff hubDiff = new HubDiff(config1, config2);
        hubDiff.printDiff(System.out);

        if (outputFilePath != null) {
            File outputFile = new File(outputFilePath);
            hubDiff.writeDiffAsCSV(outputFile);
        }
    }

    private SwaggerDoc swaggerDoc1;
    private SwaggerDoc swaggerDoc2;
    private JSONCompareResult results;

    public HubDiff(HubServerConfig config1, HubServerConfig config2)
            throws IllegalArgumentException, EncryptionException, JSONException, HubIntegrationException {
        RestConnection connection1 = new CredentialsRestConnection(config1);
        RestConnection connection2 = new CredentialsRestConnection(config2);
        connection1.connect();
        connection2.connect();

        String serverVersion1 = fetchHubVersion(connection1);
        String serverVersion2 = fetchHubVersion(connection2);
        swaggerDoc1 = new SwaggerDoc(fetch(connection1), serverVersion1);
        swaggerDoc2 = new SwaggerDoc(fetch(connection2), serverVersion2);

        try {
            saveFiles(swaggerDoc1);
            saveFiles(swaggerDoc2);
        } catch (HubIntegrationException | IOException | URISyntaxException e) {
            System.out.println("Failed to save files");
            e.printStackTrace();
        }

        results = swaggerDoc1.getDifference(swaggerDoc2);
    }

    public HubDiff(SwaggerDoc swaggerDoc1, SwaggerDoc swaggerDoc2) throws JSONException {
        this.swaggerDoc1 = swaggerDoc1;
        this.swaggerDoc2 = swaggerDoc2;
        results = swaggerDoc1.getDifference(swaggerDoc2);
    }

    public void saveFiles(SwaggerDoc swaggerDoc) throws HubIntegrationException, IOException, URISyntaxException {
        URL basePath = this.getClass().getProtectionDomain().getCodeSource().getLocation();

        File swaggerFile = new File(basePath.toURI().resolve("api-docs-" + swaggerDoc.getVersion() + ".json"));
        if (!swaggerFile.exists()) {
            FileUtils.write(swaggerFile, swaggerDoc.getSwaggerDoc(), StandardCharsets.UTF_8);
            log.info("No doc for version [{}]. Creating one now.", swaggerDoc.getVersion());
        }
    }

    public String fetch(RestConnection rest) throws HubIntegrationException {
        String url = rest.getBaseUrl() + "/api/v2/api-docs.json";
        HubRequest docsRequest = new HubRequest(rest);
        docsRequest.setUrl(url);
        log.info("Making GET request to hub: {}", url);
        return docsRequest.executeGetForResponseString().replaceAll("", "<").replaceAll("", ">");
    }

    public String fetchHubVersion(RestConnection rest) throws HubIntegrationException {
        String url = rest.getBaseUrl() + "/api/v1/current-version";
        HubRequest versionRequest = new HubRequest(rest);
        versionRequest.setUrl(url);
        log.info("Making GET request to hub: {}", url);
        return versionRequest.executeGetForResponseString().replaceAll("\"", "");

    }

    public String getDiff() {
        String diff = "";
        for (FieldComparisonFailure added : results.getFieldUnexpected()) {
            diff += ("[ADDED] " + added.getActual() + " TO " + added.getField());
            diff += ("\n");
        }
        for (FieldComparisonFailure changed : results.getFieldFailures()) {
            diff += ("[CHANGED] " + changed.getField() + " FROM " + changed.getExpected() + " TO "
                    + changed.getActual());
            diff += ("\n");
        }
        for (FieldComparisonFailure removed : results.getFieldMissing()) {
            diff += ("[REMOVED] " + removed.getExpected() + " FROM " + removed.getField());
            diff += ("\n");
        }
        return diff;
    }

    public void printDiff(OutputStream out) {
        try {
            out.write(getDiff().getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void writeDiff(File file) {
        try {
            FileUtils.write(file, getDiff(), StandardCharsets.UTF_8);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public String writeDiffAsCSV(File file) throws IOException {
        if (!file.exists()) {
            file.createNewFile();
        }

        CSVPrinter printer = new CSVPrinter(new PrintStream(file), CSVFormat.EXCEL);

        printer.printRecord("HubVersions", swaggerDoc1.getVersion(), " -> ", swaggerDoc2.getVersion());
        printer.printRecord("Operation", "Expected", "Actual", "Field");

        // Log all additions to the API
        for (FieldComparisonFailure added : results.getFieldUnexpected()) {
            printer.printRecord("ADDED", added.getExpected(), added.getActual(), added.getField());
        }
        // Log all changes made to the API
        for (FieldComparisonFailure changed : results.getFieldFailures()) {
            printer.printRecord("CHANGED", changed.getExpected(), changed.getActual(), changed.getField());
        }
        // Log all deletions made to the API
        for (FieldComparisonFailure removed : results.getFieldMissing()) {
            printer.printRecord("REMOVED", removed.getExpected(), removed.getActual(), removed.getField());
        }

        printer.close();
        return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
    }
}