Package com.streamreduce.rest

Source Code of com.streamreduce.rest.GatewayResourceITCase

/*
* 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.rest;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.mongodb.BasicDBList;
import com.mongodb.util.JSON;
import com.streamreduce.AbstractInContainerTestCase;
import com.streamreduce.ProviderIdConstants;
import com.streamreduce.connections.AuthType;
import com.streamreduce.core.model.Account;
import com.streamreduce.core.model.Connection;
import com.streamreduce.core.model.Event;
import com.streamreduce.core.model.InventoryItem;
import com.streamreduce.core.service.EventService;
import com.streamreduce.core.service.InventoryService;
import com.streamreduce.connections.CustomProvider;
import com.streamreduce.connections.GatewayProvider;
import com.streamreduce.rest.dto.response.ConnectionResponseDTO;
import com.streamreduce.rest.resource.ErrorMessage;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.bson.types.ObjectId;
import org.codehaus.jackson.map.type.TypeFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class GatewayResourceITCase extends AbstractInContainerTestCase {

    @Autowired
    private EventService eventService;
    @Autowired
    private InventoryService inventoryService;

    private Account account;
    private ConnectionResponseDTO connection;
    private String apiKey;

    @Before
    @Override
    public void setUp() throws Exception {
        super.setUp();

        String authnToken = login(testUsername, testUsername);
        JSONObject json = new JSONObject();

        json.put("providerId", ProviderIdConstants.CUSTOM_PROVIDER_ID);
        json.put("type", CustomProvider.TYPE);
        json.put("alias", "Test Generic Connection");
        json.put("authType", AuthType.API_KEY);

        try {
            // Create a new IMG connection
            connection = jsonToObject(makeRequest(connectionsBaseUrl, "POST", json, authnToken),
                                      TypeFactory.defaultInstance().constructType(ConnectionResponseDTO.class));

            // Get the IMG connection API key
            apiKey = connection.getIdentity();

            // Validate the connection was created
            Connection cConnection = applicationManager.getSecurityService().getByApiKey(apiKey, GatewayProvider.TYPE);

            assertNotNull(cConnection);

            account = cConnection.getAccount();

            // Enable inbound IMG support
            account.setConfigValue(Account.ConfigKey.DISABLE_INBOUND_API, false);
            applicationManager.getUserService().updateAccount(account);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

    @After
    @Override
    public void tearDown() throws Exception {
        if (connection != null) {
            applicationManager.getConnectionService().deleteConnection(
                    applicationManager.getConnectionService().getConnection(connection.getId()));
        }
        super.tearDown();
    }

    @Test
    @Ignore
    public void testGMGInvalidAuth() throws Exception {
        assertTrue(makeRequest(imgBaseUrl, "POST", new JSONObject(), "some_bogus_key", AuthTokenType.GATEWAY)
                           .contains("Authentication failed"));
    }

    @Test
    @Ignore
    public void testGMGInboundDisabled() throws Exception {
        // Disable inbound IMG support
        account.setConfigValue(Account.ConfigKey.DISABLE_INBOUND_API, true);
        applicationManager.getUserService().updateAccount(account);

        ErrorMessage error = jsonToObject(makeRequest(imgBaseUrl, "POST", new JSONObject(), apiKey,
                                                      AuthTokenType.GATEWAY),
                                          TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("This account is not provisioned for inbound payloads, please " +
                                                          "contact support@nodeable.com."));
    }

    @Test
    @Ignore
    public void testInvalidGMGPayloads() throws Exception {
        ErrorMessage error = jsonToObject(makeRequest(imgBaseUrl, "POST", new JSONObject(), apiKey,
                                                      AuthTokenType.GATEWAY),
                                          TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        // Invalid message because the message or metrics attributes were missing
        assertTrue(error.getErrorMessage().equals("You must supply at least a 'message' or 'metrics' attribute in " +
                                                          "the payload."));

        // Invalid message because hashtags is a non-array
        JSONObject json = new JSONObject();

        json.put("message", "This message doesn't matter.");
        json.put("hashtags", 12345);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("'hashtags' must be a string array."));

        // Invalid message because hashtags is an array with non-string values
        JSONArray jsonArray = new JSONArray();
        json = new JSONObject();

        jsonArray.add(12345);

        json.put("message", "This message doesn't matter.");
        json.put("hashtags", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("All hashtags specified in the 'hashtags' attribute must be strings."));

        // Invalid message because metrics is a non-array
        json = new JSONObject();

        json.put("message", "This message doesn't matter.");
        json.put("metrics", 12345);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("'metrics' must be an object array."));

        // Invalid message because metrics is an array with non-object values
        json = new JSONObject();
        jsonArray = new JSONArray();

        jsonArray.add(12345);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("All metrics specified in the 'metrics' attribute must be objects."));

        // Invalid message because metric in metrics doesn't contain name
        JSONObject metric = new JSONObject();
        json = new JSONObject();
        jsonArray = new JSONArray();

        jsonArray.add(metric);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("'name' is required for each metric in the 'metrics' attribute."));

        // Invalid message because metric in metrics doesn't contain type
        metric = new JSONObject();
        json = new JSONObject();
        jsonArray = new JSONArray();

        metric.put("name", "This name doesn't matter.");

        jsonArray.add(metric);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("'type' is required for each metric in the 'metrics' attribute and must be " +
                                        "either 'ABSOLUTE' or 'DELTA'."));

        // Invalid message because metric in metrics doesn't contain valid type
        metric = new JSONObject();
        json = new JSONObject();
        jsonArray = new JSONArray();

        metric.put("name", "This name doesn't matter.");
        metric.put("type", "FAKE");

        jsonArray.add(metric);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("'type' is required for each metric in the 'metrics' attribute and must be " +
                                        "either 'ABSOLUTE' or 'DELTA'."));

        // Invalid message because metric in metrics doesn't contain value
        metric = new JSONObject();
        json = new JSONObject();
        jsonArray = new JSONArray();

        metric.put("name", "This name doesn't matter.");
        metric.put("type", "ABSOLUTE");

        jsonArray.add(metric);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("'value' is required for each metric in the 'metrics' attribute and must " +
                                        "be a valid numerical value."));

        // Invalid message because metric in metrics doesn't contain valid value
        metric = new JSONObject();
        json = new JSONObject();
        jsonArray = new JSONArray();

        metric.put("name", "This name doesn't matter.");
        metric.put("type", "ABSOLUTE");
        metric.put("value", "fake");

        jsonArray.add(metric);

        json.put("message", "This message doesn't matter.");
        json.put("metrics", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage()
                        .equals("'value' for each metric in the 'metrics' attribute must be a numerical value."));

        // Invalid because it's a multi-entry request but the data attribute isn't a JSONArray
        json = new JSONObject();

        json.put("data", "This should be a JSONArray.");

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("'data' must be an object array."));

        // Invalid because it's a multi-entry request but the data entry isn't an object
        json = new JSONObject();
        jsonArray = new JSONArray();

        jsonArray.add("This should be a JSONObject.");
        json.put("data", jsonArray);

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("Every object in the 'data' array should be an object."));

        // Invalid because dateGenerated is not a number
        json = new JSONObject();

        json.put("message", "This is a test message.");
        json.put("dateGenerated", "This should be a number.");

        error = jsonToObject(makeRequest(imgBaseUrl, "POST", json, apiKey,
                                         AuthTokenType.GATEWAY),
                             TypeFactory.defaultInstance().constructType(ErrorMessage.class));

        assertTrue(error.getErrorMessage().equals("'dateGenerated' must be an number."));
    }

    @Test
    @Ignore
    public void testSuccessfulConnectionMessages() throws Exception {
        List<Event> events = getEventsForTarget(connection.getId());
        JSONObject json = new JSONObject();
        int originalEventCount = events.size();

        json.put("message", "This is a test message.");

        assertEquals("201", makeRequest(imgBaseUrl, "POST", json, apiKey, AuthTokenType.GATEWAY));

        events = getEventsForTarget(connection.getId());

        assertEquals(originalEventCount + 1, events.size());

        Event event = events.get(events.size() - 1);

        validateEvent(event, json);

        json = new JSONObject();

        json.put("message", "This is another test message.");
        json.put("hashtags", ImmutableSet.of("#testing", "#test"));
        json.put("superfluous", "This is a superfluous property.");

        JSONArray metrics = new JSONArray();

        for (int i = 0; i < 2; i++) {
            JSONObject metric = new JSONObject();

            metric.put("name", "Test Metric" + (i + 1));
            metric.put("type", "ABSOLUTE");
            metric.put("value", (i + 1));

            metrics.add(metric);
        }

        json.put("metrics", metrics);

        assertEquals("201", makeRequest(imgBaseUrl, "POST", json, apiKey, AuthTokenType.GATEWAY));

        events = getEventsForTarget(connection.getId());
        event = events.get(events.size() - 1);

        assertEquals(originalEventCount + 2, events.size());

        validateEvent(event, json);
    }

    @Test
    @Ignore
    public void testSuccessfulInventoryItemMessages() throws Exception {
        List<InventoryItem> inventoryItems = inventoryService.getInventoryItems(connection.getId());
        int connectionEventCount = getEventsForTarget(connection.getId()).size();
        JSONObject json = new JSONObject();
        List<Event> events;
        InventoryItem inventoryItem;
        int originalEventCount;

        assertEquals(0, inventoryItems.size());

        json.put("message", "Creating a new IMG inventory item.");
        json.put("inventoryItemId", "testNodeId");

        assertEquals("201", makeRequest(imgBaseUrl, "POST", json, apiKey, AuthTokenType.GATEWAY));

        inventoryItems = inventoryService.getInventoryItems(connection.getId());

        // Make sure the connection isn't receiving the event
        assertEquals(connectionEventCount, getEventsForTarget(connection.getId()).size());
        // Make sure the inventory item was created
        assertEquals(1, inventoryItems.size());

        inventoryItem = inventoryItems.get(0);
        events = getEventsForTarget(inventoryItem.getId());
        originalEventCount = events.size();

        validateEvent(events.get(events.size() - 1), json);

        json = new JSONObject();

        json.put("inventoryItemId", "testNodeId");
        json.put("hashtags", ImmutableSet.of("#testing", "#test"));
        json.put("superfluous", "This is a superfluous property.");

        JSONArray metrics = new JSONArray();

        for (int i = 0; i < 2; i++) {
            JSONObject metric = new JSONObject();

            metric.put("name", "Test Metric" + (i + 1));
            metric.put("type", "DELTA");
            metric.put("value", (i + 1));

            metrics.add(metric);
        }

        json.put("metrics", metrics);

        assertEquals("201", makeRequest(imgBaseUrl, "POST", json, apiKey, AuthTokenType.GATEWAY));

        events = getEventsForTarget(inventoryItem.getId());

        validateEvent(events.get(events.size() - 1), json);

        // Make sure the connection isn't receiving the event
        assertEquals(connectionEventCount, getEventsForTarget(connection.getId()).size());
        // Make sure the inventory item event count incremented by two (read of inventory item and new message/metrics)
        assertEquals(originalEventCount + 2, events.size());
    }

    @Test
    @Ignore
    public void testMultipleMessagesInOneRequest() throws Exception {
        int originalEventCount = getEventsForTarget(connection.getId()).size();
        JSONObject json = new JSONObject();
        JSONArray jsonArray = new JSONArray();

        for (int i = 0; i < 2; i++) {
            JSONObject message = new JSONObject();

            message.put("message", "Test message " + (i + 1) + ".");
            message.put("dateGenerated", new Date().getTime());

            jsonArray.add(message);
        }

        json.put("data", jsonArray);

        assertEquals("201", makeRequest(imgBaseUrl, "POST", json, apiKey, AuthTokenType.GATEWAY));

        List<Event> events = getEventsForTarget(connection.getId());

        assertEquals(originalEventCount + 2, events.size());
    }

    private void validateEvent(Event event, JSONObject json) {
        Map<String, Object> eventMetadata = event.getMetadata();

        // Validate the hashtags
        if (json.containsKey("hashtags")) {
            BasicDBList targetHashtags = (BasicDBList)eventMetadata.get("targetHashtags");
            JSONArray messageHashtags = json.getJSONArray("hashtags");
            Set<String> expectedHashtags = new HashSet<>();

            for (Object rawHashtag : targetHashtags) {
                expectedHashtags.add(rawHashtag.toString());
            }

            // Account for the inherited '#custom' hashtag from the target
            assertEquals(messageHashtags.size() + 1, targetHashtags.size());

            // Ensure all message hashtags are in the targetHashtags
            for (Object rawHashtag : messageHashtags) {
                assertTrue(expectedHashtags.contains(rawHashtag.toString()));
            }
        }

        // Validate the payload
        assertEquals(JSON.parse(json.toString()).toString(), eventMetadata.get("payload").toString());
    }

    /**
     * Returns all events for the given target object id.
     *
     * @param targetId the target object id
     *
     * @return the list of events
     */
    private List<Event> getEventsForTarget(final ObjectId targetId) {
        return Lists.newArrayList(Iterables.filter(eventService.getEventsForAccount(testAccount),
                                                   new Predicate<Event>() {
                                                       @Override
                                                       public boolean apply(Event event) {
                                                           return event.getTargetId().equals(targetId);
                                                       }
                                                   }));
    }

}
TOP

Related Classes of com.streamreduce.rest.GatewayResourceITCase

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.