protected List<TransactionTask> terminate( String subscriberId, boolean override, Map<String, Object> metas) throws CatalogException { List<TransactionTask> tasks = new ArrayList<TransactionTask>(); Map<String, Object> context = RequestContextLocalStore.get().getInProcess(); final long TERMINATE_TIMESTAMP = System.currentTimeMillis(); context.put(Constants.MINIMUM_COMMITMENT_BREACH.name(), true); // check for minimum commitment... if (this.getMinimumCommitment() != null) { if (!(this.getMinimumCommitment() instanceof NoCommitment)) { long commitmentTime = this.getMinimumCommitment().getCommitmentTime(this); if (commitmentTime > TERMINATE_TIMESTAMP) { // minimum commitment breached.... set the context for penalty calculation... if (!override) { throw new CatalogException( "Minimum Commitment Period (" + (new Date(commitmentTime)).toString() + ") is still Active!!"); } } } } // Try to get subscriber instance... Subscriber subscriber = null; try { subscriber = (Subscriber) context.get(Constants.SUBSCRIBER_ENTITY.name()); if (subscriber == null) { subscriber = new FetchSubscriber(subscriberId).execute(); if (subscriber == null) throw new CatalogException( "Unable fetch Subscriber: " + subscriberId + "!! Cannot proceed with renewal... Will cause inconsistencies!!"); context.put(Constants.SUBSCRIBER_ENTITY.name(), subscriber); } } catch (FrameworkException e) { if (e instanceof CatalogException) throw ((CatalogException) e); throw new CatalogException("Failed to fetch Susbcriber: " + subscriber, e); } // check for additional policies in terminate... if (!override && !this.getEligibility().execute(subscriber, SubscriptionLifeCycleEvent.TERMINATE)) { // eligibility failed for this renewal.... convert to expire... throw new CatalogException("Terminate related policies rejected the request!!"); } // pretty much start packing up the tasks now.... // ---------- Charging Tasks /* * 1. Evaluate Penalties and create Charging Task */ context.put(Constants.SUBSCRIPTION_EVENT.name(), SubscriptionLifeCycleEvent.RENEWAL); Map<String, MonetaryUnit> penalties = this.getPrice().getPrintableAdviceOfCharge(); MonetaryUnit minimumCommitmentPenalty = penalties.get(Constants.MINIMUM_COMMITMENT_BREACH.name()); if (minimumCommitmentPenalty != null) { tasks.add(new Charging(ChargingMode.CHARGE, minimumCommitmentPenalty, subscriberId)); this.addPurchaseHistory( SubscriptionLifeCycleEvent.TERMINATE, TERMINATE_TIMESTAMP, minimumCommitmentPenalty); } MonetaryUnit terminationPenalty = penalties.get(Constants.MINIMUM_COMMITMENT_BREACH.name()); if (terminationPenalty != null) { tasks.add(new Charging(ChargingMode.CHARGE, terminationPenalty, subscriberId)); this.addPurchaseHistory( SubscriptionLifeCycleEvent.TERMINATE, TERMINATE_TIMESTAMP, terminationPenalty); } // ---------- Fulfillment Tasks /* * 1. get a list of all Atomic Products * 2. create a list of Fulfillment tasks * 3. add the fulfillment tasks to the transaction tasks */ // first, pack all the fulfillment tasks pertinent to deprovisioning for (AtomicProduct atomicProduct : this.getProvisionedProducts()) { tasks.add(new Fulfillment(FulfillmentMode.CANCEL, atomicProduct, subscriberId, null)); } tasks.add( new Notification( NotificationMode.NOTIFY_USER, this.getName(), subscriberId, SubscriptionLifeCycleEvent.TERMINATE.name(), metas)); // save states and history & ask to be saved in DB this.subscriptionHistory.add(SubscriptionLifeCycleState.IN_TERMINATION, TERMINATE_TIMESTAMP); tasks.add(new Persistence<Subscription>(PersistenceMode.SAVE, this, subscriberId)); return tasks; }
protected List<TransactionTask> renewal( String subscriberId, boolean override, Map<String, Object> metas) throws CatalogException { List<TransactionTask> tasks = new ArrayList<TransactionTask>(); Map<String, Object> context = RequestContextLocalStore.get().getInProcess(); metas.put("lifeCycleEvent", "renewal"); OfferCatalog catalog = new OfferCatalog(); Offer relevantOffer = catalog.getOfferById(this.getName()); if (relevantOffer.getOfferState() != State.PUBLISHED) { // current subscribed offer is not renewable anymore logger.info("This offer is not available for RENEWAAL anymore... Converting to expiry..."); tasks.addAll(this.expiry(subscriberId, true, metas)); return tasks; } // current subscribed offer is renewable... long RENEWAL_TIMESTAMP = System.currentTimeMillis(); // Get the Subscriber Subscriber subscriber = null; try { subscriber = (Subscriber) context.get(Constants.SUBSCRIBER_ENTITY.name()); if (subscriber == null) { subscriber = new FetchSubscriber(subscriberId).execute(); if (subscriber == null) throw new CatalogException( "Unable fetch Subscriber: " + subscriberId + "!! Cannot proceed with renewal... Will cause inconsistencies!!"); context.put(Constants.SUBSCRIBER_ENTITY.name(), subscriber); } } catch (FrameworkException e) { if (e instanceof CatalogException) throw ((CatalogException) e); throw new CatalogException("Failed to fetch Susbcriber: " + subscriber, e); } // enforce auto-termination.... if (!override && this.getAutoTermination() != null && !(this.getAutoTermination().getTerminationTime(this) > RENEWAL_TIMESTAMP)) { // its time for auto-termination... covert to expire... tasks.addAll(this.expiry(subscriberId, true, metas)); return tasks; } // check for additional policies for renewal event context.put(Constants.SUBSCRIPTION_EVENT.name(), SubscriptionLifeCycleEvent.RENEWAL); if (!override && !this.getEligibility().execute(subscriber, SubscriptionLifeCycleEvent.RENEWAL)) { // eligibility failed for this renewal.... convert to expire... tasks.addAll(this.expiry(subscriberId, true, metas)); return tasks; } // check if this renewal will breach accumulation.... if (!override && !this.getAccumulation().execute()) { // accumulation failed this renewal.... concert to expire... tasks.addAll(this.expiry(subscriberId, true, metas)); return tasks; } // pretty much start packing up the tasks now.... // ---------- Charging Tasks /* * 1. Evaluate Price and create Charging Task */ if (this.isCommercial()) { context.put(Constants.SUBSCRIPTION_EVENT.name(), SubscriptionLifeCycleEvent.RENEWAL); MonetaryUnit rate = this.getPrice().getSimpleAdviceOfCharge(); tasks.add(new Charging(ChargingMode.CHARGE, rate, subscriberId)); this.addPurchaseHistory(SubscriptionLifeCycleEvent.RENEWAL, RENEWAL_TIMESTAMP, rate); } // ---------- Fulfillment Tasks /* * 1. get a list of all Atomic Products * 2. create a list of Fulfillment tasks * 3. if trial period is being set, then adjust the validity period with trial period * 4. add the fulfillment tasks to the transaction tasks */ this.provisionedProducts.clear(); for (AtomicProduct atomicProduct : this.getAllAtomicProducts()) { AtomicProduct cloned = CloneHelper.deepClone(atomicProduct); cloned.getValidity().setActivationTime(RENEWAL_TIMESTAMP); this.addProvisionedProduct(cloned); tasks.add(new Fulfillment(FulfillmentMode.FULFILL, cloned, subscriberId, metas)); } this.setActivatedTimeNow(); tasks.add( new Future( FutureMode.SCHEDULE, SubscriptionLifeCycleEvent.RENEWAL, this.subscriptionId, subscriberId, this.getRenewalPeriod().getExpiryTimeInMillis(), metas)); // ----------- Notification Tasks /* * 1. Send Notification for each state of the Request Processing * 2. Transaction Engine must be able to use this task persistently across the entire process... */ tasks.add( new Notification( NotificationMode.NOTIFY_USER, this.getName(), subscriberId, SubscriptionLifeCycleEvent.RENEWAL.name(), metas)); // finally save this transaction to DB... this.addSubscriptionHistory(SubscriptionLifeCycleState.IN_RENEWAL, RENEWAL_TIMESTAMP); tasks.add(new Persistence<Subscription>(PersistenceMode.SAVE, this, subscriberId)); return tasks; }