Skip to content

Commit

Permalink
[jgitflow]merging 'release/1.0.2' into 'master'
Browse files Browse the repository at this point in the history
  • Loading branch information
jsfrench committed Apr 9, 2018
2 parents 7d95547 + cc9b2c5 commit 3f42f52
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 69 deletions.
119 changes: 107 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,112 @@
# swaggerhub-maven-plugin
A maven plugin to download API definitions from and publish to SwaggerHub.
[![Build Status](https://travis-ci.org/swagger-api/swaggerhub-maven-plugin.svg)](https://travis-ci.org/swagger-api/swaggerhub-maven-plugin)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.swagger/swaggerhub-maven-plugin/badge.svg?style=plastic)](https://maven-badges.herokuapp.com/maven-central/io.swagger/swaggerhub-maven-plugin)
# swaggerhub-maven-plugin
A simple maven plugin to access [SwaggerHub](https:\\swaggerhub.com) hosting of [OpenAPI/Swagger](https://swagger.io/specification/) from a maven build process, primarily to integrate with other OpenAPI/Swagger maven tooling.

## Features
* Download/upload API definitions from/to SwaggerHub.
* Supports `json` and `yaml` format for API definitions.
* Authenticate with API key for restricted operations (e.g downloading a private API definition).
* Connects to SwaggerHub cloud by default or local SwaggerHub instance through optional configuration.

The pattern of usage is likely to depend on whether a [code first or design first](https://swaggerhub.com/blog/api-design/design-first-or-code-first-api-development/) approach is followed.

## Example use cases

### Code First
1. Code API implementation.
2. Automatically generate API definition from implementation, e.g. via annotations from [swagger-core](https://github.com/swagger-api/swagger-core).
3. Upload generated API definition to SwaggerHub with swaggerhub-maven-plugin.

### Design First
1. Write API definition (e.g. in Swagger Editor or SwaggerHub).
2. Download API definition with swaggerhub-maven-plugin.
3. Pass API definition to another Swagger tool e.g.
- [swagger-codegen-maven-plugin](https://github.com/swagger-api/swagger-codegen/tree/master/modules/swagger-codegen-maven-plugin) to generate API client and resource classes.
- [swagger-inflector](https://github.com/swagger-api/swagger-inflector) to automatically wire up the API definition to the implementation and provide out-of-the-box mocking.



## Goals
### download
#### Example Usage
* Download a public API definition in json format from SwaggerHub automatically as part of the default maven build lifecycle and save to a local file.
```xml
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swaggerhub-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>download</goal>
</goals>
<configuration>
<api>PetStoreAPI</api>
<owner>jsfrench</owner>
<version>1.0.0</version>
<outputFile>target/petStoreAPI.json</outputFile>
</configuration>
</execution>
</executions>
</plugin>
```

#### Parameters
* **api**: API name.
* **owner**": API owner.
* **version**: API version.
* **token**: SwaggerHub API key.
* **outputFile**: Swagger definition downloaded from SwaggerHub is written to this file.
Parameter | Description | Required | Default
--------- | ----------- | --------- | -------
**`api`** | API name | true | -
**`owner`** | API owner | true | -
**`version`** | API version | true | -
**`outputFile`** | API definition is written to this file | true | -
**`token`** | SwaggerHub API key, required to access private definitions | false | -
**`format`** | API definition format, `json` or `yaml` | false | `json`
**`host`** | URL of SwaggerHub API | false | `api.swaggerhub.com`
**`protocol`** | Protocol for SwaggerHub API,`http` or `https` | false | `https`
**`port`** | Port to access SwaggerHub API| false | `443`

***

### upload
#### Example Usage
* Upload an API definition in json format as a public API in SwaggerHub.
```xml
<plugin>
<groupId>io.swagger</groupId>
<artifactId>swaggerhub-maven-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<phase>deploy</phase>
<goals>
<goal>upload</goal>
</goals>
<configuration>
<api>PetStoreAPI</api>
<owner>jsfrench</owner>
<version>1.0.1-SNAPSHOT</version>
<inputFile>target/petStoreAPI.json</inputFile>
<token>${SWAGGERHUB_APIKEY}</token>
</configuration>
</execution>
</executions>
</plugin>
```
#### Parameters
* **api**: API name.
* **owner**": API owner.
* **version**: API version.
* **token**: SwaggerHub API key.
* **inputFile**: Path to file containing Swagger definition to upload to SwaggerHub.
Parameter | Description | Required | Default
--------- | ----------- | --------- | -------
**`api`** | API name | true | -
**`owner`** | API owner | true | -
**`version`** | API version | true | -
**`inputFile`** | Local file containing the API definition in json or yaml format | true | -
**`token`** | SwaggerHub API key | true | -
**`format`** | API definition format, `json` or `yaml` | false | `json`
**`isPrivate`** | Defines whether the API should be private on SwaggerHub (using `true` requires a paid plan) | false | `false`
**`host`** | URL of SwaggerHub API | false | `api.swaggerhub.com`
**`protocol`** | Protocol for SwaggerHub API,`http` or `https` | false | `https`
**`port`** | Port to access SwaggerHub API| false | `443`




22 changes: 13 additions & 9 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>io.github.jsfrench</groupId>
<groupId>io.swagger</groupId>
<artifactId>swaggerhub-maven-plugin</artifactId>
<version>1.0.1</version>
<version>1.0.2</version>
<packaging>maven-plugin</packaging>
<name>SwaggerHub Maven Plugin</name>
<description>A maven plugin for downloading and uploading Swagger/OAS definitions from/to SwaggerHub as
part of a build process.
</description>
<url>https://github.com/jsfrench/swaggerhub-maven-plugin</url>
<url>https://github.com/swagger-api/swaggerhub-maven-plugin</url>

<scm>
<connection>scm:git:git://github.com:jsfrench/swaggerhub-maven-plugin.git</connection>
<developerConnection>scm:git:ssh://github.com:jsfrench/swaggerhub-maven-plugin.git</developerConnection>
<url>https://github.com/jsfrench/swaggerhub-maven-plugin/tree/master</url>
<connection>scm:git:git://github.com:swagger-api/swaggerhub-maven-plugin.git</connection>
<developerConnection>scm:git:ssh://github.com:swagger-api/swaggerhub-maven-plugin.git</developerConnection>
<url>https://github.com/swagger-api/swaggerhub-maven-plugin/tree/master</url>
</scm>

<licenses>
Expand All @@ -26,10 +26,14 @@

<developers>
<developer>
<id>jsfrench</id>
<name>John French</name>
<email>[email protected]</email>
<organization>jsfrench</organization>
<organizationUrl>https://github.com/jsfrench</organizationUrl>
</developer>
<developer>
<id>webron</id>
<name>Ron Ratovsky</name>
<email>[email protected]</email>
</developer>
</developers>

Expand Down Expand Up @@ -112,7 +116,7 @@
<pushFeatures>true</pushFeatures>
<pushReleases>true</pushReleases>
<pushHotfixes>true</pushHotfixes>
<noDeploy>false</noDeploy>
<noDeploy>true</noDeploy>
<scmCommentPrefix>[jgitflow]</scmCommentPrefix>
<username>${git.user}</username>
<password>${git.password}</password>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;

import com.squareup.okhttp.HttpUrl;
import com.squareup.okhttp.MediaType;
Expand All @@ -7,6 +7,7 @@
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
import org.apache.maven.plugin.MojoExecutionException;

import java.io.IOException;

public class SwaggerHubClient {
Expand Down Expand Up @@ -51,7 +52,8 @@ public String getDefinition(SwaggerHubRequest swaggerHubRequest) throws MojoExec
private Request buildGetRequest(HttpUrl httpUrl, MediaType mediaType) {
Request.Builder requestBuilder = new Request.Builder()
.url(httpUrl)
.addHeader("Accept", mediaType.toString());
.addHeader("Accept", mediaType.toString())
.addHeader("User-Agent", "swaggerhub-maven-plugin");
if (token != null) {
requestBuilder.addHeader("Authorization", token);
}
Expand Down Expand Up @@ -79,11 +81,12 @@ public void saveDefinition(SwaggerHubRequest swaggerHubRequest) throws MojoExecu

private Request buildPostRequest(HttpUrl httpUrl, MediaType mediaType, String content) {
return new Request.Builder()
.url(httpUrl)
.addHeader("Content-Type", mediaType.toString())
.addHeader("Authorization", token)
.post(RequestBody.create(mediaType, content))
.build();
.url(httpUrl)
.addHeader("Content-Type", mediaType.toString())
.addHeader("Authorization", token)
.addHeader("User-Agent", "swaggerhub-maven-plugin")
.post(RequestBody.create(mediaType, content))
.build();
}

private HttpUrl getDownloadUrl(SwaggerHubRequest swaggerHubRequest) {
Expand All @@ -96,7 +99,6 @@ private HttpUrl getUploadUrl(SwaggerHubRequest swaggerHubRequest) {
return getBaseUrl(swaggerHubRequest.getOwner(), swaggerHubRequest.getApi())
.addEncodedQueryParameter("version", swaggerHubRequest.getVersion())
.addEncodedQueryParameter("isPrivate", Boolean.toString(swaggerHubRequest.isPrivate()))
.addEncodedQueryParameter("force", Boolean.toString(swaggerHubRequest.isForce()))
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;


import org.apache.maven.plugin.AbstractMojo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;


public class SwaggerHubRequest {
Expand All @@ -8,7 +8,6 @@ public class SwaggerHubRequest {
private final String format;
private final String swagger;
private final boolean isPrivate;
private final boolean force;

public String getApi() {
return api;
Expand All @@ -34,18 +33,13 @@ public boolean isPrivate() {
return isPrivate;
}

public boolean isForce() {
return force;
}

private SwaggerHubRequest(Builder builder) {
this.api = builder.api;
this.owner = builder.owner;
this.version = builder.version;
this.format = builder.format;
this.swagger = builder.swagger;
this.isPrivate = builder.isPrivate;
this.force = builder.force;
}

public static class Builder {
Expand All @@ -55,7 +49,6 @@ public static class Builder {
private String format;
private String swagger;
private boolean isPrivate;
private boolean force;

public Builder(String api, String owner, String version) {
this.api = api;
Expand All @@ -78,11 +71,6 @@ public Builder isPrivate(boolean isPrivate) {
return this;
}

public Builder force(boolean force) {
this.force = force;
return this;
}

public SwaggerHubRequest build() {
return new SwaggerHubRequest(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;


import org.apache.maven.plugin.AbstractMojo;
Expand Down Expand Up @@ -37,8 +37,6 @@ public class SwaggerHubUpload extends AbstractMojo {
private String inputFile;
@Parameter(property = "upload.isPrivate", defaultValue = "false")
private Boolean isPrivate;
@Parameter(property = "upload.force", defaultValue = "false")
private Boolean force;

private SwaggerHubClient swaggerHubClient;

Expand All @@ -51,8 +49,7 @@ public void execute() throws MojoExecutionException {
+ ", version: " + version
+ ", inputFile: " + inputFile
+ ", format: " + format
+ ", isPrivate: " + isPrivate
+ ", force: " + force);
+ ", isPrivate: " + isPrivate);

try {
String content = new String(Files.readAllBytes(Paths.get(inputFile)), Charset.forName("UTF-8"));
Expand All @@ -61,7 +58,6 @@ public void execute() throws MojoExecutionException {
.swagger(content)
.format(format)
.isPrivate(isPrivate)
.force(force)
.build();

swaggerHubClient.saveDefinition(swaggerHubRequest);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;

import org.apache.maven.DefaultMaven;
import org.apache.maven.Maven;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;

import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package io.github.jsfrench.swaggerhub;
package io.swagger.swaggerhub.plugin;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.matching.RequestPatternBuilder;
import com.github.tomakehurst.wiremock.matching.UrlPathPattern;
import org.codehaus.plexus.configuration.PlexusConfiguration;

Expand Down Expand Up @@ -37,8 +36,8 @@ public void testUploadYaml() throws Exception {
runTest(pom);
}

public void testUploadPrivateForcel() throws Exception {
File pom = getTestFile("src/test/resources/testProjects/upload-private-force.xml");
public void testUploadPrivate() throws Exception {
File pom = getTestFile("src/test/resources/testProjects/upload-private.xml");
runTest(pom);
}

Expand All @@ -64,7 +63,6 @@ private UrlPathPattern setupServerMocking(PlexusConfiguration config) {
int port = Integer.parseInt(config.getChild("port").getValue());
String format = config.getChild("format").getValue();
String isPrivate = config.getChild("isPrivate").getValue();
String force = config.getChild("force").getValue();


startMockServer(port);
Expand All @@ -74,10 +72,10 @@ private UrlPathPattern setupServerMocking(PlexusConfiguration config) {
stubFor(post(url)
.withQueryParam("version", equalTo(version))
.withQueryParam("isPrivate", equalTo(isPrivate != null ? isPrivate : "false"))
.withQueryParam("force", equalTo(force != null ? force : "false"))
.withHeader("Content-Type", equalToIgnoreCase(
String.format("application/%s; charset=UTF-8", format != null ? format : "json")))
.withHeader("Authorization", equalTo(token))
.withHeader("User-Agent", equalTo("swaggerhub-maven-plugin"))
.willReturn(created()));

return url;
Expand Down
4 changes: 2 additions & 2 deletions src/test/resources/testProjects/download-yaml.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.github.jsfrench.swaggerhub</groupId>
<groupId>io.swagger.swaggerhub</groupId>
<artifactId>swaggerhub-maven-plugin-test</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
Expand All @@ -10,7 +10,7 @@
<build>
<plugins>
<plugin>
<groupId>io.github.jsfrench</groupId>
<groupId>io.swagger</groupId>
<artifactId>swaggerhub-maven-plugin</artifactId>
<configuration>
<api>PetStoreAPI</api>
Expand Down
Loading

0 comments on commit 3f42f52

Please sign in to comment.