Using Services from manager-service

This section provides examples for web services in manager-service and also includes additional technniques you can apply.

Prior to using the services described here, it is assumed you have the authentication token from LoginService required to log in and log out of the service. If the examples tell you to enter credentials, refer to Using the LoginService from core-service for details.

Topics in this section:

CaseService

This example is a simple Java application that logs in to ESM, gets the description of a case resource with the specified ID, and then updates the case by changing its state from QUEUED to CLOSED. Find the referred classes in the ESM installation under utilities/sdk/examples/CaseExample.

package main.java.com.arcsight.demo.TestClient;

import java.io.ByteArrayInputStream;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

public class TestCaseRest {
     public static void main(String[] args) throws Exception {
        ArcSightRestClient.trustAll();

        // Specify your ESM host and credentials here
        String host = "localhost";
        String username = "PROVIDE_HERE";
        String password = "PROVIDE_HERE";
        // Specify ID of the Case Resource to be used in this example
        String caseId = "7B7wtYzEBABCAGyLqkEdj+g==";

        // Login through REST
        HashMap<String, String> params = new HashMap<String, String>();
        params.put("login", username);
        params.put("password", password);
        String xml = ArcSightRestClient.getRestXml(host, 8443,
                "core-service", "LoginService", "login", params);

        // Parse the XML for token
        DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
        DocumentBuilder b = f.newDocumentBuilder();
        Document d = b.parse(new ByteArrayInputStream(xml.getBytes()));
        Node node = d.getDocumentElement().getChildNodes().item(0);
        String token = node.getTextContent();
        if (token == null) {
            System.out.println("Failed to login");
            System.out.println(xml);
            return;
        }
        // Search case resource
        params = new HashMap<String, String>();
        params.put("authToken", token);
        params.put("caseID", caseId);
        String resXml = ArcSightRestClient.getRestXml(host, 8443,
                "manager-service", "CaseService", "getCaseEventIDs", params);

        params = new HashMap<String, String>();
        params.put("authToken", token);
        params.put("resourceId", caseId);
        // Alternatively you could use "postRestXml" method here
        String caseXml = ArcSightRestClient.getRestXml(host, 8443,
                "manager-service", "CaseService", "getResourceById", params);

        int startIndex, endIndex;
        // extract xml namespace headers
        startIndex = caseXml.indexOf("xmlns");
        endIndex = caseXml.indexOf("><ns3:return>");
        String xmlNameSpace = caseXml.substring(startIndex, endIndex);

        // extract case body
        startIndex = caseXml.indexOf("<ns3:return>") + 12;
        endIndex = caseXml.indexOf("</ns3:return>");
        String caseBodyXml = caseXml.substring(startIndex, endIndex);
        // remove <referenceString>
        startIndex = caseBodyXml.indexOf("<referenceString>");
        endIndex = caseBodyXml.indexOf("</referenceString>") + 18;
        caseBodyXml = caseBodyXml.substring(0, startIndex) + caseBodyXml.substring(endIndex);

        // toggle stage of QUEUED and CLOSED
        String oldStage = "<stage>QUEUED</stage>";
        String newStage = "<stage>CLOSED</stage>";
        if (caseBodyXml.indexOf(oldStage) >= 0) {
            caseBodyXml = caseBodyXml.replace(oldStage, newStage);
        } else {
            caseBodyXml = caseBodyXml.replace(newStage, oldStage);
        }

        String caseUpdateXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
        caseUpdateXml += "<ns3:update " + xmlNameSpace + ">";
        caseUpdateXml += "<ns3:authToken>" + token + "</ns3:authToken>";
        caseUpdateXml += "<ns3:resource>" + caseBodyXml + "</ns3:resource>";
        caseUpdateXml += "</ns3:update>";

        params = new HashMap<String, String>();
        params.put("value", caseUpdateXml);
        String updateXml = ArcSightRestClient.postRestXml(host, 8443,
                "manager-service", "CaseService", "update", params);

        String updatedXml = caseXml.replace("UNCLASSIFIED", "");
   }
}

GroupService

This example demonstrates how to add a new subgroup for storing case resources to an existing group with the specified ID. ESM SDK classes are used to prepare a complex JSON request body.

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.stream.XMLStreamWriter;

import org.codehaus.jettison.mapped.Configuration;
import org.codehaus.jettison.mapped.MappedNamespaceConvention;
import org.codehaus.jettison.mapped.MappedXMLStreamWriter;

import com.arcsight.web.rest.CommandResult;
import com.arcsight.web.rest.RequestDataException;
import com.arcsight.web.rest.httpclients.ExecutorClient;
import com.arcsight.web.rest.httpclients.URLConnectionExecutorClient;
import com.arcsight.web.rest.media.JsonRequestData;
import com.arcsight.web.rest.media.RequestData;
public class GroupExample extends ArcSightRestClient {

...

    /**
     * Login and perform all created tests.
     * @throws Exception
     */
    public void runTests(ExecutorClient httpClient) throws Exception {

     String authToken = login(httpClient);
     try {
          int groupType = 7; // CASE
          createNewGroup(httpClient, authToken, "New Test Group for Cases", getGroupId(), groupType);
          
     } finally {
          if ( null != authToken ) {
             logout(httpClient, authToken);
          }
     }
     logMsg(this, "runTests", "COMPLETED for httpClient= " + httpClient);
  }
  /**
    * Creates a new group resource with the name <code>groupName</code> under existing Group with ID <code>parentGroupId</code>.
    *
    * @param httpClient client to communicate with the server
    * @param authToken authentication token for the session
    * @param groupName Name of new Group resource
    * @param parentGroupId ID of the parent Group
    * @param groupType identifier of new Group type
    * @throws Exception is any error happens during the execution of the method
    */
  private void createNewGroup(ExecutorClient httpClient, String authToken, String groupName,
     String parentGroupId, int groupType) throws Exception {

     final String methodName = "runTests";

     // 1. Prepare the request the form of a Java object, not JSON or XML string

     //    a. Create an object for a new Group
     com.arcsight.product.manager.resource.service.v1.model.Group testGroup
          = new com.arcsight.product.manager.resource.service.v1.model.Group();
     testGroup.setName(groupName);
     testGroup.setContainedResourceType(groupType);

     //    b. Create and populate Java object containing request data
     com.arcsight.product.manager.resource.service.v1.axis2.jaxws.GroupServiceInsertResource requestObject
     = new com.arcsight.product.manager.resource.service.v1.axis2.jaxws.GroupServiceInsertResource();
     requestObject.setAuthToken(authToken);
     requestObject.setParentId(parentGroupId);
     requestObject.setResource(testGroup);

     // 2. Using JSON parser convert JAX-WS objects into JSON
     String namespaceUri = "http://ws.v1.service.resource.manager.product.arcsight.com/groupService/";
     String shortNamespace = "gro";
     String requestBody = getJsonRequest(requestObject,
          namespaceUri, shortNamespace);
     debugMsg(this, methodName, "1. requestBody: " + requestBody);

     // 3. Wrap JSON into the internal object and send the request to the server
     RequestData requestData = new JsonRequestData(requestBody, "application/json");
     CommandResult result = httpClient.sendPost(getProtocol(), getServerName(), getPort(),
          "manager-service", "GroupService", "insertResource", requestData);
     debugMsg(this, methodName, "2. status: " + result.getStatusCode());

     // 4. Report the result or error
     if ( result.isSuccess() ) {
          debugMsg(this, methodName, "3. New Group: " + result.getResponse());
     } else {
          debugMsg(this, methodName, "3. Failure: " + result.getError());
     }

}
  /**
   * Converts Java object into JSON presentation.
   *
   * @param requestObject Object to convert to JSON
   * @param namespaceUri namespace associated with the service
   * @param namespacePrefix JSON namespace defined for the service (see jettison)
   * @return JSON presentation for the specified Java object
   * @throws RequestDataException
   */
  private static String getJsonRequest(final Object requestObject,
          final String namespaceUri, final String namespacePrefix) throws RequestDataException {

    StringWriter writer = new StringWriter();
    JAXBContext jaxbContext;
    try {
          jaxbContext = JAXBContext.newInstance(requestObject.getClass());

          Configuration config = new Configuration();
          Map<String, String> xmlToJsonNamespaces = new HashMap<String, String>(1);
          xmlToJsonNamespaces.put(namespaceUri, namespacePrefix);
          xmlToJsonNamespaces.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
          config.setXmlToJsonNamespaces(xmlToJsonNamespaces);
          MappedNamespaceConvention con = new MappedNamespaceConvention(config);
          XMLStreamWriter xmlStreamWriter = new MappedXMLStreamWriter(con, writer);
          Marshaller marshaller = jaxbContext.createMarshaller();
          marshaller.marshal(requestObject, xmlStreamWriter);
          return writer.toString();
        } catch (JAXBException e) {
          throw new RequestDataException("Failed to convert requestObject to JSON: " + e, e);
        }
    }

    ...
}

ReportService

This example demonstrates a way to request the XML description of the report resource and print its value in one of the fields (URI field is used here). Other methods of ReportService allow you to create a new report resource, delete, and modify existing resources. Note that this service does not provide the ability to run reports. Running reports are done through the ArchiveReportService, which is not supported in Service Layer APIs for ESM 6.8c or later.

private void runTests(ExecutorClient httpClient, String authToken) throws Exception {

    final String methodName = "runTests";

    // get description of existing Report
    String serviceMethodName = "getResourceById";
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("authToken", authToken);
    params.put("resourceId", reportId);
    RequestData requestData = new NameValuePairRequestData(params);
    CommandResult commandResult = httpClient.sendGet(getProtocol(), getServerName(), getPort(),
        "manager-service", "ReportService", serviceMethodName, requestData);
    String resXml = commandResult.getResponse();
    //debugMsg(this, methodName, "1.GET " + serviceMethodName + ": " + resXml);

    int startIndex, endIndex;

    // extract Resource
    startIndex = resXml.indexOf("<ns22:return>") + 13;
    endIndex = resXml.indexOf("</ns22:return>");
    String reportResource = resXml.substring(startIndex, endIndex);
    //debugMsg(this, methodName, "2. reportResource: " + reportResource);

    // extract <URI>
    startIndex = resXml.indexOf("<URI>") + 5;
    endIndex = resXml.indexOf("</URI>");
    String uri = resXml.substring(startIndex, endIndex);
    debugMsg(this, methodName, "3. URI: " + uri);
}

ResourceService

In this example, you will use ResourceService to list all paths to the root resource from the resource with the given ID. You will see that each path corresponds to a different representation of the resource within the ESM framework hierarchy.

private void runTests(ExecutorClient httpClient, String authToken) throws Exception {

    final String methodName = "runTests";

    // get description of existing Resource
    String serviceMethodName = "getAllPathsToRoot";
    HashMap<String, String> params = new HashMap<String, String>();
    params.put("authToken", authToken);
    params.put("resourceId", resourceId);
    RequestData requestData = new NameValuePairRequestData(params);
        CommandResult commandResult = httpClient.sendGet(getProtocol(), getServerName(), getPort(),
        "manager-service", "ResourceService", serviceMethodName, requestData);
    String resXml = commandResult.getResponse();
    //debugMsg(this, methodName, "1.GET " + serviceMethodName + ": " + resXml);

    /*
    * Multiple paths to root will be returned in the form of array like below
    *
<ns23:return>01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/06tGQ60cBABCAEoIkbYC9AQ==/7iINeGUgBABCAF5RSwU2eOg==</ns23:return>
<ns23:return>01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/0wu10okcBABCAFs59orlj6g==/06tGQ60cBABCAEoIkbYC9AQ==/7iINeGUgBABCAF5RSwU2eOg==</ns23:return>
<ns23:return>01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/0wu10okcBABCAFs59orlj6g==/7iINeGUgBABCAF5RSwU2eOg==</ns23:return>         
    */

    int startIndex=0;
    int endIndex=0;

    // Extract paths to root
    int numPaths = 0;
    while ( true ) {
        startIndex = resXml.indexOf("<ns23:return>", endIndex) + 13;
        if ( startIndex < 0 || startIndex < endIndex) {
            break;
        }
        endIndex = resXml.indexOf("</ns23:return>", startIndex);
        if ( endIndex < 0 ) {
            break;
        }
        String allPathsToRoot = resXml.substring(startIndex, endIndex);
        numPaths++;
        debugMsg(this, methodName, "" + numPaths + ". allPathsToRoot: " + allPathsToRoot);
    }
    
    debugMsg(this, methodName, "Number of paths to root: " + numPaths);
}

Here is an example of a truncated output:

18:23:38,024 DEBUG ResourceExample:217 - Received Login XML = <?xml version="1.0" encoding="UTF-8" standalone="yes"?><ns3:loginResponse xmlns:ns2="http://ws.v1.service.core.product.arcsight.com/groupService/" xmlns:ns3="http://ws.v1.service.core.product.arcsight.com/loginService/" xmlns:ns4="http://ws.v1.service.core.product.arcsight.com/userService/"><ns3:return>znDHbIXpdtdjaq1NeKOhTFWzK7AAjSDgsgDefPYEW20.</ns3:return></ns3:loginResponse>
18:23:38,068 DEBUG ResourceExample:217 - Successful login
18:23:38,073 DEBUG URLConnectionExecutorClient:64 - GET urlstr=https://HOST:8443/www/manager-service/rest/ResourceService/getAllPathsToRoot?resourceId=7iINeGUgBABCAF5RSwU2eOg%3D%3D&authToken=znDHbIXpdtdjaq1NeKOhTFWzK7AAjSDgsgDefPYEW20.
18:23:38,087 DEBUG ResourceExample:217 - 1. allPathsToRoot: 01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/06tGQ60cBABCAEoIkbYC9AQ==/7iINeGUgBABCAF5RSwU2eOg==
18:23:38,087 DEBUG ResourceExample:217 - 2. allPathsToRoot: 01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/0wu10okcBABCAFs59orlj6g==/06tGQ60cBABCAEoIkbYC9AQ==/7iINeGUgBABCAF5RSwU2eOg==
18:23:38,088 DEBUG ResourceExample:217 - 3. allPathsToRoot: 01000100010001007/01000100017777777/0AFPLmPsAABCAHBFLqlR1uw==/0XT-k80YBABCA5fPgKSmjNg==/0wu10okcBABCAFs59orlj6g==/7iINeGUgBABCAF5RSwU2eOg==
18:23:38,088 DEBUG ResourceExample:217 - Number of paths to root: 3

SecurityEventService

The example starts with a login and then requests several events by ID. The returned data could be requested in XML (shown in the example) or in JSON. With regard to the requested format, the returned data could be parsed to get the values of the desired event fields.

package com.arcsight.tests.rest;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.arcsight.web.rest.CommandResult;
import com.arcsight.web.rest.httpclients.ExecutorClient;

public class SecurityEventExample extends BaseExample {

    public long[] getEventIds() {
         return new long[] { 1L, 2L, 3L };
    }

    public void test(ExecutorClient httpClient) {
        String authToken = login(httpClient);
        try {
           getSecurityEvents(httpClient, authToken, getEventIds());
        } finally {
           if ( null != authToken ) {
                logout(httpClient, authToken);
           }
        }
     }

     private void getSecurityEvents(final ExecutorClient executor, final String authToken, final long[] eventIds)
     throws IOException {

        // See manager-client Javadoc for JSON prototype for request body
        String requestBodyFormat = "{\n"
        + " \"sev.getSecurityEvents\" : {\n"
        + " \"sev.authToken\" : \"%s\",\n"
        + " \"sev.ids\" : [ \"%s\" ],\n"
        //+    "    \"sev.timeField\" : { \"JSON for the nested object\" },\n"
        + " \"sev.startMillis\" : \"%s\",\n"
        + " \"sev.endMillis\" : \"%s\"\n"
        + " }\n"
        + "}";

        // make sure that your Events within this timeframe. Use "-1" for unlimited range
        final long startMillis = -1L;
        final long endMillis = -1L;

        // simplified way to prepare request body
        String requestBody = String.format(requestBodyFormat,
              authToken, Arrays.toString(eventIds), startMillis, endMillis);

        // Header to request response in XML format
        Map<String, String> requestProperties = new HashMap<String, String>();
        requestProperties.put("accept", "application/xml");

        // submit the request using one of the clients (HttpURLConnection or apache HttpClient)
        String urlstr = "https://HOST:PORT/Context/SecurityEventService/getSecurityEvents";
        CommandResult result = executor.sendPost(urlstr, requestProperties,
                       requestBody, "application/json");

        // Get the description of the Events in the requested format (XML/JSON)
        String responseBody = result.getResponse();

        // Parse the response to retrieve the fields with the required data
        /*
        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <ns25:getSecurityEventsResponse

xmlns:ns2="http://ws.v1.service.resource.manager.product.arcsight.com/activeListService/"
xmlns:ns3="http://ws.v1.service.resource.manager.product.arcsight.com/archiveReportService/"
xmlns:ns4="http://ws.v1.service.resource.manager.product.arcsight.com/caseService/"
            ...
xmlns:ns25="http://ws.v1.service.resource.manager.product.arcsight.com/securityEventService/"
            ...
            <ns25:return>
                <agent>
                    <mutable>true</mutable>
                    <address>265716344</address>
                    <assetId>401Id4kUBABCAXKvda6GBuw==</assetId>
                    <assetLocalId>-9223372036854775808</assetLocalId>
                    <hostName>192.0.2.0</hostName>
                    <macAddress>-9223372036854775808</macAddress>
                    <translatedAddress>-9223372036854775808</translatedAddress>
                    <zone>
                        <externalID>Hewlett-Packard Company</externalID>
                        <id>MX8HU5fsAABCCV7v-GNArfg==</id>
                        ...
            </ns25:return>
            <ns25:return>
                <agent>
                    <mutable>true</mutable>
                    <address>265716344</address>
                    <assetId>401Id4kUBABCAXKvda6GBuw==</assetId>
                    ...
                <ttl>10</ttl>
                <type>BASE</type>
            </ns25:return>
        </ns25:getSecurityEventsResponse>
        */
    }
}