killbill-aplcache

Details

diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java
new file mode 100644
index 0000000..bf67736
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequest.java
@@ -0,0 +1,19 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.util.userrequest;
+
+public interface CompletionUserRequest extends CompletionUserRequestNotifier, CompletionUserRequestWaiter{
+}
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java
new file mode 100644
index 0000000..62b9256
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestNotifier.java
@@ -0,0 +1,25 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.util.userrequest;
+
+import com.ning.billing.util.bus.BusEvent;
+
+public interface CompletionUserRequestNotifier {
+
+    public void notifyForCompletion();
+    
+    public void onBusEvent(BusEvent curEvent);
+}
diff --git a/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
new file mode 100644
index 0000000..7bfb6bc
--- /dev/null
+++ b/api/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestWaiter.java
@@ -0,0 +1,45 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.util.userrequest;
+
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
+import com.ning.billing.account.api.AccountChangeNotification;
+import com.ning.billing.account.api.AccountCreationNotification;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.invoice.api.InvoiceCreationNotification;
+import com.ning.billing.payment.api.PaymentError;
+import com.ning.billing.payment.api.PaymentInfo;
+import com.ning.billing.util.bus.BusEvent;
+
+public interface CompletionUserRequestWaiter {
+
+    public List<BusEvent> waitForCompletion(final long timeoutMilliSec) throws InterruptedException, TimeoutException;
+    
+    public void onAccountCreation(final AccountCreationNotification curEvent);
+
+    public void onAccountChange(final AccountChangeNotification curEvent);
+
+    public void onSubscriptionTransition(final SubscriptionTransition curEvent);    
+
+    public void onInvoiceCreation(final InvoiceCreationNotification curEvent);    
+
+    public void onPaymentInfo(final PaymentInfo curEvent);    
+
+    public void onPaymentError(final PaymentError curEvent);    
+}
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
new file mode 100644
index 0000000..a4d19b0
--- /dev/null
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/engine/core/EntitlementNotificationKey.java
@@ -0,0 +1,91 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.entitlement.engine.core;
+
+import java.util.UUID;
+import com.ning.billing.util.notificationq.NotificationKey;
+
+public class EntitlementNotificationKey implements NotificationKey {
+
+	private static final String DELIMITER = ":";
+	
+	private final UUID eventId;
+	private final int seqId;
+	
+	public EntitlementNotificationKey(final UUID eventId, int seqId) {
+		this.eventId = eventId;
+		this.seqId = seqId;
+	}
+
+	public EntitlementNotificationKey(final UUID eventId) {
+		this(eventId, 0);
+	}
+	
+	public EntitlementNotificationKey(final String input) {
+			
+		String [] parts = input.split(DELIMITER);
+		eventId = UUID.fromString(parts[0]);
+		if (parts.length == 2) {
+			seqId = Integer.valueOf(parts[1]);
+		} else {
+			seqId = 0;
+		}
+	}
+	
+	public UUID getEventId() {
+		return eventId;
+	}
+
+	public int getSeqId() {
+		return seqId;
+	}
+
+	public String toString() {
+		if (seqId == 0) {
+			return eventId.toString();
+		} else {
+			return eventId.toString() + ":" + seqId;
+		}
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((eventId == null) ? 0 : eventId.hashCode());
+		result = prime * result + seqId;
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		EntitlementNotificationKey other = (EntitlementNotificationKey) obj;
+		if (eventId == null) {
+			if (other.eventId != null)
+				return false;
+		} else if (!eventId.equals(other.eventId))
+			return false;
+		if (seqId != other.seqId)
+			return false;
+		return true;
+	}
+}
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserToken.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserToken.java
new file mode 100644
index 0000000..08f8aa4
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/user/TestUserToken.java
@@ -0,0 +1,46 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.entitlement.api.user;
+
+import org.testng.annotations.Test;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Stage;
+import com.ning.billing.entitlement.api.TestApiBase;
+import com.ning.billing.entitlement.api.billing.EntitlementBillingApiException;
+import com.ning.billing.entitlement.glue.MockEngineModuleSql;
+
+public class TestUserToken extends TestApiBase {
+
+
+    @Override
+    public Injector getInjector() {
+        return Guice.createInjector(Stage.DEVELOPMENT, new MockEngineModuleSql());
+    }
+
+    @Test(enabled= true, groups={"slow"})
+    public void testFoo() throws EntitlementBillingApiException {
+
+        
+        /*for (int i = 0; i < MAX_STRESS_ITERATIONS; i++) {
+            cleanupTest();
+            setupTest();
+            testCancelSubscriptionIMM();
+        }*/
+
+    }
+}
\ No newline at end of file
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementNotificationKey.java b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementNotificationKey.java
new file mode 100644
index 0000000..dbd7098
--- /dev/null
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/engine/core/TestEntitlementNotificationKey.java
@@ -0,0 +1,45 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.entitlement.engine.core;
+
+import java.util.UUID;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class TestEntitlementNotificationKey {
+
+	@Test(groups="fast")
+	public void testKeyWithSeqId() {
+		UUID id = UUID.randomUUID();
+		int seq = 4;
+		EntitlementNotificationKey input = new EntitlementNotificationKey(id, seq);
+		Assert.assertEquals(id.toString() + ":" + seq, input.toString());
+		EntitlementNotificationKey output = new EntitlementNotificationKey(input.toString());
+		Assert.assertEquals(output, input);
+	}
+
+	@Test(groups="fast")
+	public void testKeyWithoutSeqId() {
+		UUID id = UUID.randomUUID();
+		int seq = 0;
+		EntitlementNotificationKey input = new EntitlementNotificationKey(id, seq);
+		Assert.assertEquals(input.toString(), id.toString());
+		EntitlementNotificationKey output = new EntitlementNotificationKey(input.toString());
+		Assert.assertEquals(output, input);
+	}
+
+}
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java
new file mode 100644
index 0000000..7d835e8
--- /dev/null
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/util/KillbillEventHandler.java
@@ -0,0 +1,66 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.jaxrs.util;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import com.google.common.eventbus.Subscribe;
+import com.ning.billing.util.bus.BusEvent;
+import com.ning.billing.util.userrequest.CompletionUserRequest;
+import com.ning.billing.util.userrequest.CompletionUserRequestNotifier;
+import com.ning.billing.util.userrequest.CompletionUserRequestWaiter;
+
+public class KillbillEventHandler {
+    
+    
+    private final List<CompletionUserRequest> activeWaiters;
+    
+    public KillbillEventHandler() {
+        activeWaiters = new LinkedList<CompletionUserRequest>();
+    }
+    
+    public void registerCompletionUserRequestWaiter(final CompletionUserRequest waiter) {
+        if (waiter == null) {
+            return;
+        }
+        synchronized(activeWaiters) {
+            activeWaiters.add(waiter);
+        }
+    }
+    
+    public void unregisterCompletionUserRequestWaiter(final CompletionUserRequest waiter) {
+        if (waiter == null) {
+            return;
+        }
+        synchronized(activeWaiters) {
+            activeWaiters.remove(waiter);
+        }
+    }
+    
+    /*
+     * IRS event handler for killbill entitlement events
+     */
+    @Subscribe
+    public void handleEntitlementevents(final BusEvent event) {
+        if (activeWaiters.size() == 0) {
+            return;
+        }
+        for (CompletionUserRequestNotifier cur : activeWaiters) {
+            cur.onBusEvent(event);
+        }
+    }
+}
diff --git a/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
new file mode 100644
index 0000000..26c5184
--- /dev/null
+++ b/util/src/main/java/com/ning/billing/util/userrequest/CompletionUserRequestBase.java
@@ -0,0 +1,138 @@
+/* 
+ * Copyright 2010-2011 Ning, Inc.
+ *
+ * Ning 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 com.ning.billing.util.userrequest;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.UUID;
+import java.util.concurrent.TimeoutException;
+
+import com.ning.billing.account.api.AccountChangeNotification;
+import com.ning.billing.account.api.AccountCreationNotification;
+import com.ning.billing.entitlement.api.user.SubscriptionTransition;
+import com.ning.billing.invoice.api.InvoiceCreationNotification;
+import com.ning.billing.payment.api.PaymentError;
+import com.ning.billing.payment.api.PaymentInfo;
+import com.ning.billing.util.bus.BusEvent;
+
+public abstract class CompletionUserRequestBase implements CompletionUserRequest {
+
+    private static final long NANO_TO_MILLI_SEC = (1000L * 1000L);
+
+    private final List<BusEvent> events;
+
+    private final UUID userToken;
+    private long timeoutMilliSec;
+
+    private boolean isCompleted;
+    private long initialTimeMilliSec;
+
+
+    public CompletionUserRequestBase(final UUID userToken) {
+        this.events = new LinkedList<BusEvent>();
+        this.userToken = userToken;
+        this.isCompleted = false;
+    }
+
+    @Override
+    public List<BusEvent> waitForCompletion(final long timeoutMilliSec) throws InterruptedException, TimeoutException {
+
+        this.timeoutMilliSec = timeoutMilliSec;
+        initialTimeMilliSec = currentTimeMillis();
+        synchronized(this) {
+            long remainingTimeMillisSec = getRemainingTimeMillis();
+            while (!isCompleted && remainingTimeMillisSec > 0) {
+                wait(remainingTimeMillisSec);
+                if (isCompleted) {
+                    break;
+                }
+                remainingTimeMillisSec = getRemainingTimeMillis();
+            }
+            if (!isCompleted) {
+                throw new TimeoutException();
+            }
+        }
+        return events;
+    }
+
+    @Override
+    public void notifyForCompletion() {
+        synchronized(this) {
+            isCompleted = true;
+            notify();
+        }
+    }
+
+    private long currentTimeMillis() {
+        return System.nanoTime() / NANO_TO_MILLI_SEC;
+    }
+
+    private long getRemainingTimeMillis() {
+        return timeoutMilliSec - (currentTimeMillis() - initialTimeMilliSec);
+    }
+
+    @Override
+    public void onBusEvent(BusEvent curEvent) {
+        // Check if this is for us..
+        if (curEvent.getUserToken() == null ||
+                ! curEvent.getUserToken().equals(userToken)) {
+            return;
+        }
+        
+        events.add(curEvent);
+        
+        switch(curEvent.getBusEventType()) {
+        case ACCOUNT_CREATE:
+            onAccountCreation((AccountCreationNotification) curEvent);
+            break;
+        case ACCOUNT_CHANGE:
+            onAccountChange((AccountChangeNotification) curEvent);
+            break;
+        case SUBSCRIPTION_TRANSITION:
+            onSubscriptionTransition((SubscriptionTransition) curEvent);
+            break;
+        case INVOICE_CREATION:
+            onInvoiceCreation((InvoiceCreationNotification) curEvent);
+            break;
+        case PAYMENT_INFO:
+            onPaymentInfo((PaymentInfo) curEvent);
+            break;
+        case PAYMENT_ERROR:
+            onPaymentError((PaymentError) curEvent);
+            break;
+        default:
+            throw new RuntimeException("Unexpected event type " + curEvent.getBusEventType());
+        }
+    }
+
+    @Override
+    public abstract void onAccountCreation(final AccountCreationNotification curEvent);
+
+    @Override
+    public abstract void onAccountChange(final AccountChangeNotification curEvent);
+
+    @Override
+    public abstract void onSubscriptionTransition(final SubscriptionTransition curEvent);    
+
+    @Override
+    public abstract void onInvoiceCreation(final InvoiceCreationNotification curEvent);    
+
+    @Override
+    public abstract void onPaymentInfo(final PaymentInfo curEvent);    
+
+    @Override
+    public abstract void onPaymentError(final PaymentError curEvent);    
+}