diff --git a/README.md b/README.md index ee08010..c4672f7 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,5 @@ You can configure it with `-H` for IP Adress and `-P` for port number: java -jar validationtool--standalone.jar -s -D -H 192.168.1.x -P 8081 ``` -You can HTTP-POST to `/` and the response will return the report document as defined in your validator configuration. - -Additionally there is the GET `/health` endpoint which can be used by monitoring systems. - +Details and further configuration options can be [found here](./docs/daemon.md). diff --git a/docs/daemon.md b/docs/daemon.md new file mode 100644 index 0000000..577a4c8 --- /dev/null +++ b/docs/daemon.md @@ -0,0 +1,87 @@ +# Validator daemon +You can also start the validator as a HTTP-Server. This is based JDK http server functionality. Keep that mind, if you want to deploy this +in production scenarios with heavy load. + +## Basic usage +To just use the validator daemon as is, start the _Daemon-Mode_ with the `-D` option. + +```shell +java -jar validationtool--standalone.jar -s -D +``` + +Per default the HTTP-Server listens on _localhost_ at Port 8080. + +You can configure it with `-H` for IP Adress and `-P` for port number: + +```shell +java -jar validationtool--standalone.jar -s -D -H 192.168.1.x -P 8081 +``` + +## Customized usage +You can also leverage the API to create a customized version of the Daemon. Just instantiate, configure and start the daemon like this: + +````java +Configuration config = Configuration.load(...); + +Daemon daemon = new Daemon(); +daemon.setPort("8090"); +// further config goes here +daemon.startServer(config); +```` + +The possible customizations are: + +* `bindAddress` - the interface to bind the daemon to +* `port` - the port to expose +* `threadCount` - number of worker threads to handle results +* `guiEnabled` - enable or disable the basic gui with usage information + +## Access the http interface +The validation service listens to `POST`-requests to any server uri. You need to supply the xml/object to validate in the post body. +The service expects a single plain input in the post body, e.g. `multipart/form-data` is not supported. + +Examples: + +* `cURL` +```shell script +curl --location --request POST 'http://localhost:8080' \ +--header 'Content-Type: application/xml' \ +--data-binary '@/target.xml' +``` + +* `java` (Apache HttpClient) +```java +HttpClient httpClient = HttpClientBuilder.create().build(); +HttpPost postRequest = new HttpPost("http://localhost:8080/"); +FileEntity entity = new FileEntity(Paths.get("some.xml").toFile(), ContentType.APPLICATION_XML); +postRequest.setEntity(entity); +HttpResponse response = httpClient.execute(postRequest); +System.out.println(IOUtils.toString(response.getEntity().getContent())); +``` + +* `javascript` +```javascript +var myHeaders = new Headers(); +myHeaders.append("Content-Type", "application/xml"); + +var file = ""; + +var requestOptions = { + method: 'POST', + headers: myHeaders, + body: file, + redirect: 'follow' +}; + +fetch("http://localhost:8080", requestOptions) + .then(response => response.text()) + .then(result => console.log(result)) + .catch(error => console.log('error', error)); +``` +## Authorization +There is no mechanism to check, whether client is allowed to consume the service or not. The user is responsible to secure access to the service +This can be done using infrastructural service like a forwarding proxy (e.g. `nginx` or `apache http server`) or by implementing a custom solution + +## Monitoring and administration +The validation service can be integrated in monitoring solutions like `Icinga` or `Nagios`. There is a `health` endpoint exposed under `/server/health` wich returns +some basic information about the service like memory consumption, general information about the version and a status `UP` as an XML file. \ No newline at end of file diff --git a/pom.xml b/pom.xml index 34e62a2..694557a 100644 --- a/pom.xml +++ b/pom.xml @@ -129,6 +129,12 @@ 1.0.0 test + +org.apache.httpcomponents +httpclient + 4.5.8 + + diff --git a/src/main/java/de/kosit/validationtool/daemon/Daemon.java b/src/main/java/de/kosit/validationtool/daemon/Daemon.java index 6dde8c6..fa0dcbe 100644 --- a/src/main/java/de/kosit/validationtool/daemon/Daemon.java +++ b/src/main/java/de/kosit/validationtool/daemon/Daemon.java @@ -34,17 +34,24 @@ public class Daemon { private static final int DEFAULT_PORT = 8080; - private final String hostName; + private String bindAddress; - private final int port; + private int port; - private final int threadCount; + private int threadCount; - @Setter(AccessLevel.PRIVATE) - private boolean guiDisabled = false; + private boolean guiEnabled = true; - public void disableGui() { - guiDisabled = true; + /** + * Create a new daemon. + * @param hostname the interface to bind to + * @param port the port to expose + * @param threadCount the number of working threads + */ + public Daemon(String hostname, int port, int threadCount) { + this.bindAddress = hostname; + this.port = port; + this.threadCount = threadCount; } /** @@ -75,7 +82,7 @@ public class Daemon { HttpHandler rootHandler; final DefaultCheck check = new DefaultCheck(config); final CheckHandler checkHandler = new CheckHandler(check, config.getContentRepository().getProcessor()); - if (!guiDisabled) { + if (guiEnabled) { GuiHandler gui = new GuiHandler(); rootHandler = new RoutingHandler(checkHandler, gui); } else { @@ -89,6 +96,6 @@ public class Daemon { } private InetSocketAddress getSocket() { - return new InetSocketAddress(defaultIfBlank(this.hostName, DEFAULT_HOST), this.port > 0 ? this.port : DEFAULT_PORT); + return new InetSocketAddress(defaultIfBlank(this.bindAddress, DEFAULT_HOST), this.port > 0 ? this.port : DEFAULT_PORT); } } diff --git a/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java b/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java index d1a7675..d15a39c 100644 --- a/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java +++ b/src/main/java/de/kosit/validationtool/daemon/RoutingHandler.java @@ -6,8 +6,11 @@ import lombok.RequiredArgsConstructor; import java.io.IOException; +/** + * A simple handler which routes between the {@link CheckHandler} and the {@link GuiHandler} depending on the request. + */ @RequiredArgsConstructor -public class RoutingHandler extends BaseHandler { +class RoutingHandler extends BaseHandler { private final CheckHandler checkHandler;