Package com.streamreduce.storm.bolts

Source Code of com.streamreduce.storm.bolts.AbstractMetricsBoltTest

/*
* Copyright 2012 Nodeable Inc
*
*    Licensed 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.streamreduce.storm.bolts;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import backtype.storm.task.OutputCollector;
import backtype.storm.tuple.Tuple;
import backtype.storm.tuple.Values;
import com.google.common.collect.ImmutableSet;
import com.streamreduce.ProviderIdConstants;
import com.streamreduce.core.event.EventId;
import com.streamreduce.storm.MockOutputCollector;
import org.bson.types.ObjectId;
import org.mockito.Mockito;

/**
* Class all tests will extend if the bolt being tested extends {@link AbstractMetricsBolt}.
*/
public abstract class AbstractMetricsBoltTest {

    protected MockOutputCollector outputCollector;

    /**
     * Returns an instance of the bolt being tested.
     *
     * @return the bolt
     */
    public abstract AbstractMetricsBolt getBolt();

    /**
     * Takes a list of mock events, executes them using the bolt specified and returns the calculated metrics.
     *
     * @param events the events
     *
     * @return the map of calculated events
     */
    protected Map<String, Float> processEvents(List<Map<String, Object>> events) {
        Map<String, Float> metricCounts = new HashMap<>();
        AbstractMetricsBolt bolt = getBolt();

        outputCollector = new MockOutputCollector();

        // Prepare the bolt so that it uses our mock output collector
        bolt.prepare(null, null, new OutputCollector(outputCollector));

        // Emit all events
        for (Map<String, Object> event : events) {
            Tuple tuple = Mockito.mock(Tuple.class);

            Mockito.when(tuple.getValue(0)).thenReturn(event);

            bolt.execute(tuple);
        }

        // Turn all emitted metrics into the metrics map
        for (Values metric : outputCollector.getEmittedValues()) {
            String accountId = metric.get(0).toString();
            String metricId = metric.get(6).toString();
            Float metricValue = (Float)metric.get(5);
            String mapKey = accountId + "." + metricId;
            Float mapValue = metricCounts.containsKey(mapKey) ? metricCounts.get(mapKey) : 0f;

            metricCounts.put(mapKey, mapValue += metricValue);
        }

        return metricCounts;
    }

    /**
     * Helper to create a full cycle of CRUD events for a target type.
     *
     * @param targetType the target type
     *
     * @return map where each CRUD event is the key and the object for said event is the value
     */
    protected Map<EventId, Map<String, Object>> createCRUDEvents(String targetType) {
        Map<String, Object> createEvent = createBaseEventMock(EventId.CREATE, targetType, null);
        Map<String, Object> readEvent = createBaseEventMock(EventId.READ, createEvent.get("accountId").toString(),
                                                            createEvent.get("userId").toString(),
                                                            createEvent.get("targetId").toString(), targetType, null);
        Map<String, Object> updateEvent = createBaseEventMock(EventId.UPDATE, createEvent.get("accountId").toString(),
                                                              createEvent.get("userId").toString(),
                                                              createEvent.get("targetId").toString(), targetType, null);
        Map<String, Object> deleteEvent = createBaseEventMock(EventId.DELETE, createEvent.get("accountId").toString(),
                                                              createEvent.get("userId").toString(),
                                                              createEvent.get("targetId").toString(), targetType, null);

        Map<EventId, Map<String, Object>> crudEvents = new HashMap<>();

        crudEvents.put(EventId.CREATE, createEvent);
        crudEvents.put(EventId.READ, readEvent);
        crudEvents.put(EventId.UPDATE, updateEvent);
        crudEvents.put(EventId.DELETE, deleteEvent);

        return crudEvents;
    }

    /**
     * Returns a {@link com.mongodb.BasicDBObject} that has the default structure required to mirror
     * an {@link com.streamreduce.core.model.Event}.
     *
     * @param eventId the event id
     * @param targetType the event's target type
     * @param metadata the event's metadata
     *
     * @return the base event
     */
    protected Map<String, Object> createBaseEventMock(EventId eventId, String targetType,
                                                      Map<String, Object> metadata) {
        return createBaseEventMock(eventId, null, null, null, targetType, metadata);
    }

    /**
     * Returns a {@link com.mongodb.BasicDBObject} that has the default structure required to mirror
     * an {@link com.streamreduce.core.model.Event}.
     *
     * @param eventId the {@link EventId} of the event
     * @param accountId the account id of the event
     * @param userId the user id of the event
     * @param targetId the target id of the event
     * @param targetType the target type of the event
     *
     * @return the base event
     */
    protected Map<String, Object> createBaseEventMock(EventId eventId, String accountId, String userId,
                                                      String targetId, String targetType,
                                                      Map<String, Object> metadata) {
        Map<String, Object> baseEvent = new HashMap<>();

        baseEvent.put("_id", new ObjectId().toString());
        baseEvent.put("timestamp", new Date().getTime());
        baseEvent.put("eventId", eventId);
        baseEvent.put("accountId", accountId != null ? accountId : new ObjectId().toString());
        baseEvent.put("userId", userId != null ? userId : new ObjectId().toString());
        baseEvent.put("targetId", targetId != null ? targetId : new ObjectId().toString());

        if (metadata == null) {
            metadata = new HashMap<>();
        }

        if (targetType != null) {
            metadata.put("targetType", targetType);
        }

        baseEvent.put("metadata", metadata);

        return baseEvent;
    }

    /**
     * Helper to create a full cycle of CRUD events for a connection/inventory item and an ACTIVITY event.
     *
     * @param targetType the target's type
     * @param providerType the target's provider type
     * @param providerId the target's provider id
     * @param payload the target's activity payload
     *
     * @return map where each CRUD event is the key and the object for said event is the value
     */
    protected Map<EventId, Map<String, Object>> createConnectionOrInventoryItemEvents(String targetType,
                                                                                      String providerType,
                                                                                      String providerId,
                                                                                      Map<String, Object> payload) {
        Map<EventId, Map<String, Object>> allEvents = createCRUDEvents(targetType);
        Map<String, Object> metadata = new HashMap<>();

        metadata.put("targetProviderId", providerId);
        metadata.put("targetProviderType", providerType);
        metadata.put("targetHashtags", ImmutableSet.of('#' + providerId, '#' + providerType));

        if (targetType.equals("InventoryItem")) {
            metadata.put("targetConnectionId", new ObjectId().toString());

            if (providerId.equals(ProviderIdConstants.AWS_PROVIDER_ID)) {
                metadata.put("targetISO3166Code", "US-CA");
                metadata.put("targetRegion", "us-west-1");
                metadata.put("targetZone", "us-west-1a");
                metadata.put("targetOS", "AMZN_LINUX");
            }
        }

        for (Map.Entry<EventId, Map<String, Object>> crudEvent : allEvents.entrySet()) {
            Map<String, Object> eventMetadata = (Map<String, Object>)crudEvent.getValue().get("metadata");

            eventMetadata.putAll(metadata);

            // Since the hashtag handling in the AbstractMetricsBolt requires a database entry to handle things
            // properly, just remove hashtags from the update event so that an update doesn't produce any unnecessary
            // hashtag-related metrics.
            if (crudEvent.getKey() == EventId.UPDATE) {
                eventMetadata.remove("targetHashtags");
            }

            crudEvent.getValue().put("metadata", eventMetadata);
        }

        Map<String, Object> createEvent = allEvents.get(EventId.CREATE);
        Map<String, Object> activityEvent = createBaseEventMock(EventId.ACTIVITY,
                                                                createEvent.get("accountId").toString(),
                                                                createEvent.get("userId").toString(),
                                                                createEvent.get("targetId").toString(),
                                                                targetType,
                                                                (Map<String, Object>)createEvent.get("metadata"));
        Map<String, Object> activityMetadata = (Map<String, Object>)activityEvent.get("metadata");

        if (payload !=  null) {
            activityMetadata.put("payload", payload);
        }

        activityEvent.put("metadata", activityMetadata);

        allEvents.put(EventId.ACTIVITY, activityEvent);

        return allEvents;
    }

}
TOP

Related Classes of com.streamreduce.storm.bolts.AbstractMetricsBoltTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.