Package com.streamreduce.rest.resource.agent

Source Code of com.streamreduce.rest.resource.agent.AgentResource

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

import com.streamreduce.core.event.EventId;
import com.streamreduce.core.model.Event;
import com.streamreduce.core.model.InventoryItem;
import com.streamreduce.core.model.messages.MessageType;
import com.streamreduce.rest.resource.AbstractResource;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;

@Component
@Path("agent/metrics")
public class AgentResource extends AbstractResource {

    /**
     * Takes a JSON payload representing an agent metrics payload, validates it and
     * persists validated payloads.  This will also result in a stream message
     * with the agent metric information in the message stream.  (Note: The JSON
     * payload can be either a singular agent metrics payload or an array of agent
     * metrics payload objects.)
     * <br /><br />
     * The request object should be structured as described below:
     *
     * <ul class="indented">
     *     <li><b>node_id*:</b> The instance id as known by the cloud provider (Must correspond to a cloud inventory item's node id)</li>
     *     <li><b>data*:</b> The JSON object describing the agent metric payload
     *         <ul>
     *             <li><b>generated*:</b> The timestamp of when the metric was gathered/created (Format: yyyy-MM-dd'T'HH:mm:ss.SSSSSS)</li>
     *             <li>... (This data can be whatever you want really and since we do not validate this, no need in documenting it at this time.)</li>
     *         </ul>
     *     </li>
     * </ul>
     *
     * <b>* denotes a required field.</b>
     *
     * @param jsonString the raw JSON payload representing either a singular agent
     * metrics payload or an array of singular agent metrics payloads
     *
     * @return the result of the request
     *
     * @response.representation.405.doc Returned if the request was invalid in any way:
     * Invalid agent metrics payload structure, invalid cloud inventory item id in the
     * payload or whenever any deeper level exception occurs
     *
     * @response.representation.201.doc Returned if the request was successful
     */
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    public Response createAgentMetricsEntry(String jsonString) {

        if (isEmpty(jsonString)) {
            return error("Missing payload", Response.status(Response.Status.BAD_REQUEST));
        }

        try {
            JSONObject json = JSONObject.fromObject(jsonString);

            if (!json.has("node_id")) {
                return error("Request is missing the node id to associate the metrics with.",
                        Response.status(Response.Status.BAD_REQUEST));
            }

            if (!json.has("data")) {
                return error("Request is missing the 'data'.", Response.status(Response.Status.BAD_REQUEST));
            }

            try {
                json.getJSONArray("data");
            } catch (JSONException je) {
                return error("'data' should be an array.", Response.status(Response.Status.BAD_REQUEST));
            }

            String nodeId = json.getString("node_id");
            List<InventoryItem> inventoryItems =
                    applicationManager.getInventoryService().getInventoryItemsForExternalId(nodeId);

            if (inventoryItems == null || inventoryItems.isEmpty()) {
                return error("'node_id' does not correspond with an inventory item, no metrics stored.",
                        Response.status(Response.Status.BAD_REQUEST));
            }

            // we might have multiple inventoryItems with this nodeId
            // if keys are shared across the account boundary (you never know!)
            for (InventoryItem inventoryItem : inventoryItems) {
                JSONArray metrics = json.getJSONArray("data");

                for (Object rawMetric : metrics) {
                    JSONObject metric = (JSONObject)rawMetric;
                    String generated = metric.getString("generated");
                    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
                    Date dateGenerated;

                    try {
                        dateGenerated = df.parse(generated);
                    } catch (ParseException pe) {
                        logger.error("Unable to parse the generated date of the metric.", pe);
                        dateGenerated = new Date();
                    }

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

                    eventContext.put("activityGenerated", dateGenerated);
                    eventContext.put("activityPayload", metric);

                    inventoryItem.addHashtag("agent");

                    // Create the event stream entry
                    Event event = applicationManager.getEventService().createEvent(EventId.ACTIVITY,
                                                                                   inventoryItem,
                                                                                   eventContext);

                    // create the message
                    // note: all messages will have the #agent tag now.
                    applicationManager.getMessageService().sendAccountMessage(event,
                                                                              inventoryItem,
                                                                              inventoryItem.getConnection(),
                                                                              dateGenerated.getTime(),
                                                                              MessageType.AGENT,
                                                                              inventoryItem.getHashtags(),
                                                                              null);

                }

            }

            return Response
                    .status(Response.Status.CREATED)
                    .build();

        } catch (Exception e) {
            logger.error("Agent Exception", e);
            return error(e.getMessage(), Response.status(Response.Status.BAD_REQUEST));
        }
    }

}
TOP

Related Classes of com.streamreduce.rest.resource.agent.AgentResource

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.