killbill-aplcache

meter: switch APIs to store samples for a generic source name Don't

12/5/2012 12:43:57 AM

Details

diff --git a/api/src/main/java/com/ning/billing/meter/api/MeterUserApi.java b/api/src/main/java/com/ning/billing/meter/api/MeterUserApi.java
index b3aee1f..597cf74 100644
--- a/api/src/main/java/com/ning/billing/meter/api/MeterUserApi.java
+++ b/api/src/main/java/com/ning/billing/meter/api/MeterUserApi.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Collection;
 import java.util.Map;
-import java.util.UUID;
 
 import org.joda.time.DateTime;
 
@@ -29,21 +28,21 @@ import com.ning.billing.util.callcontext.TenantContext;
 
 public interface MeterUserApi {
 
-    public void getAggregateUsage(OutputStream outputStream, UUID bundleId, Collection<String> categories,
+    public void getAggregateUsage(OutputStream outputStream, String source, Collection<String> categories,
                                   DateTime fromTimestamp, DateTime toTimestamp, TenantContext context) throws IOException;
 
-    public void getUsage(OutputStream outputStream, UUID bundleId, Map<String, Collection<String>> metricsPerCategory,
+    public void getUsage(OutputStream outputStream, String source, Map<String, Collection<String>> metricsPerCategory,
                          DateTime fromTimestamp, DateTime toTimestamp, TenantContext context) throws IOException;
 
     /**
      * Shortcut API to record a usage value of "1" for a given category and metric.
      *
-     * @param bundleId     bundle id source
+     * @param source       source name for this usage
      * @param categoryName category name for this usage
      * @param metricName   metric name associated with this category
      * @param context      call context
      */
-    public void incrementUsage(UUID bundleId, String categoryName, String metricName, DateTime timestamp, CallContext context);
+    public void incrementUsage(String source, String categoryName, String metricName, DateTime timestamp, CallContext context);
 
     /**
      * Shortcut API to record a usage value of "1" for a given category and metric.
@@ -52,20 +51,20 @@ public interface MeterUserApi {
      * This is useful if one wants to store fine grained usage information (e.g. number of minutes used per cell phone number),
      * while keeping a fast access path to the aggregate (e.g. number of minutes used across all cell phone numbers).
      *
-     * @param bundleId     bundle id source
+     * @param source       source name for this usage
      * @param categoryName category name for this usage
      * @param metricName   metric name associated with this category
      * @param context      call context
      */
-    public void incrementUsageAndAggregate(UUID bundleId, String categoryName, String metricName, DateTime timestamp, CallContext context);
+    public void incrementUsageAndAggregate(String source, String categoryName, String metricName, DateTime timestamp, CallContext context);
 
     /**
      * Fine grained usage API. This is used to record e.g. "X has used 2 credits at 2012/02/04 4:12pm".
      *
-     * @param bundleId                       bundle id source
+     * @param source                         source name for this usage
      * @param samplesForCategoriesAndMetrics samples per metric and category
      * @param timestamp                      timestamp of this usage
      * @param context                        tenant context
      */
-    public void recordUsage(UUID bundleId, Map<String, Map<String, Object>> samplesForCategoriesAndMetrics, DateTime timestamp, CallContext context);
+    public void recordUsage(String source, Map<String, Map<String, Object>> samplesForCategoriesAndMetrics, DateTime timestamp, CallContext context);
 }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
index d2973cb..82d6d7d 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/JaxrsResource.java
@@ -37,7 +37,7 @@ public interface JaxrsResource {
     /*
      * Patterns
      */
-    public static String STRING_PATTERN = "\\w+";
+    public static String STRING_PATTERN = "[\\w-]+";
     public static String UUID_PATTERN = "\\w+-\\w+-\\w+-\\w+-\\w+";
 
     /*
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/MeterResource.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/MeterResource.java
index 9b81ac9..634d63f 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/MeterResource.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/resources/MeterResource.java
@@ -23,7 +23,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.ws.rs.Consumes;
@@ -51,7 +50,6 @@ import com.ning.billing.util.callcontext.CallContext;
 import com.ning.billing.util.callcontext.TenantContext;
 import com.ning.billing.util.clock.Clock;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
@@ -61,8 +59,6 @@ import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
 @Path(JaxrsResource.METER_PATH)
 public class MeterResource extends JaxRsResourceBase {
 
-    private static final ObjectMapper objectMapper = new ObjectMapper();
-
     private final MeterUserApi meterApi;
     private final Clock clock;
 
@@ -80,9 +76,9 @@ public class MeterResource extends JaxRsResourceBase {
     }
 
     @GET
-    @Path("/{bundleId:" + UUID_PATTERN + "}")
+    @Path("/{source:" + STRING_PATTERN + "}")
     @Produces(APPLICATION_JSON)
-    public StreamingOutput getUsage(@PathParam("bundleId") final String bundleIdString,
+    public StreamingOutput getUsage(@PathParam("source") final String source,
                                     @QueryParam(QUERY_METER_CATEGORY) final List<String> categories,
                                     // Format: category,metric
                                     @QueryParam(QUERY_METER_CATEGORY_AND_METRIC) final List<String> categoriesAndMetrics,
@@ -90,7 +86,6 @@ public class MeterResource extends JaxRsResourceBase {
                                     @QueryParam(QUERY_METER_TO) final String toTimestampString,
                                     @QueryParam(QUERY_METER_WITH_AGGREGATE) @DefaultValue("false") final Boolean withAggregate,
                                     @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID bundleId = UUID.fromString(bundleIdString);
         final DateTime fromTimestamp = DATE_TIME_FORMATTER.parseDateTime(fromTimestampString);
         final DateTime toTimestamp = DATE_TIME_FORMATTER.parseDateTime(toTimestampString);
         final TenantContext tenantContext = context.createContext(request);
@@ -99,10 +94,10 @@ public class MeterResource extends JaxRsResourceBase {
             @Override
             public void write(final OutputStream output) throws IOException, WebApplicationException {
                 if (withAggregate) {
-                    meterApi.getAggregateUsage(output, bundleId, categories, fromTimestamp, toTimestamp, tenantContext);
+                    meterApi.getAggregateUsage(output, source, categories, fromTimestamp, toTimestamp, tenantContext);
                 } else {
                     final Map<String, Collection<String>> metricsPerCategory = retrieveMetricsPerCategory(categoriesAndMetrics);
-                    meterApi.getUsage(output, bundleId, metricsPerCategory, fromTimestamp, toTimestamp, tenantContext);
+                    meterApi.getUsage(output, source, metricsPerCategory, fromTimestamp, toTimestamp, tenantContext);
                 }
             }
         };
@@ -131,10 +126,10 @@ public class MeterResource extends JaxRsResourceBase {
     }
 
     @POST
-    @Path("/{bundleId:" + UUID_PATTERN + "}/{categoryName:" + STRING_PATTERN + "}/{metricName:" + STRING_PATTERN + "}")
+    @Path("/{source:" + STRING_PATTERN + "}/{categoryName:" + STRING_PATTERN + "}/{metricName:" + STRING_PATTERN + "}")
     @Consumes(APPLICATION_JSON)
     @Produces(APPLICATION_JSON)
-    public Response recordUsage(@PathParam("bundleId") final String bundleIdString,
+    public Response recordUsage(@PathParam("source") final String source,
                                 @PathParam("categoryName") final String categoryName,
                                 @PathParam("metricName") final String metricName,
                                 @QueryParam(QUERY_METER_WITH_AGGREGATE) @DefaultValue("false") final Boolean withAggregate,
@@ -143,7 +138,6 @@ public class MeterResource extends JaxRsResourceBase {
                                 @HeaderParam(HDR_REASON) final String reason,
                                 @HeaderParam(HDR_COMMENT) final String comment,
                                 @javax.ws.rs.core.Context final HttpServletRequest request) {
-        final UUID bundleId = UUID.fromString(bundleIdString);
         final CallContext callContext = context.createContext(createdBy, reason, comment, request);
 
         final DateTime timestamp;
@@ -154,9 +148,9 @@ public class MeterResource extends JaxRsResourceBase {
         }
 
         if (withAggregate) {
-            meterApi.incrementUsageAndAggregate(bundleId, categoryName, metricName, timestamp, callContext);
+            meterApi.incrementUsageAndAggregate(source, categoryName, metricName, timestamp, callContext);
         } else {
-            meterApi.incrementUsage(bundleId, categoryName, metricName, timestamp, callContext);
+            meterApi.incrementUsage(source, categoryName, metricName, timestamp, callContext);
         }
 
         return Response.ok().build();
diff --git a/meter/src/main/java/com/ning/billing/meter/api/user/DefaultMeterUserApi.java b/meter/src/main/java/com/ning/billing/meter/api/user/DefaultMeterUserApi.java
index 8ea781b..92023cc 100644
--- a/meter/src/main/java/com/ning/billing/meter/api/user/DefaultMeterUserApi.java
+++ b/meter/src/main/java/com/ning/billing/meter/api/user/DefaultMeterUserApi.java
@@ -20,13 +20,11 @@ import java.io.IOException;
 import java.io.OutputStream;
 import java.util.Collection;
 import java.util.Map;
-import java.util.UUID;
 
 import javax.inject.Inject;
 
 import org.joda.time.DateTime;
 
-import com.ning.billing.ObjectType;
 import com.ning.billing.meter.api.MeterUserApi;
 import com.ning.billing.meter.timeline.TimelineEventHandler;
 import com.ning.billing.meter.timeline.persistent.TimelineDao;
@@ -58,50 +56,48 @@ public class DefaultMeterUserApi implements MeterUserApi {
     }
 
     @Override
-    public void getAggregateUsage(final OutputStream outputStream, final UUID bundleId, final Collection<String> categories,
+    public void getAggregateUsage(final OutputStream outputStream, final String source, final Collection<String> categories,
                                   final DateTime fromTimestamp, final DateTime toTimestamp, final TenantContext context) throws IOException {
         final ImmutableMap.Builder<String, Collection<String>> metricsPerCategory = new Builder<String, Collection<String>>();
         for (final String category : categories) {
             metricsPerCategory.put(category, ImmutableList.<String>of(AGGREGATE_METRIC_NAME));
         }
-        getUsage(outputStream, bundleId, metricsPerCategory.build(), fromTimestamp, toTimestamp, context);
+        getUsage(outputStream, source, metricsPerCategory.build(), fromTimestamp, toTimestamp, context);
     }
 
     @Override
-    public void getUsage(final OutputStream outputStream, final UUID bundleId, final Map<String, Collection<String>> metricsPerCategory,
+    public void getUsage(final OutputStream outputStream, final String source, final Map<String, Collection<String>> metricsPerCategory,
                          final DateTime fromTimestamp, final DateTime toTimestamp, final TenantContext context) throws IOException {
         final InternalTenantContext internalTenantContext = internalCallContextFactory.createInternalTenantContext(context);
 
         final JsonSamplesOutputer outputerJson = new JsonSamplesOutputer(timelineEventHandler, timelineDao, internalTenantContext);
-        outputerJson.output(outputStream, ImmutableList.<UUID>of(bundleId), metricsPerCategory, fromTimestamp, toTimestamp);
+        outputerJson.output(outputStream, ImmutableList.<String>of(source), metricsPerCategory, fromTimestamp, toTimestamp);
     }
 
     @Override
-    public void incrementUsage(final UUID bundleId, final String categoryName, final String metricName,
+    public void incrementUsage(final String source, final String categoryName, final String metricName,
                                final DateTime timestamp, final CallContext context) {
-        recordUsage(bundleId,
+        recordUsage(source,
                     ImmutableMap.<String, Map<String, Object>>of(categoryName, ImmutableMap.<String, Object>of(metricName, (short) 1)),
                     timestamp,
                     context);
     }
 
     @Override
-    public void incrementUsageAndAggregate(final UUID bundleId, final String categoryName, final String metricName,
+    public void incrementUsageAndAggregate(final String source, final String categoryName, final String metricName,
                                            final DateTime timestamp, final CallContext context) {
-        recordUsage(bundleId,
+        recordUsage(source,
                     ImmutableMap.<String, Map<String, Object>>of(categoryName, ImmutableMap.<String, Object>of(metricName, (short) 1, AGGREGATE_METRIC_NAME, (short) 1)),
                     timestamp,
                     context);
     }
 
     @Override
-    public void recordUsage(final UUID bundleId, final Map<String, Map<String, Object>> samplesForCategoriesAndMetrics,
+    public void recordUsage(final String source, final Map<String, Map<String, Object>> samplesForCategoriesAndMetrics,
                             final DateTime timestamp, final CallContext context) {
-        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(bundleId, ObjectType.BUNDLE, context);
-
+        final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(context);
         for (final String category : samplesForCategoriesAndMetrics.keySet()) {
-            final String sourceName = bundleId.toString();
-            timelineEventHandler.record(sourceName, category, timestamp, samplesForCategoriesAndMetrics.get(category),
+            timelineEventHandler.record(source, category, timestamp, samplesForCategoriesAndMetrics.get(category),
                                         internalCallContext);
         }
     }
diff --git a/meter/src/main/java/com/ning/billing/meter/api/user/JsonSamplesOutputer.java b/meter/src/main/java/com/ning/billing/meter/api/user/JsonSamplesOutputer.java
index 1e6ca23..5309ed7 100644
--- a/meter/src/main/java/com/ning/billing/meter/api/user/JsonSamplesOutputer.java
+++ b/meter/src/main/java/com/ning/billing/meter/api/user/JsonSamplesOutputer.java
@@ -23,7 +23,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -69,17 +68,17 @@ public class JsonSamplesOutputer {
         this.context = context;
     }
 
-    public void output(final OutputStream output, final List<UUID> bundleIds, final Map<String, Collection<String>> metricsPerCategory,
+    public void output(final OutputStream output, final List<String> sources, final Map<String, Collection<String>> metricsPerCategory,
                        final DateTime startTime, final DateTime endTime) throws IOException {
         // Default - output all data points as CSV
-        output(output, bundleIds, metricsPerCategory, DecimationMode.PEAK_PICK, null, false, false, startTime, endTime);
+        output(output, sources, metricsPerCategory, DecimationMode.PEAK_PICK, null, false, false, startTime, endTime);
     }
 
-    public void output(final OutputStream output, final List<UUID> bundleIds, final Map<String, Collection<String>> metricsPerCategory,
+    public void output(final OutputStream output, final List<String> sources, final Map<String, Collection<String>> metricsPerCategory,
                        final DecimationMode decimationMode, @Nullable final Integer outputCount, final boolean decodeSamples, final boolean compact,
                        final DateTime startTime, final DateTime endTime) throws IOException {
         // Retrieve the source and metric ids
-        final List<Integer> sourceIds = translateBundleIdsToSourceIds(bundleIds);
+        final List<Integer> sourceIds = translateSourcesToSourceIds(sources);
         final List<Integer> metricIds = translateCategoriesAndMetricNamesToMetricIds(metricsPerCategory);
 
         // Create the decimating filters, if needed
@@ -108,10 +107,10 @@ public class JsonSamplesOutputer {
         generator.close();
     }
 
-    private List<Integer> translateBundleIdsToSourceIds(final List<UUID> bundleIds) {
-        final List<Integer> hostIds = new ArrayList<Integer>(bundleIds.size());
-        for (final UUID bundleId : bundleIds) {
-            hostIds.add(timelineDao.getSourceId(bundleId.toString(), context));
+    private List<Integer> translateSourcesToSourceIds(final List<String> sources) {
+        final List<Integer> hostIds = new ArrayList<Integer>(sources.size());
+        for (final String source : sources) {
+            hostIds.add(timelineDao.getSourceId(source, context));
         }
 
         return hostIds;
diff --git a/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVConsumer.java b/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVConsumer.java
index d06e56c..c62f717 100644
--- a/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVConsumer.java
+++ b/meter/src/main/java/com/ning/billing/meter/timeline/consumer/CSVConsumer.java
@@ -24,17 +24,10 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.meter.timeline.chunks.TimelineChunk;
 import com.ning.billing.meter.timeline.codec.SampleCoder;
-import com.ning.billing.meter.timeline.consumer.filter.DecimatingSampleFilter;
 
 public class CSVConsumer {
 
-    private CSVConsumer() {
-    }
-
-    public static String getSamplesAsCSV(final SampleCoder sampleCoder, final TimelineChunk chunk, final DecimatingSampleFilter rangeSampleProcessor) throws IOException {
-        sampleCoder.scan(chunk, rangeSampleProcessor);
-        return rangeSampleProcessor.toString();
-    }
+    private CSVConsumer() {}
 
     public static String getSamplesAsCSV(final SampleCoder sampleCoder, final TimelineChunk chunk) throws IOException {
         return getSamplesAsCSV(sampleCoder, chunk, null, null);
@@ -42,7 +35,11 @@ public class CSVConsumer {
 
     public static String getSamplesAsCSV(final SampleCoder sampleCoder, final TimelineChunk chunk, @Nullable final DateTime startTime, @Nullable final DateTime endTime) throws IOException {
         final CSVSampleProcessor processor = new CSVSampleProcessor(startTime, endTime);
-        sampleCoder.scan(chunk, processor);
-        return processor.toString();
+        return getSamplesAsCSV(sampleCoder, chunk, processor);
+    }
+
+    public static String getSamplesAsCSV(final SampleCoder sampleCoder, final TimelineChunk chunk, final TimeRangeSampleProcessor rangeSampleProcessor) throws IOException {
+        sampleCoder.scan(chunk, rangeSampleProcessor);
+        return rangeSampleProcessor.toString();
     }
 }
diff --git a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
index 1780d91..eb09494 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/KillbillClient.java
@@ -809,15 +809,15 @@ public abstract class KillbillClient extends ServerTestSuiteWithEmbeddedDB {
     // METERING
     //
 
-    protected void recordMeteringUsage(final UUID bundleId, final String category, final String metric, final DateTime timestamp) throws IOException {
-        final String meterURI = JaxrsResource.METER_PATH + "/" + bundleId.toString() + "/" + category + "/" + metric;
+    protected void recordMeteringUsage(final String source, final String category, final String metric, final DateTime timestamp) throws IOException {
+        final String meterURI = JaxrsResource.METER_PATH + "/" + source + "/" + category + "/" + metric;
         final Response meterResponse = doPost(meterURI, null, ImmutableMap.<String, String>of(JaxrsResource.QUERY_METER_WITH_AGGREGATE, "true",
                                                                                               JaxrsResource.QUERY_METER_TIMESTAMP, timestamp.toString()), DEFAULT_HTTP_TIMEOUT_SEC);
         assertEquals(meterResponse.getStatusCode(), Status.OK.getStatusCode());
     }
 
-    protected List<Map<String, Object>> getMeteringAggregateUsage(final UUID bundleId, final String category, final DateTime from, final DateTime to) throws IOException {
-        final String meterURI = JaxrsResource.METER_PATH + "/" + bundleId.toString();
+    protected List<Map<String, Object>> getMeteringAggregateUsage(final String source, final String category, final DateTime from, final DateTime to) throws IOException {
+        final String meterURI = JaxrsResource.METER_PATH + "/" + source;
         final Response meterResponse = doGet(meterURI, ImmutableMap.<String, String>of(JaxrsResource.QUERY_METER_CATEGORY, category,
                                                                                        JaxrsResource.QUERY_METER_FROM, from.toString(),
                                                                                        JaxrsResource.QUERY_METER_TO, to.toString(),
diff --git a/server/src/test/java/com/ning/billing/jaxrs/TestMeter.java b/server/src/test/java/com/ning/billing/jaxrs/TestMeter.java
index 05e2759..0f88e9b 100644
--- a/server/src/test/java/com/ning/billing/jaxrs/TestMeter.java
+++ b/server/src/test/java/com/ning/billing/jaxrs/TestMeter.java
@@ -20,7 +20,6 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.Random;
 import java.util.UUID;
 
 import org.joda.time.DateTime;
@@ -34,7 +33,7 @@ import com.google.common.collect.Ordering;
 
 public class TestMeter extends TestJaxrsBase {
 
-    private final UUID bundleId = UUID.randomUUID();
+    private final String source = UUID.randomUUID().toString();
     private final String category = "PageView";
     private final String visitor1 = "pierre";
     private final String visitor2 = "stephane";
@@ -56,10 +55,10 @@ public class TestMeter extends TestJaxrsBase {
         final DateTime end = dateTimeOrdering.max(visits);
 
         // Verify the visits recorded
-        final List<Map<String, Object>> meteringAggregateUsage = getMeteringAggregateUsage(bundleId, category, start, end);
+        final List<Map<String, Object>> meteringAggregateUsage = getMeteringAggregateUsage(source, category, start, end);
         final List<DateTime> visitsFound = new ArrayList<DateTime>();
         for (final Map<String, Object> oneUsage : meteringAggregateUsage) {
-            Assert.assertEquals(oneUsage.get("sourceName"), bundleId.toString());
+            Assert.assertEquals(oneUsage.get("sourceName"), source);
             Assert.assertEquals(oneUsage.get("eventCategory"), category);
             Assert.assertEquals(oneUsage.get("metric"), "__AGGREGATE__");
 
@@ -79,11 +78,11 @@ public class TestMeter extends TestJaxrsBase {
         final List<DateTime> visits = new ArrayList<DateTime>();
         for (int i = 0; i < nbVisits; i++) {
             DateTime visitDate = lastVisit.plusSeconds(i);
-            recordMeteringUsage(bundleId, category, visitor1, visitDate);
+            recordMeteringUsage(source, category, visitor1, visitDate);
             visits.add(visitDate);
 
             visitDate = visitDate.plusSeconds(1);
-            recordMeteringUsage(bundleId, category, visitor2, visitDate);
+            recordMeteringUsage(source, category, visitor2, visitDate);
             visits.add(visitDate);
 
             lastVisit = visitDate;