/**
* Copyright (c) 2009 - 2012 Red Hat, Inc.
*
* This software is licensed to you under the GNU General Public License,
* version 2 (GPLv2). There is NO WARRANTY for this software, express or
* implied, including the implied warranties of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2
* along with this software; if not, see
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
*
* Red Hat trademarks are not licensed under GPLv2. No permission is
* granted to use or replicate Red Hat trademarks that are incorporated
* in this software or its documentation.
*/
package org.candlepin.resource;
import org.candlepin.auth.Verify;
import org.candlepin.common.exceptions.BadRequestException;
import org.candlepin.common.exceptions.NotFoundException;
import org.candlepin.controller.PoolManager;
import org.candlepin.model.Consumer;
import org.candlepin.model.ConsumerCurator;
import org.candlepin.model.Pool;
import org.candlepin.model.SubscriptionsCertificate;
import org.candlepin.model.dto.Subscription;
import org.candlepin.service.SubscriptionServiceAdapter;
import com.google.inject.Inject;
import org.jboss.resteasy.annotations.providers.jaxb.DoNotUseJAXBProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xnap.commons.i18n.I18n;
import java.util.LinkedList;
import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import io.swagger.annotations.Authorization;
/**
* SubscriptionResource
*/
@Path("/subscriptions")
@Api(value = "subscriptions", authorizations = { @Authorization("basic") })
@Consumes(MediaType.APPLICATION_JSON)
public class SubscriptionResource {
private static Logger log = LoggerFactory.getLogger(SubscriptionResource.class);
private SubscriptionServiceAdapter subService;
private ConsumerCurator consumerCurator;
private PoolManager poolManager;
private I18n i18n;
@Inject
public SubscriptionResource(SubscriptionServiceAdapter subService,
ConsumerCurator consumerCurator, PoolManager poolManager, I18n i18n) {
this.subService = subService;
this.consumerCurator = consumerCurator;
this.poolManager = poolManager;
this.i18n = i18n;
}
/**
* Retrieves the master pool generated from the specified subscription. If an appropriate master
* pool cannot be found, this method throws a NotFoundException.
*
* @param subscriptionId
* The subscription ID for which to retrieve the master pool
*
* @throws NotFoundException
* if an appropriate master pool cannot be found.
*
* @return
* the master pool for the given subscription
*/
protected Pool getMasterPoolForSubscription(String subscriptionId) {
Pool pool = this.poolManager.getMasterPoolBySubscriptionId(subscriptionId);
if (pool == null) {
throw new NotFoundException(
i18n.tr("A subscription with the ID \"{0}\" could not be found.", subscriptionId)
);
}
return pool;
}
/**
* Retrieves the subscription certificate for the given subscription ID. If the subscription
* cannot be found or does not have a certificate, this method throws a NotFoundException.
*
* @param subscriptionId
* The subscription ID for which to retrieve a subscription certificate
*
* @throws NotFoundException
* if the subscription cannot be found or the subscription does not have a certificate
*
* @return
* the certificate associated with the specified subscription
*/
protected SubscriptionsCertificate getSubscriptionCertificate(String subscriptionId) {
Pool pool = this.getMasterPoolForSubscription(subscriptionId);
if (pool.getCertificate() == null) {
throw new NotFoundException(
i18n.tr("A certificate was not found for subscription \"{0}\"", subscriptionId)
);
}
return pool.getCertificate();
}
@ApiOperation(notes = "Retrieves a list of Subscriptions", value = "getSubscriptions")
@GET
@Produces(MediaType.APPLICATION_JSON)
public List<Subscription> getSubscriptions() {
List<Subscription> subscriptions = new LinkedList<Subscription>();
for (Pool pool : this.poolManager.listMasterPools()) {
subscriptions.add(this.poolManager.fabricateSubscriptionFromPool(pool));
}
return subscriptions;
}
@ApiOperation(notes = "Retrieves a single Subscription", value = "getSubscription")
@ApiResponses({ @ApiResponse(code = 400, message = "") })
@GET
@Path("/{subscription_id}")
@Produces(MediaType.APPLICATION_JSON)
public Subscription getSubscription(@PathParam("subscription_id") String subscriptionId) {
Pool pool = this.getMasterPoolForSubscription(subscriptionId);
return this.poolManager.fabricateSubscriptionFromPool(pool);
}
@ApiOperation(notes = "Retrieves a Subscription Certificate As a PEM", value = "getSubCertAsPem")
@DoNotUseJAXBProvider
@GET
@Path("{subscription_id}/cert")
// cpc passes up content-type on all calls, make sure we don't 415 it
@Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Produces({ MediaType.TEXT_PLAIN })
public String getSubCertAsPem(
@PathParam("subscription_id") String subscriptionId) {
SubscriptionsCertificate cert = this.getSubscriptionCertificate(subscriptionId);
return cert.getCert() + cert.getKey();
}
@ApiOperation(notes = "Retrieves a Subscription Certificate", value = "getSubCert")
@GET
@Path("{subscription_id}/cert")
@Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Produces({ MediaType.APPLICATION_JSON})
public SubscriptionsCertificate getSubCert(
@PathParam("subscription_id") String subscriptionId) {
return this.getSubscriptionCertificate(subscriptionId);
}
@ApiOperation(notes = "Activates a Subscription", value = "activateSubscription")
@ApiResponses({ @ApiResponse(code = 400, message = ""), @ApiResponse(code = 503, message = ""),
@ApiResponse(code = 202, message = "") })
@POST
@Produces(MediaType.WILDCARD)
@Consumes(MediaType.WILDCARD)
public Response activateSubscription(
@ApiParam(required = true) @QueryParam("consumer_uuid") @Verify(Consumer.class) String consumerUuid,
@ApiParam(required = true) @QueryParam("email") String email,
@ApiParam(required = true) @QueryParam("email_locale") String emailLocale) {
if (email == null) {
throw new BadRequestException(i18n.tr("email is required for notification"));
}
if (emailLocale == null) {
throw new BadRequestException(i18n.tr("email locale is required for notification"));
}
Consumer consumer = consumerCurator.findByUuid(consumerUuid);
if (consumer == null) {
throw new BadRequestException(i18n.tr("No such unit: {0}", consumerUuid));
}
this.subService.activateSubscription(consumer, email, emailLocale);
// setting response status to 202 because subscription does not
// exist yet, but is currently being processed
return Response.status(Status.ACCEPTED).build();
}
@ApiOperation(notes = "Removes a Subscription", value = "deleteSubscription")
@ApiResponses({ @ApiResponse(code = 400, message = "") })
@DELETE
@Path("/{subscription_id}")
@Produces(MediaType.APPLICATION_JSON)
public void deleteSubscription(@PathParam("subscription_id") String subscriptionId) {
// Lookup pools from subscription ID
List<Pool> pools = this.poolManager.getPoolsBySubscriptionId(subscriptionId);
if (pools.isEmpty()) {
throw new NotFoundException(
i18n.tr("A subscription with the ID \"{0}\" could not be found.", subscriptionId)
);
}
for (Pool pool : pools) {
this.poolManager.deletePool(pool);
}
}
}