use of org.joda.time.DateTimeZone in project killbill by killbill.
the class TestWithTimeZones method testWithDayLightSaving.
// Verify that recurring invoice items are correctly computed although we went through and out of daylight saving transitions
@Test(groups = "slow")
public void testWithDayLightSaving() throws Exception {
// Start with a date in daylight saving period and make sure we use a time of 8 hour so that we we reach standard time
// the next month where the difference is 9 hours, a transformation from DateTime to LocalDate with the account time zone would bring us a day earlier
clock.setTime(new DateTime("2015-09-01T08:01:01.000Z"));
final DateTimeZone tz = DateTimeZone.forID("America/Juneau");
final AccountData accountData = new MockAccountBuilder().name(UUID.randomUUID().toString().substring(1, 8)).firstNameLength(6).email(UUID.randomUUID().toString().substring(1, 8)).phone(UUID.randomUUID().toString().substring(1, 8)).migrated(false).isNotifiedForInvoices(false).externalKey(UUID.randomUUID().toString().substring(1, 8)).billingCycleDayLocal(1).currency(Currency.USD).paymentMethodId(UUID.randomUUID()).timeZone(tz).build();
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
final List<ExpectedInvoiceItemCheck> expectedInvoices = new ArrayList<ExpectedInvoiceItemCheck>();
final TestDryRunArguments dryRun = new TestDryRunArguments(DryRunType.SUBSCRIPTION_ACTION, "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, null, null, SubscriptionEventType.START_BILLING, null, null, null, null);
final Invoice dryRunInvoice = invoiceUserApi.triggerInvoiceGeneration(account.getId(), clock.getUTCToday(), dryRun, callContext);
expectedInvoices.add(new ExpectedInvoiceItemCheck(new LocalDate(2015, 9, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
invoiceChecker.checkInvoiceNoAudits(dryRunInvoice, callContext, expectedInvoices);
final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.MONTHLY, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// Check bundle after BP got created otherwise we get an error from auditApi.
subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext, expectedInvoices);
expectedInvoices.clear();
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2015, 10, 1), new LocalDate(2015, 11, 1), InvoiceItemType.RECURRING, new BigDecimal("249.95")));
LocalDate startDate = new LocalDate(2015, 11, 1);
// We loop 18 times to go over a year and transitions several times between winter and summer (daylight saving)
for (int i = 0; i < 18; i++) {
final LocalDate endDate = startDate.plusMonths(1);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), i + 3, callContext, new ExpectedInvoiceItemCheck(startDate, endDate, InvoiceItemType.RECURRING, new BigDecimal("249.95")));
startDate = endDate;
}
}
use of org.joda.time.DateTimeZone in project killbill by killbill.
the class TestWithTimeZones method testReferenceTimeInDSTGap.
@Test(groups = "slow")
public void testReferenceTimeInDSTGap() throws Exception {
final DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");
clock.setTime(new DateTime(2015, 3, 7, 2, 0, 0, tz));
final AccountData accountData = new MockAccountBuilder().currency(Currency.USD).timeZone(tz).build();
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
Assert.assertEquals(account.getTimeZone(), tz);
Assert.assertEquals(account.getFixedOffsetTimeZone(), DateTimeZone.forOffsetHours(-8));
// Note the gap: 2015-03-07T02:00:00.000-08:00 to 2015-03-08T03:00:00.000-07:00
clock.addDays(1);
try {
// See TimeAwareContext#toUTCDateTime (which uses account.getFixedOffsetTimeZone() instead)
new DateTime(clock.getUTCToday().getYear(), clock.getUTCToday().getMonthOfYear(), clock.getUTCToday().getDayOfMonth(), account.getReferenceTime().toDateTime(tz).getHourOfDay(), account.getReferenceTime().toDateTime(tz).getMinuteOfHour(), account.getReferenceTime().toDateTime(tz).getSecondOfMinute(), account.getTimeZone());
Assert.fail();
} catch (final IllegalInstantException e) {
// Illegal instant due to time zone offset transition (daylight savings time 'gap'): 2015-03-08T10:00:00.000 (America/Los_Angeles)
}
busHandler.pushExpectedEvents(NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
final PlanPhaseSpecifier spec = new PlanPhaseSpecifier("Blowdart", BillingPeriod.MONTHLY, "notrial", null);
// Pass a date of today, to trigger TimeAwareContext#toUTCDateTime
final Entitlement entitlement = entitlementApi.createBaseEntitlement(account.getId(), spec, "Something", ImmutableList.<PlanPhasePriceOverride>of(), clock.getUTCToday(), clock.getUTCToday(), false, ImmutableList.<PluginProperty>of(), callContext);
assertListenerStatus();
Assert.assertEquals(entitlement.getEffectiveStartDate().compareTo(new LocalDate("2015-03-08")), 0);
Assert.assertEquals(((DefaultEntitlement) entitlement).getBasePlanSubscriptionBase().getStartDate().compareTo(new DateTime("2015-03-08T02:00:00.000-08:00")), 0);
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-04-08"), callContext);
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(31);
assertListenerStatus();
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-05-08"), callContext);
for (int i = 0; i < 25; i++) {
busHandler.pushExpectedEvents(NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addMonths(1);
assertListenerStatus();
invoiceChecker.checkChargedThroughDate(entitlement.getId(), new LocalDate("2015-03-08").plusMonths(3 + i), callContext);
}
}
use of org.joda.time.DateTimeZone in project killbill by killbill.
the class TestConsumableInArrear method testWithDayLightSaving.
@Test(groups = "slow")
public void testWithDayLightSaving() throws Exception {
clock.setTime(new DateTime("2015-09-01T08:01:01.000Z"));
final DateTimeZone tz = DateTimeZone.forID("America/Juneau");
final AccountData accountData = new MockAccountBuilder().name(UUID.randomUUID().toString().substring(1, 8)).firstNameLength(6).email(UUID.randomUUID().toString().substring(1, 8)).phone(UUID.randomUUID().toString().substring(1, 8)).migrated(false).isNotifiedForInvoices(false).externalKey(UUID.randomUUID().toString().substring(1, 8)).billingCycleDayLocal(1).currency(Currency.USD).paymentMethodId(UUID.randomUUID()).timeZone(tz).build();
final Account account = createAccountWithNonOsgiPaymentMethod(accountData);
accountChecker.checkAccount(account.getId(), accountData, callContext);
//
// CREATE SUBSCRIPTION AND EXPECT BOTH EVENTS: NextEvent.CREATE, NextEvent.BLOCK NextEvent.INVOICE
//
final DefaultEntitlement bpSubscription = createBaseEntitlementAndCheckForCompletion(account.getId(), "bundleKey", "Shotgun", ProductCategory.BASE, BillingPeriod.ANNUAL, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.INVOICE);
// Check bundle after BP got created otherwise we get an error from auditApi.
subscriptionChecker.checkSubscriptionCreated(bpSubscription.getId(), internalCallContext);
invoiceChecker.checkInvoice(account.getId(), 1, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2015, 9, 1), null, InvoiceItemType.FIXED, new BigDecimal("0")));
assertListenerStatus();
//
// ADD ADD_ON ON THE SAME DAY
//
final DefaultEntitlement aoSubscription = addAOEntitlementAndCheckForCompletion(bpSubscription.getBundleId(), "Bullets", ProductCategory.ADD_ON, BillingPeriod.NO_BILLING_PERIOD, NextEvent.CREATE, NextEvent.BLOCK, NextEvent.NULL_INVOICE);
assertListenerStatus();
busHandler.pushExpectedEvents(NextEvent.PHASE, NextEvent.NULL_INVOICE, NextEvent.INVOICE, NextEvent.PAYMENT, NextEvent.INVOICE_PAYMENT);
clock.addDays(30);
assertListenerStatus();
invoiceChecker.checkInvoice(account.getId(), 2, callContext, new ExpectedInvoiceItemCheck(new LocalDate(2015, 10, 1), new LocalDate(2016, 10, 1), InvoiceItemType.RECURRING, new BigDecimal("2399.95")));
// 2015-11-1
busHandler.pushExpectedEvent(NextEvent.NULL_INVOICE);
clock.addMonths(1);
assertListenerStatus();
// 2015-12-1
busHandler.pushExpectedEvent(NextEvent.NULL_INVOICE);
clock.addMonths(1);
assertListenerStatus();
// We sleep to let system creates lots of notification if an infinite loop was indeed happening
Thread.sleep(3000);
// And then we check that we only have the expected number of notifications in the history table.
final Integer countNotifications = dbi.withHandle(new HandleCallback<Integer>() {
@Override
public Integer withHandle(final Handle handle) throws Exception {
List<Map<String, Object>> res = handle.select("select count(*) as count from notifications_history;");
final Integer count = Integer.valueOf(res.get(0).get("count").toString());
return count;
}
});
Assert.assertEquals(countNotifications.intValue(), 4);
}
use of org.joda.time.DateTimeZone in project pinot by linkedin.
the class AnomalyReportGenerator method buildReport.
public void buildReport(long startTime, long endTime, List<MergedAnomalyResultDTO> anomalies, String subject, ThirdEyeAnomalyConfiguration configuration, boolean includeSentAnomaliesOnly, String emailRecipients, String fromEmail, String alertConfigName, boolean includeSummary) {
if (anomalies == null || anomalies.size() == 0) {
LOG.info("No anomalies found to send email, please check the parameters.. exiting");
} else {
Set<String> metrics = new HashSet<>();
int alertedAnomalies = 0;
int feedbackCollected = 0;
int trueAlert = 0;
int falseAlert = 0;
int nonActionable = 0;
List<AnomalyReportDTO> anomalyReportDTOList = new ArrayList<>();
List<String> anomalyIds = new ArrayList<>();
for (MergedAnomalyResultDTO anomaly : anomalies) {
metrics.add(anomaly.getMetric());
if (anomaly.getFeedback() != null) {
feedbackCollected++;
if (anomaly.getFeedback().getFeedbackType().equals(AnomalyFeedbackType.ANOMALY)) {
trueAlert++;
} else if (anomaly.getFeedback().getFeedbackType().equals(AnomalyFeedbackType.NOT_ANOMALY)) {
falseAlert++;
} else {
nonActionable++;
}
}
String feedbackVal = getFeedback(anomaly.getFeedback() == null ? "Not Resolved" : "Resolved(" + anomaly.getFeedback().getFeedbackType().name() + ")");
DateTimeZone dateTimeZone = Utils.getDataTimeZone(anomaly.getCollection());
AnomalyReportDTO anomalyReportDTO = new AnomalyReportDTO(String.valueOf(anomaly.getId()), getAnomalyURL(anomaly, configuration.getDashboardHost()), String.format("%.2f", anomaly.getAvgBaselineVal()), String.format("%.2f", anomaly.getAvgCurrentVal()), getDimensionsString(anomaly.getDimensions()), String.format("%.2f hours (%s to %s) %s", getTimeDiffInHours(anomaly.getStartTime(), anomaly.getEndTime()), getDateString(anomaly.getStartTime(), dateTimeZone), getDateString(anomaly.getEndTime(), dateTimeZone), // duration
getTimezoneString(dateTimeZone)), feedbackVal, anomaly.getFunction().getFunctionName(), // lift
String.format("%+.2f%%", anomaly.getWeight() * 100), getLiftDirection(anomaly.getWeight()), anomaly.getMetric());
if (anomaly.isNotified()) {
alertedAnomalies++;
}
// include notified alerts only in the email
if (includeSentAnomaliesOnly) {
if (anomaly.isNotified()) {
anomalyReportDTOList.add(anomalyReportDTO);
anomalyIds.add(anomalyReportDTO.getAnomalyId());
}
} else {
anomalyReportDTOList.add(anomalyReportDTO);
anomalyIds.add(anomalyReportDTO.getAnomalyId());
}
}
HtmlEmail email = new HtmlEmail();
DateTimeZone timeZone = DateTimeZone.forTimeZone(AlertTaskRunnerV2.DEFAULT_TIME_ZONE);
DataReportHelper.DateFormatMethod dateFormatMethod = new DataReportHelper.DateFormatMethod(timeZone);
Map<String, Object> templateData = new HashMap<>();
templateData.put("timeZone", timeZone);
templateData.put("dateFormat", dateFormatMethod);
templateData.put("startTime", startTime);
templateData.put("endTime", endTime);
templateData.put("anomalyCount", anomalies.size());
templateData.put("metricsCount", metrics.size());
templateData.put("notifiedCount", alertedAnomalies);
templateData.put("feedbackCount", feedbackCollected);
templateData.put("trueAlertCount", trueAlert);
templateData.put("falseAlertCount", falseAlert);
templateData.put("nonActionableCount", nonActionable);
templateData.put("anomalyDetails", anomalyReportDTOList);
templateData.put("alertConfigName", alertConfigName);
templateData.put("includeSummary", includeSummary);
templateData.put("reportGenerationTimeMillis", System.currentTimeMillis());
templateData.put("dashboardHost", configuration.getDashboardHost());
templateData.put("anomalyIds", Joiner.on(",").join(anomalyIds));
boolean isSingleAnomalyEmail = false;
String imgPath = null;
if (anomalyReportDTOList.size() == 1) {
isSingleAnomalyEmail = true;
AnomalyReportDTO singleAnomaly = anomalyReportDTOList.get(0);
subject = subject + " - " + singleAnomaly.getMetric();
imgPath = EmailScreenshotHelper.takeGraphScreenShot(singleAnomaly.getAnomalyId(), configuration);
String cid = "";
try {
cid = email.embed(new File(imgPath));
} catch (Exception e) {
LOG.error("Exception while embedding screenshot for anomaly {}", singleAnomaly.getAnomalyId(), e);
}
templateData.put("cid", cid);
}
buildEmailTemplateAndSendAlert(templateData, configuration.getSmtpConfiguration(), subject, emailRecipients, fromEmail, isSingleAnomalyEmail, email);
if (StringUtils.isNotBlank(imgPath)) {
try {
Files.deleteIfExists(new File(imgPath).toPath());
} catch (IOException e) {
LOG.error("Exception in deleting screenshot {}", imgPath, e);
}
}
}
}
use of org.joda.time.DateTimeZone in project pinot by linkedin.
the class DetectionJobRunner method alignTimestampsToDataTimezone.
private DateTime alignTimestampsToDataTimezone(DateTime inputDateTime, String collection) {
try {
DatasetConfigDTO datasetConfig = DAO_REGISTRY.getDatasetConfigDAO().findByDataset(collection);
TimeSpec timespec = ThirdEyeUtils.getTimeSpecFromDatasetConfig(datasetConfig);
TimeGranularity dataGranularity = timespec.getDataGranularity();
String timeFormat = timespec.getFormat();
if (dataGranularity.getUnit().equals(TimeUnit.DAYS)) {
DateTimeZone dataTimeZone = Utils.getDataTimeZone(collection);
DateTimeFormatter inputDataDateTimeFormatter = DateTimeFormat.forPattern(timeFormat).withZone(dataTimeZone);
long inputMillis = inputDateTime.getMillis();
String inputDateTimeString = inputDataDateTimeFormatter.print(inputMillis);
long timeZoneOffsetMillis = inputDataDateTimeFormatter.parseMillis(inputDateTimeString);
inputDateTime = new DateTime(timeZoneOffsetMillis);
}
} catch (Exception e) {
LOG.error("Exception in aligning timestamp to data time zone", e);
}
return inputDateTime;
}
Aggregations