killbill-aplcache
Changes
profiles/killbill/src/main/java/org/killbill/billing/server/config/MultiTenantNotificationConfig.java 68(+68 -0)
profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java 6(+5 -1)
profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationKey.java 11(+6 -5)
Details
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/config/MultiTenantNotificationConfig.java b/profiles/killbill/src/main/java/org/killbill/billing/server/config/MultiTenantNotificationConfig.java
new file mode 100644
index 0000000..cfea29b
--- /dev/null
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/config/MultiTenantNotificationConfig.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2014-2016 Groupon, Inc
+ * Copyright 2014-2016 The Billing Project, LLC
+ *
+ * The Billing Project 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 org.killbill.billing.server.config;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.killbill.billing.callcontext.InternalTenantContext;
+import org.killbill.billing.payment.glue.PaymentModule;
+import org.killbill.billing.util.config.definition.NotificationConfig;
+import org.killbill.billing.util.config.tenant.CacheConfig;
+import org.killbill.billing.util.config.tenant.MultiTenantConfigBase;
+import org.skife.config.Param;
+import org.skife.config.TimeSpan;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+
+public class MultiTenantNotificationConfig extends MultiTenantConfigBase implements NotificationConfig {
+
+ private final NotificationConfig staticConfig;
+
+ @Inject
+ public MultiTenantNotificationConfig(@Named(PaymentModule.STATIC_CONFIG) final NotificationConfig staticConfig, final CacheConfig cacheConfig) {
+ super(cacheConfig);
+ this.staticConfig = staticConfig;
+ }
+
+ @Override
+ protected Method getConfigStaticMethod(final String methodName) {
+ try {
+ return NotificationConfig.class.getMethod(methodName, InternalTenantContext.class);
+ } catch (final NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public List<TimeSpan> getPushNotificationsRetries() {
+ return staticConfig.getPushNotificationsRetries();
+ }
+
+ @Override
+ public List<TimeSpan> getPushNotificationsRetries(@Param("dummy") final InternalTenantContext tenantContext) {
+ final Method method = new Object() {}.getClass().getEnclosingMethod();
+
+ final String result = getStringTenantConfig(method.getName(), tenantContext);
+ if (result != null) {
+ return convertToListTimeSpan(result, method.getName());
+ }
+ return getPushNotificationsRetries();
+ }
+}
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
index cd01301..ff6de44 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/modules/KillbillServerModule.java
@@ -58,6 +58,7 @@ import org.killbill.billing.platform.api.KillbillConfigSource;
import org.killbill.billing.server.DefaultServerService;
import org.killbill.billing.server.ServerService;
import org.killbill.billing.server.config.KillbillServerConfig;
+import org.killbill.billing.server.config.MultiTenantNotificationConfig;
import org.killbill.billing.server.filters.ResponseCorsFilter;
import org.killbill.billing.server.notifications.PushNotificationListener;
import org.killbill.billing.server.notifications.PushNotificationRetryService;
@@ -96,10 +97,12 @@ import org.skife.jdbi.v2.tweak.ResultSetMapper;
import ch.qos.logback.classic.helpers.MDCInsertingServletFilter;
import com.google.inject.multibindings.Multibinder;
+import com.google.inject.name.Names;
public class KillbillServerModule extends KillbillPlatformModule {
public static final String SHIRO_DATA_SOURCE_ID = "shiro";
+ public static final String STATIC_CONFIG = "StaticConfig";
public KillbillServerModule(final ServletContext servletContext, final KillbillServerConfig serverConfig, final KillbillConfigSource configSource) {
super(servletContext, serverConfig, configSource);
@@ -212,7 +215,8 @@ public class KillbillServerModule extends KillbillPlatformModule {
protected void configurePushNotification() {
final ConfigurationObjectFactory factory = new ConfigurationObjectFactory(skifeConfigSource);
final NotificationConfig notificationConfig = factory.build(NotificationConfig.class);
- bind(NotificationConfig.class).toInstance(notificationConfig);
+ bind(NotificationConfig.class).annotatedWith(Names.named(STATIC_CONFIG)).toInstance(notificationConfig);
+ bind(NotificationConfig.class).to(MultiTenantNotificationConfig.class).asEagerSingleton();
bind(PushNotificationListener.class).asEagerSingleton();
bind(PushNotificationRetryService.class).asEagerSingleton();
bind(ServerService.class).to(DefaultServerService.class).asEagerSingleton();
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationKey.java b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationKey.java
index f77799e..e72dec3 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationKey.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationKey.java
@@ -31,7 +31,7 @@ public class PushNotificationKey implements NotificationEvent {
private final String eventType;
private final String objectType;
private final UUID objectId;
- private Integer attemptNumber;
+ private final int attemptNumber;
private final String url;
@JsonCreator
@@ -40,7 +40,7 @@ public class PushNotificationKey implements NotificationEvent {
@JsonProperty("eventType") final String eventType,
@JsonProperty("objectType") final String objectType,
@JsonProperty("objectId") final UUID objectId,
- @JsonProperty("attemptNumber") final Integer attemptNumber,
+ @JsonProperty("attemptNumber") final int attemptNumber,
@JsonProperty("url") final String url) {
this.tenantId = tenantId;
this.accountId = accountId;
@@ -51,8 +51,9 @@ public class PushNotificationKey implements NotificationEvent {
this.url = url;
}
- public void increaseAttemptNumber() {
- this.attemptNumber = ++attemptNumber;
+ public PushNotificationKey(final PushNotificationKey key, final int attemptNumber) {
+ this(key.getTenantId(), key.getAccountId(), key.getEventType(), key.getObjectType(), key.getObjectId(),
+ attemptNumber, key.getUrl());
}
public UUID getTenantId() {
@@ -76,7 +77,7 @@ public class PushNotificationKey implements NotificationEvent {
}
public Integer getAttemptNumber() {
- return attemptNumber == null ? 0 : attemptNumber;
+ return attemptNumber;
}
public String getUrl() {
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
index b6e968c..afa18cf 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationListener.java
@@ -28,7 +28,6 @@ import javax.inject.Inject;
import org.joda.time.DateTime;
import org.killbill.billing.ObjectType;
-import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.callcontext.InternalTenantContext;
import org.killbill.billing.jaxrs.json.NotificationJson;
import org.killbill.billing.notification.plugin.api.ExtBusEvent;
@@ -118,11 +117,12 @@ public class PushNotificationListener {
final NotificationJson notification = new NotificationJson(event);
final String body = mapper.writeValueAsString(notification);
for (final String cur : callbacks) {
- doPost(tenantId, cur, body, TIMEOUT_NOTIFICATION);
+ doPost(tenantId, cur, body, notification, TIMEOUT_NOTIFICATION, 0);
}
}
- private boolean doPost(final UUID tenantId, final String url, final String body, final int timeoutSec) {
+ private boolean doPost(final UUID tenantId, final String url, final String body, final NotificationJson notification,
+ final int timeoutSec, final int attemptRetryNumber) {
final BoundRequestBuilder builder = httpClient.preparePost(url);
builder.setBody(body == null ? "{}" : body);
builder.addHeader(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_JSON);
@@ -138,81 +138,48 @@ public class PushNotificationListener {
});
response = futureStatus.get(timeoutSec, TimeUnit.SECONDS);
} catch (final TimeoutException toe) {
- saveRetryPushNotificationInQueue(tenantId, url, body);
+ saveRetryPushNotificationInQueue(tenantId, url, notification, attemptRetryNumber);
return false;
} catch (final Exception e) {
log.warn("Failed to push notification url='{}', tenantId='{}'", url, tenantId, e);
return false;
}
- if ((response.getStatusCode() == 301) || (response.getStatusCode() == 500)) {
- saveRetryPushNotificationInQueue(tenantId, url, body);
+ if (response.getStatusCode() >= 200 && response.getStatusCode() < 300) {
+ return true;
+ } else {
+ saveRetryPushNotificationInQueue(tenantId, url, notification, attemptRetryNumber);
return false;
}
-
- return response.getStatusCode() >= 200 && response.getStatusCode() < 300;
}
- public void resendPushNotification(final PushNotificationKey key, final InternalCallContext callContext) throws JsonProcessingException {
+ public void resendPushNotification(final PushNotificationKey key) throws JsonProcessingException {
final NotificationJson notification = new NotificationJson(key.getEventType() != null ? key.getEventType().toString() : null,
key.getAccountId() != null ? key.getAccountId().toString() : null,
key.getObjectType() != null ? key.getObjectType().toString() : null,
key.getObjectId() != null ? key.getObjectId().toString() : null);
final String body = mapper.writeValueAsString(notification);
-
- final BoundRequestBuilder builder = httpClient.preparePost(key.getUrl());
- builder.setBody(body == null ? "{}" : body);
- builder.addHeader(HTTP_HEADER_CONTENT_TYPE, CONTENT_TYPE_JSON);
-
- final Response response;
- try {
- final ListenableFuture<Response> futureStatus =
- builder.execute(new AsyncCompletionHandler<Response>() {
- @Override
- public Response onCompleted(final Response response) throws Exception {
- return response;
- }
- });
- response = futureStatus.get(TIMEOUT_NOTIFICATION, TimeUnit.SECONDS);
- } catch (final TimeoutException toe) {
- saveRetryPushNotificationInQueue(key);
- return;
- } catch (final Exception e) {
- log.warn("Failed to push notification url='{}', tenantId='{}'", key.getUrl(), key.getTenantId(), e);
- return;
- }
-
- if ((response.getStatusCode() == 301) || (response.getStatusCode() == 500)) {
- saveRetryPushNotificationInQueue(key);
- }
+ doPost(key.getTenantId(), key.getUrl(), body, notification, TIMEOUT_NOTIFICATION, key.getAttemptNumber());
}
- private void saveRetryPushNotificationInQueue(final UUID tenantId, final String url, final String body) {
- try {
- final NotificationJson notificationJson = mapper.readValue(body, NotificationJson.class);
- final PushNotificationKey key = new PushNotificationKey(tenantId,
- notificationJson.getAccountId() != null ? UUID.fromString(notificationJson.getAccountId()) : null,
- notificationJson.getEventType(),
- notificationJson.getObjectType(),
- notificationJson.getObjectId() != null ? UUID.fromString(notificationJson.getObjectId()) : null,
- 0, url);
- saveRetryPushNotificationInQueue(key);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
+ private void saveRetryPushNotificationInQueue(final UUID tenantId, final String url, final NotificationJson notificationJson, final int attemptRetryNumber) {
+ final PushNotificationKey key = new PushNotificationKey(tenantId,
+ notificationJson.getAccountId() != null ? UUID.fromString(notificationJson.getAccountId()) : null,
+ notificationJson.getEventType(),
+ notificationJson.getObjectType(),
+ notificationJson.getObjectId() != null ? UUID.fromString(notificationJson.getObjectId()) : null,
+ attemptRetryNumber + 1, url);
- private void saveRetryPushNotificationInQueue(final PushNotificationKey key) {
- final TenantContext tenantContext = contextFactory.createTenantContext(key.getTenantId());
- key.increaseAttemptNumber();
+ final TenantContext tenantContext = contextFactory.createTenantContext(tenantId);
final DateTime nextNotificationTime = getNextNotificationTime(key.getAttemptNumber(), internalCallContextFactory.createInternalTenantContextWithoutAccountRecordId(tenantContext));
if (nextNotificationTime == null) {
log.warn("Max attempt number reached for push notification url='{}', tenantId='{}'", key.getUrl(), key.getTenantId());
return;
}
- log.debug("Push notification is schedule to send at {} for url='{}', tenantId='{}'", nextNotificationTime, key.getUrl(), key.getTenantId());
+ log.debug("Push notification is scheduled to send at {} for url='{}', tenantId='{}'", nextNotificationTime, key.getUrl(), key.getTenantId());
+
final Long accountRecordId = internalCallContextFactory.getRecordIdFromObject(key.getAccountId(), ObjectType.ACCOUNT, tenantContext);
final Long tenantRecordId = internalCallContextFactory.getRecordIdFromObject(key.getTenantId(), ObjectType.TENANT, tenantContext);
try {
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationRetryService.java b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationRetryService.java
index 94e805d..5284a21 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationRetryService.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/notifications/PushNotificationRetryService.java
@@ -20,11 +20,8 @@ package org.killbill.billing.server.notifications;
import java.util.UUID;
import org.joda.time.DateTime;
-import org.killbill.billing.callcontext.InternalCallContext;
import org.killbill.billing.server.DefaultServerService;
-import org.killbill.billing.util.callcontext.CallOrigin;
import org.killbill.billing.util.callcontext.InternalCallContextFactory;
-import org.killbill.billing.util.callcontext.UserType;
import org.killbill.notificationq.api.NotificationEvent;
import org.killbill.notificationq.api.NotificationQueue;
import org.killbill.notificationq.api.NotificationQueueService;
@@ -69,9 +66,8 @@ public class PushNotificationRetryService {
return;
}
final PushNotificationKey key = (PushNotificationKey) notificationKey;
- final InternalCallContext callContext = internalCallContextFactory.createInternalCallContext(tenantRecordId, accountRecordId, retryService, CallOrigin.INTERNAL, UserType.SYSTEM, userToken);
try {
- pushNotificationListener.resendPushNotification(key, callContext);
+ pushNotificationListener.resendPushNotification(key);
} catch (JsonProcessingException e) {
log.error("Failed to push notification url='{}', tenantId='{}'", key.getUrl(), key.getTenantId(), e);
}