Skip to content
This repository has been archived by the owner on Jan 21, 2024. It is now read-only.

Commit

Permalink
Merge pull request #1748 from davetobin/Fix-looping-issue
Browse files Browse the repository at this point in the history
Provisioning looping issue fix
  • Loading branch information
markewallace authored Mar 7, 2017
2 parents 89ba5b4 + 9ef09f7 commit c9c02d4
Show file tree
Hide file tree
Showing 5 changed files with 290 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ public synchronized boolean updateCurrentWeight(String url, Rest method){
logger.finest("currentWeight = " + this.currentWeight);
this.currentWeight = this.currentWeight + getWeightValuePerBSSCall(url, method);
logger.finest("currentWeight updated = " + this.currentWeight);
logger.finest("Threshold = " + threshold);
if( currentWeight >= threshold ){
callPermitted = false ;
logger.warning("THRESHOLD REACHED OR EXCEEDED !!!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -115,6 +116,14 @@ public class BSSProvisioning implements Runnable {
* number of currently provisioned subscribers
*/
protected static AtomicInteger subscribersProvisioned = new AtomicInteger(0);
/**
* number of currently failed subscribers
*/
protected static AtomicInteger subscribersFailed = new AtomicInteger(0);
/**
* list of failed subscribers
*/
protected static List<SubscriberTask> failedSubscriptions = new ArrayList<SubscriberTask>();
/**
* <code>Map</code> associating each subscribers with a String array, containing a timestamp for each
* state transition of the corresponding subscriber
Expand Down Expand Up @@ -302,7 +311,7 @@ public static void main( String[] args ){
.getAsString("EmailAddress");
SubscriberTask subscriberTask =
new SubscriberTask(subscriber, customerId, subscriptionId,
SubscriberTask.State.SUBSCRIBER_NON_EXISTENT );
SubscriberTask.State.SUBSCRIBER_NON_EXISTENT, 10);
subscriberTasks.add(subscriberTask);
stateTransitionReport.put(suscriberEmail, new String[6]);
subscriberWeightReport.put(suscriberEmail, new int[3]);
Expand Down Expand Up @@ -376,7 +385,7 @@ public void run(){
Thread.currentThread().setName("Provisioning");
}

if(BSSProvisioning.getSubscribersQuantity().get() > BSSProvisioning.getSubscribersProvisioned().get()){
if(BSSProvisioning.getSubscribersQuantity().get() > (BSSProvisioning.getSubscribersProvisioned().get() + BSSProvisioning.getSubscribersFailed().get())){
// stop submitting when the threshold has been reached and the queue has been emptied
while( !WeightManager.getInstance().isThresholdReached() && subscriberTasks != null && !subscriberTasks.isEmpty() ){
SubscriberTask subscriberTask = subscriberTasks.poll();
Expand All @@ -387,11 +396,24 @@ public void run(){
subscriberReport[0] = sdf.format(new Date());
}
threadpool.submit(subscriberTask);

if(subscriberTask.getStatus() == SubscriberTask.State.SUBSCRIBE_FAILED){
logger.info("Subscriber task for " +subscriberTask.getSubscriberId()+ " failed due to exceeded attempts");
}
}
//sleeping 250 millisec between one submit and the other with the goal of
//avoiding to overwhelm the server with requests
Thread.sleep(250);
}
}else{
if(BSSProvisioning.getSubscribersFailed().get()>0){
logger.warning("Provisioned Subscribers: "+ BSSProvisioning.getSubscribersProvisioned().get() +"\nFailed Subscribers: "+ BSSProvisioning.getSubscribersFailed().get());

}else{
logger.finest("ALL SUBSCRIBERS PROVISIONED !!!");
}
logger.info("Provisioning finished");
WeightManager.getInstance().shutdown();
}
}catch(Exception e){
logger.severe("Catched Exception in the BSSProvisioning run() method : "+e.getMessage() );
Expand Down Expand Up @@ -742,9 +764,30 @@ public static synchronized void incrementSubscribersProvisioned(){
/**
* {@link #subscribersProvisioned} getter method
*/
public static synchronized AtomicInteger getSubscribersProvisioned(){
public static synchronized AtomicInteger getSubscribersProvisioned(){
return subscribersProvisioned ;
}

/**
* {@link #subscribersFailed} incrementation method
*/
public static synchronized void incrementSubscribersFailed(){
subscribersFailed.incrementAndGet();
}

/**
* {@link #subscribersFailed} getter method
*/
public static synchronized AtomicInteger getSubscribersFailed(){
return subscribersFailed ;
}

/**
* {@link #failedSubscriptions} getter method
*/
public static synchronized List<SubscriberTask> getFailedSubscriptions(){
return failedSubscriptions ;
}

/**
* {@link #stateTransitionReport} getter method
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.authentication.SetOneTimePassword;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.ActivateSubscriber;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.AddSubscriber;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.AddSubscriberSuppressEmail;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.EntitleSubscriber;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.GetSubscriber;
import com.ibm.sbt.provisioning.sample.app.weightedBSSCall.subscriber.UpdateNotesSubscriber;
Expand All @@ -59,6 +60,7 @@ public enum State {
SUBSCRIBER_PASSWORD_CHANGED,
SUBSCRIBER_UPDATED,
SUBSCRIBER_ENTITLED,
SUBSCRIBE_FAILED,
SEAT_ASSIGNED
}

Expand All @@ -70,6 +72,10 @@ public enum State {
private String subscriberId ;
private String oneTimePassword;
private String newPassword;
private int attemptCount = 0;
private int attempts;
private boolean attemptsFlag = false;
private boolean suppressEmail = false;

/**
* Each subscriberTask has a key made up by the subscriberEmail, column, subscriptionId
Expand All @@ -87,8 +93,22 @@ public SubscriberTask(JsonJavaObject subscriber, String customerId, List<Subscri
this.subscriberEmail = this.subscriber.getAsObject("Subscriber").getAsObject("Person").getAsString("EmailAddress");
this.taskKey = this.subscriberEmail;
}

public SubscriberTask(JsonJavaObject subscriber, String customerId, List<SubscriptionEntitlement> entitlements,
State initialStatus, String newPassword, int attempts){
this.subscriber = subscriber;
this.customerId = customerId;
this.entitlements = entitlements;
this.status = initialStatus;
this.oneTimePassword = "onet1me!";
this.newPassword = newPassword;
this.subscriberEmail = this.subscriber.getAsObject("Subscriber").getAsObject("Person").getAsString("EmailAddress");
this.taskKey = this.subscriberEmail;
this.attempts = attempts;
this.attemptsFlag = true;
}

public SubscriberTask( JsonJavaObject subscriber, String customerId, String subscriptionId , State initialStatus ) {
public SubscriberTask(JsonJavaObject subscriber, String customerId, String subscriptionId, State initialStatus) {
this.subscriber = subscriber ;
this.customerId = customerId ;
this.status = initialStatus ;
Expand All @@ -97,6 +117,16 @@ public SubscriberTask( JsonJavaObject subscriber, String customerId, String subs
this.taskKey = this.subscriberEmail;
}

public SubscriberTask(JsonJavaObject subscriber, String customerId, String subscriptionId, State initialStatus, int attempts) {
this.subscriber = subscriber ;
this.customerId = customerId ;
this.status = initialStatus ;
this.oneTimePassword = "onet1me!";
this.subscriberEmail = this.subscriber.getAsObject("Subscriber").getAsObject("Person").getAsString("EmailAddress");
this.taskKey = this.subscriberEmail;
this.attempts = attempts;
this.attemptsFlag = true;
}
/**
* Business logic of the task
* <p>
Expand All @@ -113,7 +143,11 @@ public void run() {
boolean success = true ;
while( success == true ){
if (this.status == State.SUBSCRIBER_NON_EXISTENT) {
this.subscriberId = addSubscriber();
if(suppressEmail){
this.subscriberId = addSubscriberSuppressEmail();
}else{
this.subscriberId = addSubscriber();
}
if( this.subscriberId != null ) {
this.status = State.SUBSCRIBER_ADDED ;
}else{
Expand All @@ -134,14 +168,14 @@ public void run() {
} else if ( this.status == State.SUBSCRIBER_ACTIVE ) {
if (setOneTimePassword()){
this.status = State.SUBSCRIBER_ONE_TIME_PWD_SET ;
} else{
}else{
success = false ;
}
} else if(this.newPassword == null){
// If the new password is null, we don't change it, the user will change it on first login
// If the new password is not null, we change it
this.status = State.SUBSCRIBER_PASSWORD_CHANGED;
}else if( this.status == State.SUBSCRIBER_ONE_TIME_PWD_SET ){
} else if( this.status == State.SUBSCRIBER_ONE_TIME_PWD_SET ){
if(changePassword()){
this.status = State.SUBSCRIBER_PASSWORD_CHANGED;
}else{
Expand All @@ -159,12 +193,39 @@ public void run() {
}else{
success = false ;
}
} else if( this.status == State.SEAT_ASSIGNED ){
} else if( this.status == State.SEAT_ASSIGNED){
success = false ;
attemptsFlag = false;
} else if( this.status == State.SUBSCRIBE_FAILED){
success = false ;
attemptsFlag = false;
logger.info("Checking for task completion...");
logger.info("Completed: "+checkForFinish());
}
}
logger.info("Task execution exiting with status:"+ this.status.name() );
if( this.status != State.SEAT_ASSIGNED ){
if(attemptsFlag){
if(success==false){
attemptCount++;
logger.info("Attempts = " + attemptCount+"/"+attempts);
logger.info("Waiting 30 seconds before retrying task...");
try {
Thread.sleep(1000*30);
} catch (InterruptedException e) {
logger.severe(e.getMessage());
}
}
if(attemptCount>=attempts&&this.status != State.SEAT_ASSIGNED){
this.status = State.SUBSCRIBE_FAILED;
BSSProvisioning.failedSubscriptions.add(this);
BSSProvisioning.incrementSubscribersFailed();
logger.info("Checking for task completion...");
logger.info("Completed: "+checkForFinish());
}
}
logger.info("Task execution exiting with status: "+ this.status.name() );
if( this.status == State.SEAT_ASSIGNED ){
logger.info("Task exited." );
}else{
BSSProvisioning.getSubscribersTasks().add(this);
logger.info("Re-queuing it..." );
}
Expand Down Expand Up @@ -225,6 +286,31 @@ private String addSubscriber(){
return subscriberId ;
}

/**
* This method will trigger the adding of a subscriber w/ suppress email to an organization by mean of invocation of the <code>call()</code> method of the <code>abstract
* class WeightedBSSCall</code> on an instance of the <code>AddSubscriber</code> class
* <p>
* @return the BSS subscriber identifier
*/
private String addSubscriberSuppressEmail(){
String subscriberId = null ;
if( this.subscriber != null ){
((JsonJavaObject)this.subscriber.get("Subscriber")).putString("CustomerId", customerId);
WeightedBSSCall<String> addSubscriberSuppressEmail = new AddSubscriberSuppressEmail(this.subscriber);
logger.info("Adding subscriber with suppressed email...");
try{
subscriberId = addSubscriberSuppressEmail.call();
} catch (Exception e) {
logger.severe(e.getClass()+" : " + e.getMessage());
String responseBody = ((ClientServicesException) e.getCause()).getResponseBody();
if(emailAlreadyExists(responseBody)){
subscriberId = identifySubscriberState();
}
}
}
return subscriberId ;
}

private boolean emailAlreadyExists(String errorResponse){
try{
JsonJavaObject json = (JsonJavaObject) JsonParser.fromJson(JsonJavaFactory.instanceEx2, errorResponse);
Expand Down Expand Up @@ -422,8 +508,12 @@ private boolean waitForSeatAssignment(){
BSSProvisioning.incrementSubscribersProvisioned();
seatsAssigned = true;
}
if(BSSProvisioning.getSubscribersQuantity().get() == BSSProvisioning.getSubscribersProvisioned().get()){
logger.finest("ALL SUBSCRIBERS PROVISIONED !!!");
if(BSSProvisioning.getSubscribersQuantity().get() == (BSSProvisioning.getSubscribersProvisioned().get() + BSSProvisioning.getSubscribersFailed().get())){
if(BSSProvisioning.getSubscribersFailed().get()>0){
logger.warning("Provisioned Subscribers: "+ BSSProvisioning.getSubscribersProvisioned().get() +"\nFailed Subscribers: "+ BSSProvisioning.getSubscribersFailed().get());
}else{
logger.finest("ALL SUBSCRIBERS PROVISIONED !!!");
}
BSSProvisioning.generateStateTransitionReport();
BSSProvisioning.generateSubscriberWeightReport();
BSSProvisioning.generateCallsCounterReport();
Expand All @@ -439,6 +529,27 @@ private boolean waitForSeatAssignment(){
return seatsAssigned;
}

/**
* This method checks for completion of task
* @return <code>true</code> if complete, <code>false</code> otherwise
*/
private boolean checkForFinish(){
boolean completed = false;
if(BSSProvisioning.getSubscribersQuantity().get() == (BSSProvisioning.getSubscribersProvisioned().get() + BSSProvisioning.getSubscribersFailed().get())){
completed = true;
if(BSSProvisioning.getSubscribersFailed().get()>0){
logger.warning("Provisioned Subscribers: "+ BSSProvisioning.getSubscribersProvisioned().get() +"\nFailed Subscribers: "+ BSSProvisioning.getSubscribersFailed().get());
}else{
logger.finest("ALL SUBSCRIBERS PROVISIONED !!!");
}
BSSProvisioning.generateStateTransitionReport();
BSSProvisioning.generateSubscriberWeightReport();
BSSProvisioning.generateCallsCounterReport();
WeightManager.getInstance().shutdown();
}
return completed;
}

/**
* This method will loop through a list of object representing the seats a subscriber owns, looking for the
* one associated with the subscription specified as second argument
Expand Down Expand Up @@ -480,4 +591,8 @@ public String getSubscriberId() {
public String getSubscriberTaskKey() {
return taskKey;
}

public void setSuppressEmail(boolean suppress){
suppressEmail = suppress;
}
}
Loading

0 comments on commit c9c02d4

Please sign in to comment.