Autogenerate API docs for sidecar
Patch by Chris Lohfink, reviewed by Dinesh Joshi for CASSANDRA-15028
diff --git a/api.yaml b/api.yaml
new file mode 100644
index 0000000..a49e6a8
--- /dev/null
+++ b/api.yaml
@@ -0,0 +1,57 @@
+openapi: 3.0.0
+
+info:
+  description: Apache Cassandra sidecar
+  version: "1.0.0"
+  title: Apache Cassandra Sidecar API
+  license:
+    name: Apache 2.0
+    url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
+
+tags:
+  - name: visibility
+    description: See status of Cassandra
+  - name: management
+    description: Execute, coordinate, or schedule operations
+
+paths:
+  /api/v1/__health:
+    get:
+      tags:
+        - visibility
+      summary: Check Cassandra Health
+      operationId: health
+      description: |
+        Lists status of Cassandra Daemon and its services
+      responses:
+        '200':
+          description: Current status if Cassandra is up and returning OK status
+          content:
+            application/json:
+              schema:
+                type: object
+                items:
+                  $ref: '#/components/schemas/HealthStatus'
+        '503':
+          description: Health check failed and returning NOT_OK
+          content:
+            application/json:
+              schema:
+                type: object
+                items:
+                  $ref: '#/components/schemas/HealthStatus'
+
+components:
+  schemas:
+    HealthStatus:
+      type: object
+      required:
+        - status
+      properties:
+        status:
+          type: string
+          enum:
+            - 'OK'
+            - 'NOT_OK'
+          description: if reads are able to run through binary interface. 'OK' or 'NOT_OK'
+          example: 'OK'
diff --git a/build.gradle b/build.gradle
index b7659a8..5d4c771 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,10 +1,13 @@
+plugins {
+    id 'java'
+    id 'application'
+    id 'idea'
+    id 'org.hidetake.swagger.generator' version '2.16.0'
+}
+
 group 'org.apache.cassandra'
 version '1.0-SNAPSHOT'
 
-apply plugin: 'java'
-apply plugin: 'application'
-apply plugin: 'idea'
-
 sourceCompatibility = 1.8
 
 repositories {
@@ -41,7 +44,7 @@
     // This is needed as gradle considers `src/main/resources` as the default resources folder
     main {
         resources {
-            srcDirs = ['conf', 'setup']
+            srcDirs = ['conf', 'setup', 'src/main/resources']
         }
     }
     test {
@@ -70,7 +73,9 @@
 
     runtime group: 'commons-beanutils', name: 'commons-beanutils', version: '1.9.3'
     runtime group: 'org.yaml', name: 'snakeyaml', version: '1.23'
+
     jolokia 'org.jolokia:jolokia-jvm:1.6.0:agent'
+    swaggerUI 'org.webjars:swagger-ui:3.10.0'
 
     testCompile group: 'org.cassandraunit', name: 'cassandra-unit-shaded', version: '3.3.0.2'
     testCompile 'com.datastax.cassandra:cassandra-driver-core:3.6+:tests'
@@ -79,6 +84,19 @@
     testCompile group: 'io.vertx', name: 'vertx-junit5', version: '3.6.3'
 }
 
+swaggerSources {
+    apidoc {
+        inputFile = file('api.yaml')
+        reDoc {
+            outputDir = file('src/main/resources/docs')
+            title = 'Cassandra Sidecar API Documentation'
+        }
+        ui {
+            outputDir = file('src/main/resources/docs/swagger')
+        }
+    }
+}
+
 task copyCodeStyle(type: Copy) {
     from "ide/idea/codeStyleSettings.xml"
     into ".idea"
@@ -104,6 +122,8 @@
     delete "$projectDir/lib"
     println "Deleting agents $projectDir/src/dist/agents"
     delete "$projectDir/src/dist/agents"
+    println "Deleting generated docs $projectDir/src/main/resources/docs"
+    delete "$projectDir/src/main/resources/docs"
 
 }
 
@@ -113,5 +133,4 @@
 
 // copyDist gets called on every build
 copyDist.dependsOn installDist
-build.dependsOn copyDist
-build.dependsOn copyJolokia
+build.dependsOn copyDist, generateReDoc, generateSwaggerUI, copyJolokia
diff --git a/src/main/java/org/apache/cassandra/sidecar/MainModule.java b/src/main/java/org/apache/cassandra/sidecar/MainModule.java
index a6950a7..59113f2 100644
--- a/src/main/java/org/apache/cassandra/sidecar/MainModule.java
+++ b/src/main/java/org/apache/cassandra/sidecar/MainModule.java
@@ -28,6 +28,7 @@
 import io.vertx.ext.dropwizard.DropwizardMetricsOptions;
 import io.vertx.ext.web.Router;
 import io.vertx.ext.web.handler.LoggerHandler;
+import io.vertx.ext.web.handler.StaticHandler;
 import org.apache.cassandra.sidecar.routes.HealthCheck;
 import org.apache.cassandra.sidecar.routes.HealthService;
 import org.apache.commons.configuration2.YAMLConfiguration;
@@ -81,6 +82,14 @@
     {
         Router router = Router.router(vertx);
         router.route().handler(LoggerHandler.create());
+
+        // include docs generated into src/main/resources/docs
+        StaticHandler swagger = StaticHandler.create()
+                                             .setWebRoot("docs")
+                                             .setCachingEnabled(false);
+        router.route().path("/docs/*").handler(swagger);
+
+        // API paths
         router.route().path("/api/v1/__health").handler(healthService::handleHealth);
         return router;
     }