/*
* © Copyright IBM Corp. 2014
*
* Licensed 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 com.ibm.sbt.services.client.smartcloud.bss;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import com.ibm.commons.util.StringUtil;
import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaFactory;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.JsonParser;
import com.ibm.sbt.services.client.ClientService;
import com.ibm.sbt.services.client.Response;
import com.ibm.sbt.services.client.base.IFeedHandler;
import com.ibm.sbt.services.client.base.JsonEntity;
import com.ibm.sbt.services.client.base.NamedUrlPart;
import com.ibm.sbt.services.client.base.datahandlers.EntityList;
import com.ibm.sbt.services.endpoints.Endpoint;
/**
* Use subscription management services to create subscriptions, suspend subscriptions, get subscriptions by ID, and more.
*
* @author mwallace
*/
public class SubscriptionManagementService extends BssService {
private static final long serialVersionUID = 1L;
/**
* Constructor
*/
public SubscriptionManagementService() {
}
/**
* Constructor
*
* @param endpointName
*/
public SubscriptionManagementService(String endpointName) {
super(endpointName);
}
/**
* Constructor
*
* @param endpointName
* @param cacheSize
*/
public SubscriptionManagementService(String endpointName, int cacheSize) {
super(endpointName, cacheSize);
}
/**
* Constructor
*
* @param endpoint
* @param cacheSize
*/
public SubscriptionManagementService(Endpoint endpoint) {
super(endpoint);
}
/**
* Constructor
*
* @param endpoint
* @param cacheSize
*/
public SubscriptionManagementService(Endpoint endpoint, int cacheSize) {
super(endpoint, cacheSize);
}
/**
* Return subscription id for the specified JSON object.
*
* @param subscriptionObject
* @return
*/
public String getSubscriptionId(JsonJavaObject subscriptionObject) {
return getId(subscriptionObject, PROPERTY_SUBSCRIPTION);
}
/**
* Create one or more subscriptions for a given customer.
*
* @param order
* @return
* @throws BssException
* @throws IOException
* @throws JsonException
*/
public EntityList<JsonEntity> createSubscription(OrderJsonBuilder order) throws BssException, IOException, JsonException {
return createSubscription(order.toJson());
}
/**
* Create one or more subscriptions for a given customer.
*
* @param orderJson
* @return
* @throws BssException
* @throws JsonException
* @throws IOException
*/
public EntityList<JsonEntity> createSubscription(String orderJson) throws BssException, JsonException, IOException {
JsonJavaObject jsonObject = (JsonJavaObject)JsonParser.fromJson(JsonJavaFactory.instanceEx, orderJson);
return createSubscription(jsonObject);
}
/**
* Create one or more subscriptions for a given customer.
*
* @param orderObject
* @return
* @throws BssException
*/
public EntityList<JsonEntity> createSubscription(JsonJavaObject orderObject) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION.format(this);
Response serverResponse = createData(serviceUrl, null, JsonHeader, orderObject, ClientService.FORMAT_JSON);
IFeedHandler<JsonEntity> jsonHandler = getJsonFeedHandler();
return jsonHandler.createEntityList(serverResponse);
} catch (Exception e) {
throw new BssException(e, "Error creating subscription {0} caused by {1}", orderObject, e.getMessage());
}
}
/**
* Use the subscription ID to locate a subscription and get details about that subscription.
*
* @param subscriptionId
* @return
* @throws BssException
*/
public JsonEntity getSubscriptionById(String subscriptionId) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SUBSCRIPTIONID.format(this, new NamedUrlPart("subscriptionId", subscriptionId));
return getEntity(serviceUrl, null, getJsonFeedHandler());
} catch (Exception e) {
throw new BssException(e, "Error retrieving subscription {0} caused by {1}", subscriptionId, e.getMessage());
}
}
/**
* Get a list of subscriptions that belong to a particular customer.
*
* @param customerId
* @return
* @throws BssException
* @throws {@link IllegalArgumentException}
*/
public EntityList<JsonEntity> getSubscriptionsById(String customerId) throws BssException {
if (StringUtil.isEmpty(customerId)) {
throw new IllegalArgumentException("Invalid id");
}
try {
String serviceUrl = BssUrls.API_RESOURCE_GET_SUBSCRIPTION_BY_CUSTOMERID.format(this,
new NamedUrlPart("customerId", customerId));
return (EntityList<JsonEntity>)getEntities(serviceUrl, null, getJsonFeedHandler());
} catch (Exception e) {
throw new BssException(e, "Error retrieving subscription list by customer id {0} caused by {1}", customerId, e.getMessage());
}
}
/**
* Get a list of subscriptions for all the vendor's customers.
*
* @return
* @throws BssException
* @throws {@link IllegalArgumentException}
*/
public EntityList<JsonEntity> getSubscriptions() throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION.format(this);
return (EntityList<JsonEntity>)getEntities(serviceUrl, null, getJsonFeedHandler());
} catch (Exception e) {
throw new BssException(e, "Error retrieving subscription list caused by {0}", e.getMessage());
}
}
/**
* Get a list of subscriptions for all the vendor's customers.
*
* @param pageNumber
* @param pageSize
* @return
* @throws BssException
* @throws {@link IllegalArgumentException}
*/
public EntityList<JsonEntity> getSubscriptions(int pageNumber, int pageSize) throws BssException {
try {
HashMap<String, String> params = new HashMap<String, String>();
params.put("_pageNumber", String.valueOf(pageNumber));
params.put("_pageSize", String.valueOf(pageSize));
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION.format(this);
return (EntityList<JsonEntity>)getEntities(serviceUrl, params, getJsonFeedHandler());
} catch (Exception e) {
throw new BssException(e, "Error retrieving subscription list for page {0},{1} caused by {2}", pageNumber, pageSize, e.getMessage());
}
}
/**
* Suspend a subscription and its child subscriptions for a registered customer.
* Any subscriptions who have a seat entitled to the subscription are suspended.
* However, any seat that is assigned to subscriptions of the subscription remain in the assigned state.
*
* @param subscriptionId
* @return
* @throws BssException
*/
public void suspendSubscription(String subscriptionId) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SUBSCRIPTIONID.format(this, new NamedUrlPart("subscriptionId", subscriptionId));
Response response = createData(serviceUrl, null, SuspendSubscriptionHeader, (Object)null);
// expect a 204
int statusCode = response.getResponse().getStatusLine().getStatusCode();
if (statusCode != 204) {
throw new BssException(response, "Error suspending subscription {0} caused by {1}", subscriptionId, statusCode);
}
} catch (Exception e) {
throw new BssException(e, "Error suspending subscription {0} caused by {1}", subscriptionId, e.getMessage());
}
}
/**
* Change the status of a subscription from suspended to active. Child subscriptions are also moved to active state.
* Any subscribers who have a seat entitled to the subscription are moved from suspended to active state.
* If the subscription is a pooled child subscription, the parent subscription is also moved to active state.
*
* @param subscriptionId
* @return
* @throws BssException
*/
public void unsuspendSubscription(String subscriptionId) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SUBSCRIPTIONID.format(this, new NamedUrlPart("subscriptionId", subscriptionId));
Response response = createData(serviceUrl, (Map<String, String>)null, UnsuspendSubscriptionHeader, (Object)null);
// expect a 204
int statusCode = response.getResponse().getStatusLine().getStatusCode();
if (statusCode != 204) {
throw new BssException(response, "Error unsuspending subscription {0} caused by {1}", subscriptionId, statusCode);
}
} catch (Exception e) {
throw new BssException(e, "Error unsuspending subscription {0} caused by {1}", subscriptionId, e.getMessage());
}
}
/**
* Cancel a subscription to revoke access for all users who are entitled to the subscription.
* After you cancel the subscription, you can mark the subscription as deleted by deleting the customer.
* See the Delete customer topic for more details.
*
* @param subscriptionId
* @return
* @throws BssException
*/
public void cancelSubscription(String subscriptionId) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SUBSCRIPTIONID.format(this, new NamedUrlPart("subscriptionId", subscriptionId));
Response response = deleteData(serviceUrl, null, null);
// expect a 204
int statusCode = response.getResponse().getStatusLine().getStatusCode();
if (statusCode != 204) {
throw new BssException(response, "Error cancelling subscription {0} caused by {1}", subscriptionId, statusCode);
}
} catch (Exception e) {
throw new BssException(e, "Error cancelling subscription {0} caused by {1]", subscriptionId, e.getMessage());
}
}
/**
* Update a subscription for a registered customer to change the expiration date or the number of available seats.
* The subscription must be owned by the organization of the authenticated user.
*
* @param subscriptionObject
* @throws BssException
*/
public void updateSubscription(JsonJavaObject subscriptionObject) throws BssException {
try {
String subscriptionId = getSubscriptionId(subscriptionObject);
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SUBSCRIPTIONID.format(this, new NamedUrlPart("subscriptionId", subscriptionId));
Response response = updateData(serviceUrl, null, JsonHeader, subscriptionObject, null);
// expect a 204
int statusCode = response.getResponse().getStatusLine().getStatusCode();
if (statusCode != 204) {
throw new BssException(response, "Error updating subscription {0} causd by {1}", subscriptionObject, statusCode);
}
} catch (Exception e) {
throw new BssException(e, "Error updating subscription {0} caused by {1}", subscriptionObject, e.getMessage());
}
}
/**
* This service retrieves details of the specified seat object from the BSS database.
*
* @param subscriptionId The ID of the subscription for which quota is to be changed.
* @param seatId The ID of the seat for which quota is to be changed.
* @param seatObject The seat in JSON format
*
* @return
* @throws BssException
* @throws {@link IllegalArgumentException}
*/
public JsonEntity getSeat(String subscriptionId, String seatId) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SEAT.format(this,
new NamedUrlPart("subscriptionId", subscriptionId), new NamedUrlPart("seatId", seatId));
return getEntity(serviceUrl, null, getJsonFeedHandler());
} catch (Exception e) {
throw new BssException(e, "Error retrieving a seat caused by {0}", e.getMessage());
}
}
/**
* This operation is to assign or allocate extra storage for a pooled storage subscription.
*
* @param subscriptionId The ID of the subscription for which quota is to be changed.
* @param seatId The ID of the seat for which quota is to be changed.
* @param seatObject The seat in JSON format
*
* @return
* @throws BssException
* @throws {@link IllegalArgumentException}
*/
public void changeQuota(String subscriptionId, String seatId, JsonJavaObject seatObject) throws BssException {
try {
String serviceUrl = BssUrls.API_RESOURCE_SUBSCRIPTION_SEAT.format(this,
new NamedUrlPart("subscriptionId", subscriptionId), new NamedUrlPart("seatId", seatId));
createData(serviceUrl, null, ChangeQuotaHeaders, seatObject, ClientService.FORMAT_JSON);
} catch (Exception e) {
throw new BssException(e, "Error changing quota caused by {0}", e.getMessage());
}
}
/**
* Wait for the subscription to change to the specified state and then call the state change listener.
*
* @param subscriptionId
* @param state
* @param maxAttempts
* @param waitInterval
* @param listener
*
* @throws BssException
*/
public boolean waitSubscriptionState(String subscriptionId, String state, int maxAttempts, long waitInterval, StateChangeListener listener) throws BssException {
for (int i=0; i<maxAttempts; i++) {
JsonEntity subscription = getSubscriptionById(subscriptionId);
String currentState = subscription.getAsString("Subscription/SubscriptionState");
if (state.equalsIgnoreCase(currentState)) {
try {
listener.stateChanged(subscription);
return true;
} catch (Exception e) {
logger.log(Level.WARNING, "Error invoking subscription state listener", e);
}
}
// wait the specified interval
try {
Thread.sleep(waitInterval);
} catch (InterruptedException ie) {}
}
return false;
}
}