All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.zodiac.sdk.nio.http.client.ClientEntryPoint Maven / Gradle / Ivy

There is a newer version: 1.6.8
Show newest version
package org.zodiac.sdk.nio.http.client;

import io.vavr.control.Either;
import io.vavr.control.Try;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

import org.zodiac.sdk.cli.*;
import org.zodiac.sdk.nio.http.NioHttpConstants;
import org.zodiac.sdk.nio.http.TransportProtocol;
import org.zodiac.sdk.nio.http.common.HTTPMethod;
import org.zodiac.sdk.nio.http.common.HTTPRequest;
import org.zodiac.sdk.nio.http.common.HTTPResponse;

@Command(name = NioHttpConstants.HTTPC, description = "httpc is a curl-like application but supports HTTP protocol only.")
public class ClientEntryPoint {
    @SubCommand(
        name = "get",
        argument = @Argument(
            name = "url",
            format = "https://some-website.ca",
            regex = "(^(https://)?\\S+$)",
            description = "The URL of the request."),
        description = "Get executes a HTTP GET request for a given URL.")
    String get;

    @SubCommand(
        name = "post",
        argument = @Argument(
            name = "url",
            format = "https://some-website.ca",
            regex = "(^(https://)?\\S+$)",
            description = "The URL of the request."),
        description = "Post executes a HTTP POST request for a given URL with inline data or from file.")
    String post;

    @Flag(
        name = "verbose",
        alias = {"--verbose", "-v"},
        required = false,
        subCommands = {"get", "post"},
        description = "Prints the detail of the response such as protocol, status, and headers.")
    boolean verbose;

    @Flag(
        name = "udp",
        alias = {"--udp"},
        required = false,
        subCommands = {"get", "post"},
        description = "Uses a UDP Selective Repeat protocol instead of the default TCP protocol.")
    boolean udp;

    @Option(
        name = "headers",
        alias = {"--header", "-h"},
        argument = @Argument(
            name = "header",
            format = "key:value",
            regex = "(^[^\\s\\:]+\\s*:\\s*[^\\s\\:]+$)",
            description = ""),
        subCommands = {"get", "post"},
        description = "Associates headers to HTTP Request with the format 'key:value'")
    List headers;

    @Option(
        name = "data",
        alias = {"--data", "-d"},
        argument = @Argument(name = "data",
            format = "{\"prop\": \"value\"}",
            regex = "(.*)", //""(^\\{(\\s*,?\\s*\\S+:\\s*\\S+\\s*)+\\}$)",
            description = ""),
        subCommands = {"post"},
        description = "Associates an inline data to the body HTTP POST request.")
    String data;

    @Option(
        name = "in",
        alias = {"--file", "-f"},
        argument = @Argument(name = "file",
            format = "/file/to/body",
            regex = "(^.*$)",
            description = ""),
        subCommands = {"post"},
        description = "Associates the content of a file to the body HTTP POST request.")
    String in;

    @Option(
        name = "out",
        alias = {"--out", "-o"},
        argument = @Argument(name = "out",
            format = "/file/to/output",
            regex = "(^\\/[\\w\\W]+\\.txt$)",
            description = ""),
        subCommands = {"get", "post"},
        description = "Outputs the response of the HTTP request to a file.")
    String out;

    @Option(
        name = "path",
        alias = {"--path", "-p"},
        argument = @Argument(name = "path",
            format = "/some/path.txt",
            regex = "(.*)",
            description = ""),
        subCommands = {"get", "post"},
        description = "Associates a path to the request when UDP is used.")
    String path;

    public ClientEntryPoint() {
        super();
    }

    public ClientEntryPoint(String get, String post, boolean verbose, boolean udp, List headers, String data,
        String in, String out, String path) {
        this.get = get;
        this.post = post;
        this.verbose = verbose;
        this.udp = udp;
        this.headers = headers;
        this.data = data;
        this.in = in;
        this.out = out;
        this.path = path;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((data == null) ? 0 : data.hashCode());
        result = prime * result + ((get == null) ? 0 : get.hashCode());
        result = prime * result + ((headers == null) ? 0 : headers.hashCode());
        result = prime * result + ((in == null) ? 0 : in.hashCode());
        result = prime * result + ((out == null) ? 0 : out.hashCode());
        result = prime * result + ((path == null) ? 0 : path.hashCode());
        result = prime * result + ((post == null) ? 0 : post.hashCode());
        result = prime * result + (udp ? 1231 : 1237);
        result = prime * result + (verbose ? 1231 : 1237);
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ClientEntryPoint other = (ClientEntryPoint)obj;
        if (data == null) {
            if (other.data != null)
                return false;
        } else if (!data.equals(other.data))
            return false;
        if (get == null) {
            if (other.get != null)
                return false;
        } else if (!get.equals(other.get))
            return false;
        if (headers == null) {
            if (other.headers != null)
                return false;
        } else if (!headers.equals(other.headers))
            return false;
        if (in == null) {
            if (other.in != null)
                return false;
        } else if (!in.equals(other.in))
            return false;
        if (out == null) {
            if (other.out != null)
                return false;
        } else if (!out.equals(other.out))
            return false;
        if (path == null) {
            if (other.path != null)
                return false;
        } else if (!path.equals(other.path))
            return false;
        if (post == null) {
            if (other.post != null)
                return false;
        } else if (!post.equals(other.post))
            return false;
        if (udp != other.udp)
            return false;
        if (verbose != other.verbose)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "ClientEntryPoint [get=" + get + ", post=" + post + ", verbose=" + verbose + ", udp=" + udp + ", headers="
            + headers + ", data=" + data + ", in=" + in + ", out=" + out + ", path=" + path + "]";
    }

    public static void entryPoint(final String[] args) {
        final Parser parser = new Parser<>(ClientEntryPoint.class);
        final Try> result = parser.parse(String.join(" ", args));

        result
            .onSuccess(success -> {
                if (success.isLeft()) {
                    System.out.println(success.getLeft());
                }

                if (success.isRight()) {
                    exec(success.get())
                        .onSuccess(response -> {
                            String whatToPrint = "\n";
                            if (success.get().verbose) {
                                whatToPrint += response != null && response.getRequest() != null ? response.getRequest() + "\n" : "";
                                whatToPrint += response != null && response.getRequest() != null ? response.messageHeader() : "\n\n";
                            }
                            whatToPrint += response != null && response.getRequest() != null ? "\n\n" + response.getBody() : "\n";
                            if (success.get().out != null && response != null) {
                                byte[] whatToPrintInBytes = whatToPrint.getBytes();
                                Try.of(() -> Files.write(Paths.get(success.get().out), whatToPrintInBytes))
                                    .onSuccess(nothing -> System.out.println("Output saved in " + success.get().out))
                                    .onFailure(failure -> System.out.println(
                                        "Something went wrong trying to save the contents of the response to the file. " + failure.getClass()
                                            .getSimpleName() + ": " + failure.getMessage()));
                            } else {
                                System.out.println(whatToPrint);
                            }
                        })
                        .onFailure(failure -> {
                            System.err.println(failure.getMessage());
                            System.err.println(parser.help());
                            System.exit(1);
                        });
                }
            })
            .onFailure(failure -> {
                System.err.println(failure.getMessage());
                System.err.println(parser.help());
                System.exit(1);
            });
    }

    static Try exec(final ClientEntryPoint ep) {
        try {
            if (ep.get == null && ep.post == null) {
                throw new ParseError("At least one of the possible sub-commands and a url must be specified.");
            }

            String host = ep.get != null ? ep.get : ep.post;

            if (ep.udp) {
                if (host.startsWith("http")) {
                    throw new ParseError("Invalid host url, do not specify an http:// prefix in UDP mode. Use the host address with " +
                        "port such as 'localhost:8007'");
                }
            } else {
                if (ep.path != null) {
                    throw new ParseError("Invalid option specified. Do not specify the '-p'/'--path' option while in TCP mode. Use the " +
                        "host path instead, such as 'http://localhost:80'");
                }

                if (!host.startsWith("http://") || !host.startsWith("https://")) {
                    host = "http://" + host;
                }
            }

            if (ep.get != null && ep.in != null) {
                throw new ParseError("Only specify both the '-f'/'--file' option when making a GET request.");
            }

            final HTTPRequest request = HTTPRequest.builder()
                .method(ep.get != null ? HTTPMethod.GET : HTTPMethod.POST)
                .url(host)
                .headers(ep.headers)
                .body(ep.data)
                .in(ep.in)
                .out(ep.out)
                .path(ep.path)
                .build();

            return Try.of(() -> new Client(TransportProtocol.of(TransportProtocol.Type.of(ep.udp ? "UDP" : "TCP"))).request(request));
        } catch (final ParseError e) {
            return Try.failure(e);
        } catch (final MalformedURLException e) {
            return Try.failure(new HTTPRequest.RequestError("Something went wrong while trying to parse the url. \n" + e.getClass()
                .getSimpleName() + ": " + e.getMessage()));
        } catch (final IOException e) {
            return Try.failure(new HTTPRequest.RequestError("Something went wrong while trying to read the contents of the input file. \n" + e
                .getClass()
                .getSimpleName() + ": " + e.getMessage()));
        } catch (final HTTPRequest.RequestError e) {
            return Try.failure(new HTTPRequest.RequestError("Something went wrong while processing the request. \n" + e.getClass()
                .getSimpleName() + ": " + e.getMessage()));
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy