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>
*/
}
}