killbill-memoizeit
Changes
jaxrs/pom.xml 4(+4 -0)
pom.xml 2(+1 -1)
profiles/killbill/pom.xml 4(+4 -0)
profiles/killbill/src/main/java/org/killbill/billing/server/filters/ResponseCorsFilter.java 50(+50 -0)
Details
jaxrs/pom.xml 4(+4 -0)
diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index f40e5f3..0328799 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -66,6 +66,10 @@
<artifactId>jersey-server</artifactId>
</dependency>
<dependency>
+ <groupId>com.wordnik</groupId>
+ <artifactId>swagger-annotations</artifactId>
+ </dependency>
+ <dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<scope>provided</scope>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
index 95e1a82..619b9ea 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/AccountResource.java
@@ -107,11 +107,16 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.ACCOUNTS_PATH)
+@Api(value = JaxrsResource.ACCOUNTS_PATH, description = "Operations on accounts")
public class AccountResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "accountId";
@@ -145,6 +150,9 @@ public class AccountResource extends JaxRsResourceBase {
@GET
@Path("/{accountId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve an account", response = AccountJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid accountId supplied"),
+ @ApiResponse(code = 404, message = "Account not found")})
public Response getAccount(@PathParam("accountId") final String accountId,
@QueryParam(QUERY_ACCOUNT_WITH_BALANCE) @DefaultValue("false") final Boolean accountWithBalance,
@QueryParam(QUERY_ACCOUNT_WITH_BALANCE_AND_CBA) @DefaultValue("false") final Boolean accountWithBalanceAndCBA,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
index ad97126..5612bf9 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/BundleResource.java
@@ -71,10 +71,12 @@ import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.BUNDLES_PATH)
+@Api(value = JaxrsResource.BUNDLES_PATH, description = "Operations on bundles")
public class BundleResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "bundleId";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
index 1de293d..fbc85ab 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CatalogResource.java
@@ -46,12 +46,14 @@ import org.killbill.xmlloader.XMLWriter;
import com.codahale.metrics.annotation.Timed;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.APPLICATION_XML;
@Singleton
@Path(JaxrsResource.CATALOG_PATH)
+@Api(value = JaxrsResource.CATALOG_PATH, description = "Catalog information")
public class CatalogResource extends JaxRsResourceBase {
private final CatalogService catalogService;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
index 3af4ca5..1ea0c3f 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CreditResource.java
@@ -52,11 +52,13 @@ import org.killbill.billing.util.callcontext.TenantContext;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.CREDITS_PATH)
+@Api(value = JaxrsResource.CREDITS_PATH, description = "Operations on credits")
public class CreditResource extends JaxRsResourceBase {
private final InvoiceUserApi invoiceUserApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
index 35556ad..50d3ec7 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/CustomFieldResource.java
@@ -49,11 +49,13 @@ import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.CUSTOM_FIELDS_PATH)
+@Api(value = JaxrsResource.CUSTOM_FIELDS_PATH, description = "Operations on custom fields")
public class CustomFieldResource extends JaxRsResourceBase {
@Inject
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
index 672d7e2..0dc4810 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/ExportResource.java
@@ -43,11 +43,13 @@ import org.killbill.billing.util.callcontext.CallContext;
import com.codahale.metrics.annotation.Timed;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.TEXT_PLAIN;
@Singleton
@Path(JaxrsResource.EXPORT_PATH)
+@Api(value = JaxrsResource.EXPORT_PATH, description = "Export endpoints")
public class ExportResource extends JaxRsResourceBase {
private final ExportUserApi exportUserApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
index 2995a0c..1c6dad5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoicePaymentResource.java
@@ -71,10 +71,12 @@ import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.INVOICE_PAYMENTS_PATH)
+@Api(value = JaxrsResource.INVOICE_PAYMENTS_PATH, description = "Operations on invoice payments")
public class InvoicePaymentResource extends JaxRsResourceBase {
private static final String ID_PARAM_NAME = "paymentId";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
index 43ab896..d91d658 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/InvoiceResource.java
@@ -90,11 +90,13 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.TEXT_HTML;
@Path(JaxrsResource.INVOICES_PATH)
+@Api(value = JaxrsResource.INVOICES_PATH, description = "Operations on invoices")
public class InvoiceResource extends JaxRsResourceBase {
private static final Logger log = LoggerFactory.getLogger(InvoiceResource.class);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
index aeabae3..a6d97d0 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxrsResource.java
@@ -191,6 +191,9 @@ public interface JaxrsResource {
// No PREFIX here!
public static final String PLUGINS_PATH = "/" + PLUGINS;
+ public static final String TEST = "test";
+ public static final String TEST_PATH = PREFIX + "/" + TEST;
+
public static final String CBA_REBALANCING = "cbaRebalancing";
public static final String PAUSE = "pause";
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
index 829bef6..dd84e46 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentGatewayResource.java
@@ -58,11 +58,13 @@ import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.MediaType.WILDCARD;
@Path(JaxrsResource.PAYMENT_GATEWAYS_PATH)
+@Api(value = JaxrsResource.PAYMENT_GATEWAYS_PATH, description = "HPP endpoints")
public class PaymentGatewayResource extends JaxRsResourceBase {
private final PaymentGatewayApi paymentGatewayApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
index 183eb21..752b80c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentMethodResource.java
@@ -63,11 +63,13 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.PAYMENT_METHODS_PATH)
+@Api(value = JaxrsResource.PAYMENT_METHODS_PATH, description = "Operations on payment methods")
public class PaymentMethodResource extends JaxRsResourceBase {
@Inject
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
index b9496c4..f9ad929 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PaymentResource.java
@@ -65,10 +65,12 @@ import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.PAYMENTS_PATH)
+@Api(value = JaxrsResource.PAYMENTS_PATH, description = "Operations on payments")
public class PaymentResource extends JaxRsResourceBase {
@Inject
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
index f581061..2526e84 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/PluginResource.java
@@ -62,9 +62,11 @@ import com.google.common.io.ByteStreams;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
+import com.wordnik.swagger.annotations.Api;
@Singleton
@Path(JaxrsResource.PLUGINS_PATH + "{subResources:.*}")
+@Api(value = JaxrsResource.PLUGINS_PATH + "{subResources:.*}", description = "Plugins servlets", hidden = true)
public class PluginResource extends JaxRsResourceBase {
private static final Logger log = LoggerFactory.getLogger(PluginResource.class);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
index c4348b5..a9abece 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SecurityResource.java
@@ -47,11 +47,15 @@ import com.google.common.base.Functions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.inject.Inject;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.SECURITY_PATH)
+@Api(value = JaxrsResource.SECURITY_PATH, description = "Information about RBAC")
public class SecurityResource extends JaxRsResourceBase {
private final SecurityApi securityApi;
@@ -74,6 +78,8 @@ public class SecurityResource extends JaxRsResourceBase {
@GET
@Path("/permissions")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "List user permissions", response = String.class, responseContainer = "List")
+ @ApiResponses(value = {})
public Response getCurrentUserPermissions(@javax.ws.rs.core.Context final HttpServletRequest request) {
final Set<Permission> permissions = securityApi.getCurrentUserPermissions(context.createContext(request));
final List<String> json = ImmutableList.<String>copyOf(Iterables.<Permission, String>transform(permissions, Functions.toStringFunction()));
@@ -84,6 +90,8 @@ public class SecurityResource extends JaxRsResourceBase {
@GET
@Path("/subject")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Get user information", response = SubjectJson.class)
+ @ApiResponses(value = {})
public Response getCurrentUserSubject(@javax.ws.rs.core.Context final HttpServletRequest request) {
final Subject subject = SecurityUtils.getSubject();
final SubjectJson subjectJson = new SubjectJson(subject);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
index ddd2768..67268f2 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/SubscriptionResource.java
@@ -80,10 +80,12 @@ import org.killbill.billing.util.userrequest.CompletionUserRequestBase;
import com.codahale.metrics.annotation.Timed;
import com.google.inject.Inject;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.SUBSCRIPTIONS_PATH)
+@Api(value = JaxrsResource.SUBSCRIPTIONS_PATH, description = "Operations on subscriptions")
public class SubscriptionResource extends JaxRsResourceBase {
private static final Logger log = LoggerFactory.getLogger(SubscriptionResource.class);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
index 343dd43..e2a1ce8 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagDefinitionResource.java
@@ -55,11 +55,16 @@ import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.TAG_DEFINITIONS_PATH)
+@Api(value = JaxrsResource.TAG_DEFINITIONS_PATH, description = "Operations on tag definitions")
public class TagDefinitionResource extends JaxRsResourceBase {
@Inject
@@ -77,6 +82,8 @@ public class TagDefinitionResource extends JaxRsResourceBase {
@Timed
@GET
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "List tag definitions", response = TagDefinitionJson.class, responseContainer = "List")
+ @ApiResponses(value = {})
public Response getTagDefinitions(@javax.ws.rs.core.Context final HttpServletRequest request,
@QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode) {
final TenantContext tenantContext = context.createContext(request);
@@ -95,6 +102,8 @@ public class TagDefinitionResource extends JaxRsResourceBase {
@GET
@Path("/{tagDefinitionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a tag definition", response = TagDefinitionJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tagDefinitionId supplied")})
public Response getTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
@QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@javax.ws.rs.core.Context final HttpServletRequest request) throws TagDefinitionApiException {
@@ -109,6 +118,8 @@ public class TagDefinitionResource extends JaxRsResourceBase {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Create a tag definition")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid name or description supplied")})
public Response createTagDefinition(final TagDefinitionJson json,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
@@ -127,6 +138,8 @@ public class TagDefinitionResource extends JaxRsResourceBase {
@DELETE
@Path("/{tagDefinitionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Delete a tag definition")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tagDefinitionId supplied")})
public Response deleteTagDefinition(@PathParam("tagDefinitionId") final String tagDefId,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
index 4871ce2..6370612 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TagResource.java
@@ -53,11 +53,16 @@ import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.TAGS_PATH)
+@Api(value = JaxrsResource.TAGS_PATH, description = "Operations on tags")
public class TagResource extends JaxRsResourceBase {
@Inject
@@ -76,6 +81,8 @@ public class TagResource extends JaxRsResourceBase {
@GET
@Path("/" + PAGINATION)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "List tags", response = TagJson.class, responseContainer = "List")
+ @ApiResponses(value = {})
public Response getTags(@QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset,
@QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit,
@QueryParam(QUERY_AUDIT) @DefaultValue("NONE") final AuditMode auditMode,
@@ -107,6 +114,8 @@ public class TagResource extends JaxRsResourceBase {
@GET
@Path("/" + SEARCH + "/{searchKey:" + ANYTHING_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Search tags", response = TagJson.class, responseContainer = "List")
+ @ApiResponses(value = {})
public Response searchTags(@PathParam("searchKey") final String searchKey,
@QueryParam(QUERY_SEARCH_OFFSET) @DefaultValue("0") final Long offset,
@QueryParam(QUERY_SEARCH_LIMIT) @DefaultValue("100") final Long limit,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
index b0e6789..50f8625 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TenantResource.java
@@ -57,11 +57,16 @@ import org.killbill.billing.util.callcontext.TenantContext;
import com.codahale.metrics.annotation.Timed;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.TENANTS_PATH)
+@Api(value = JaxrsResource.TENANTS_PATH, description = "Operations on tenants")
public class TenantResource extends JaxRsResourceBase {
private final TenantUserApi tenantApi;
@@ -84,6 +89,9 @@ public class TenantResource extends JaxRsResourceBase {
@GET
@Path("/{tenantId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a tenant by id", response = TenantJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tenantId supplied"),
+ @ApiResponse(code = 404, message = "Tenant not found")})
public Response getTenant(@PathParam("tenantId") final String tenantId) throws TenantApiException {
final Tenant tenant = tenantApi.getTenantById(UUID.fromString(tenantId));
return Response.status(Status.OK).entity(new TenantJson(tenant)).build();
@@ -92,6 +100,8 @@ public class TenantResource extends JaxRsResourceBase {
@Timed
@GET
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a tenant by its API key", response = TenantJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 404, message = "Tenant not found")})
public Response getTenantByApiKey(@QueryParam(QUERY_API_KEY) final String externalKey) throws TenantApiException {
final Tenant tenant = tenantApi.getTenantByApiKey(externalKey);
return Response.status(Status.OK).entity(new TenantJson(tenant)).build();
@@ -101,6 +111,8 @@ public class TenantResource extends JaxRsResourceBase {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Create a tenant")
+ @ApiResponses(value = {@ApiResponse(code = 500, message = "Tenant already exists")})
public Response createTenant(final TenantJson json,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
@@ -117,6 +129,8 @@ public class TenantResource extends JaxRsResourceBase {
@Path("/" + REGISTER_NOTIFICATION_CALLBACK)
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Create a push notification")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tenantId supplied")})
public Response registerPushNotificationCallback(@PathParam("tenantId") final String tenantId,
@QueryParam(QUERY_NOTIFICATION_CALLBACK) final String notificationCallback,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@@ -133,6 +147,8 @@ public class TenantResource extends JaxRsResourceBase {
@GET
@Path("/" + REGISTER_NOTIFICATION_CALLBACK)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve a push notification", response = TenantKeyJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tenantId supplied")})
public Response getPushNotificationCallbacks(@javax.ws.rs.core.Context final HttpServletRequest request) throws TenantApiException {
final TenantContext tenatContext = context.createContext(request);
@@ -144,6 +160,8 @@ public class TenantResource extends JaxRsResourceBase {
@Timed
@DELETE
@Path("/REGISTER_NOTIFICATION_CALLBACK")
+ @ApiOperation(value = "Delete a push notification")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid tenantId supplied")})
public Response deletePushNotificationCallbacks(@PathParam("tenantId") final String tenantId,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
index cc11223..d8f74e6 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TestResource.java
@@ -55,6 +55,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
+import com.wordnik.swagger.annotations.Api;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@@ -67,7 +68,8 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
// so to be used with great caution.
//
//
-@Path(JaxrsResource.PREFIX + "/test")
+@Path(JaxrsResource.TEST_PATH)
+@Api(value = JaxrsResource.TEST_PATH, description = "Operations for testing")
public class TestResource extends JaxRsResourceBase {
private static final Logger log = LoggerFactory.getLogger(TestResource.class);
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
index d3bca8c..41c1ae5 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/TransactionResource.java
@@ -67,10 +67,15 @@ import com.google.common.base.Function;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Path(JaxrsResource.PAYMENT_TRANSACTIONS)
+@Api(value = JaxrsResource.PAYMENT_TRANSACTIONS, description = "Operations on payment transactions")
public class TransactionResource extends JaxRsResourceBase {
@Inject
@@ -90,6 +95,9 @@ public class TransactionResource extends JaxRsResourceBase {
@Path("/{transactionId:" + UUID_PATTERN + "}/")
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Mark a pending payment transaction as succeeded or failed")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid paymentId supplied"),
+ @ApiResponse(code = 404, message = "Account or Payment not found")})
public Response notifyStateChanged(final PaymentTransactionJson json,
@PathParam("transactionId") final String transactionIdStr,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
index 048cae1..9df0f4c 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/UsageResource.java
@@ -60,10 +60,16 @@ import com.codahale.metrics.annotation.Timed;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.inject.Singleton;
+import com.wordnik.swagger.annotations.Api;
+import com.wordnik.swagger.annotations.ApiOperation;
+import com.wordnik.swagger.annotations.ApiResponse;
+import com.wordnik.swagger.annotations.ApiResponses;
+
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
@Singleton
@Path(JaxrsResource.USAGES_PATH)
+@Api(value = JaxrsResource.USAGES_PATH, description = "Operations on usage")
public class UsageResource extends JaxRsResourceBase {
private final UsageUserApi usageUserApi;
@@ -89,6 +95,8 @@ public class UsageResource extends JaxRsResourceBase {
@POST
@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Record usage for a subscription")
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Invalid subscription (e.g. inactive)")})
public Response recordUsage(final SubscriptionUsageRecordJson json,
@HeaderParam(HDR_CREATED_BY) final String createdBy,
@HeaderParam(HDR_REASON) final String reason,
@@ -116,6 +124,8 @@ public class UsageResource extends JaxRsResourceBase {
@GET
@Path("/{subscriptionId:" + UUID_PATTERN + "}/{unitType}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve usage for a subscription and unit type", response = RolledUpUsageJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Missing start date or end date")})
public Response getUsage(@PathParam("subscriptionId") final String subscriptionId,
@PathParam("unitType") final String unitType,
@QueryParam(QUERY_START_DATE) final String startDate,
@@ -139,6 +149,8 @@ public class UsageResource extends JaxRsResourceBase {
@GET
@Path("/{subscriptionId:" + UUID_PATTERN + "}")
@Produces(APPLICATION_JSON)
+ @ApiOperation(value = "Retrieve usage for a subscription", response = RolledUpUsageJson.class)
+ @ApiResponses(value = {@ApiResponse(code = 400, message = "Missing start date or end date")})
public Response getAllUsage(@PathParam("subscriptionId") final String subscriptionId,
@QueryParam(QUERY_START_DATE) final String startDate,
@QueryParam(QUERY_END_DATE) final String endDate,
pom.xml 2(+1 -1)
diff --git a/pom.xml b/pom.xml
index 49396f1..77ae8ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@
<parent>
<artifactId>killbill-oss-parent</artifactId>
<groupId>org.kill-bill.billing</groupId>
- <version>0.7.30</version>
+ <version>0.7.31-SNAPSHOT</version>
</parent>
<artifactId>killbill</artifactId>
<version>0.11.13-SNAPSHOT</version>
profiles/killbill/pom.xml 4(+4 -0)
diff --git a/profiles/killbill/pom.xml b/profiles/killbill/pom.xml
index a2714f6..f8b53a0 100644
--- a/profiles/killbill/pom.xml
+++ b/profiles/killbill/pom.xml
@@ -64,6 +64,10 @@
<artifactId>jersey-guice</artifactId>
</dependency>
<dependency>
+ <groupId>com.wordnik</groupId>
+ <artifactId>swagger-jersey-jaxrs_2.10</artifactId>
+ </dependency>
+ <dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java6</artifactId>
</dependency>
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/filters/ResponseCorsFilter.java b/profiles/killbill/src/main/java/org/killbill/billing/server/filters/ResponseCorsFilter.java
new file mode 100644
index 0000000..00cc162
--- /dev/null
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/filters/ResponseCorsFilter.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2014 Groupon, Inc
+ * Copyright 2014 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.server.filters;
+
+import java.io.IOException;
+
+import javax.inject.Singleton;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+@Singleton
+public class ResponseCorsFilter implements Filter {
+
+ @Override
+ public void init(final FilterConfig filterConfig) throws ServletException {
+ }
+
+ @Override
+ public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
+ final HttpServletResponse res = (HttpServletResponse) response;
+ res.addHeader("Access-Control-Allow-Origin", "*");
+ res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
+ res.addHeader("Access-Control-Allow-Headers", "Content-Type");
+ chain.doFilter(request, response);
+ }
+
+ @Override
+ public void destroy() {
+ }
+}
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
index 21dfe24..9efd504 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
@@ -28,6 +28,7 @@ import org.killbill.billing.server.filters.ProfilingContainerResponseFilter;
import org.killbill.billing.jaxrs.util.KillbillEventHandler;
import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.platform.config.DefaultKillbillConfigSource;
+import org.killbill.billing.server.filters.ResponseCorsFilter;
import org.killbill.billing.server.modules.KillbillServerModule;
import org.killbill.billing.server.security.TenantFilter;
import org.killbill.bus.api.PersistentBus;
@@ -38,20 +39,25 @@ import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Module;
import com.google.inject.servlet.ServletModule;
+import com.wordnik.swagger.jaxrs.config.BeanConfig;
public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
private static final Logger logger = LoggerFactory.getLogger(KillbillGuiceListener.class);
+ private static final String SWAGGER_PATH = "api-docs";
+
private KillbillEventHandler killbilleventHandler;
@Override
protected ServletModule getServletModule() {
// Don't filter all requests through Jersey, only the JAX-RS APIs (otherwise,
// things like static resources, favicon, etc. are 404'ed)
- final BaseServerModuleBuilder builder = new BaseServerModuleBuilder().setJaxrsUriPattern("(" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*")
+ final BaseServerModuleBuilder builder = new BaseServerModuleBuilder().setJaxrsUriPattern("/" + SWAGGER_PATH + "|((/" + SWAGGER_PATH + "|" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*)")
.addJaxrsResource("org.killbill.billing.jaxrs.mappers")
- .addJaxrsResource("org.killbill.billing.jaxrs.resources");
+ .addJaxrsResource("org.killbill.billing.jaxrs.resources")
+ // Swagger integration
+ .addJaxrsResource("com.wordnik.swagger.jersey.listing");
//
// Add jersey filters which are executed prior jersey write the output stream
@@ -62,6 +68,8 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
//builder.addJerseyFilter(GZIPContentEncodingFilter.class.getName());
builder.addJerseyFilter(ProfilingContainerResponseFilter.class.getName());
+ builder.addFilter("/" + SWAGGER_PATH + "*", ResponseCorsFilter.class);
+
// Add TenantFilter right after is multi-tenancy has been configured.
if (config.isMultiTenancyEnabled()) {
builder.addFilter("/*", TenantFilter.class);
@@ -103,4 +111,18 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
logger.warn("Failed to unregister for event notifications", e);
}
}
+
+ @Override
+ protected void startLifecycleStage3() {
+ super.startLifecycleStage3();
+
+ final BeanConfig config = new BeanConfig();
+ config.setResourcePackage("org.killbill.billing.jaxrs.resources");
+ config.setTitle("Kill Bill");
+ config.setDescription("Kill Bill is an open-source billing and payments platform");
+ config.setContact("killbilling-users@googlegroups.com");
+ config.setLicense("Apache License, Version 2.0");
+ config.setLicenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html");
+ config.setScan(true);
+ }
}
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index 42c7487..c853dad 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -51,6 +51,7 @@ import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.server.DefaultServerService;
import org.killbill.billing.server.ServerService;
import org.killbill.billing.server.config.KillbillServerConfig;
+import org.killbill.billing.server.filters.ResponseCorsFilter;
import org.killbill.billing.server.notifications.PushNotificationListener;
import org.killbill.billing.subscription.glue.DefaultSubscriptionModule;
import org.killbill.billing.tenant.glue.TenantModule;
@@ -89,6 +90,7 @@ public class KillbillServerModule extends KillbillPlatformModule {
installKillbillModules();
configureResources();
+ configureFilters();
configurePushNotification();
}
@@ -169,6 +171,10 @@ public class KillbillServerModule extends KillbillPlatformModule {
bind(TenantResource.class).asEagerSingleton();
}
+ protected void configureFilters() {
+ bind(ResponseCorsFilter.class).asEagerSingleton();
+ }
+
protected void configurePushNotification() {
bind(ServerService.class).to(DefaultServerService.class).asEagerSingleton();
bind(PushNotificationListener.class).asEagerSingleton();