YARN-3814. REST API implementation for getting raw entities in TimelineReader (Varun Saxena via sjlee)
This commit is contained in:
parent
c7224a285c
commit
451c13b1de
|
@ -18,10 +18,18 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.service.AbstractService;
|
import org.apache.hadoop.service.AbstractService;
|
||||||
|
import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntity;
|
||||||
import org.apache.hadoop.yarn.server.timelineservice.storage.TimelineReader;
|
import org.apache.hadoop.yarn.server.timelineservice.storage.TimelineReader;
|
||||||
|
import org.apache.hadoop.yarn.server.timelineservice.storage.TimelineReader.Field;
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
@Unstable
|
@Unstable
|
||||||
|
@ -33,4 +41,37 @@ public class TimelineReaderManager extends AbstractService {
|
||||||
super(TimelineReaderManager.class.getName());
|
super(TimelineReaderManager.class.getName());
|
||||||
this.reader = timelineReader;
|
this.reader = timelineReader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a set of entities matching given predicates. The meaning of each
|
||||||
|
* argument has been documented with {@link TimelineReader#getEntities}.
|
||||||
|
*
|
||||||
|
* @see TimelineReader#getEntities
|
||||||
|
*/
|
||||||
|
Set<TimelineEntity> getEntities(String userId, String clusterId,
|
||||||
|
String flowId, Long flowRunId, String appId, String entityType,
|
||||||
|
Long limit, Long createdTimeBegin, Long createdTimeEnd,
|
||||||
|
Long modifiedTimeBegin, Long modifiedTimeEnd,
|
||||||
|
Map<String, Set<String>> relatesTo, Map<String, Set<String>> isRelatedTo,
|
||||||
|
Map<String, Object> infoFilters, Map<String, String> configFilters,
|
||||||
|
Set<String> metricFilters, Set<String> eventFilters,
|
||||||
|
EnumSet<Field> fieldsToRetrieve) throws IOException {
|
||||||
|
return reader.getEntities(userId, clusterId, flowId, flowRunId, appId,
|
||||||
|
entityType, limit, createdTimeBegin, createdTimeEnd, modifiedTimeBegin,
|
||||||
|
modifiedTimeEnd, relatesTo, isRelatedTo, infoFilters, configFilters,
|
||||||
|
metricFilters, eventFilters, fieldsToRetrieve);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get single timeline entity. The meaning of each argument has been
|
||||||
|
* documented with {@link TimelineReader#getEntity}.
|
||||||
|
*
|
||||||
|
* @see TimelineReader#getEntity
|
||||||
|
*/
|
||||||
|
public TimelineEntity getEntity(String userId, String clusterId,
|
||||||
|
String flowId, Long flowRunId, String appId, String entityType,
|
||||||
|
String entityId, EnumSet<Field> fields) throws IOException {
|
||||||
|
return reader.getEntity(userId, clusterId, flowId, flowRunId, appId,
|
||||||
|
entityType, entityId, fields);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ import com.google.common.annotations.VisibleForTesting;
|
||||||
public class TimelineReaderServer extends CompositeService {
|
public class TimelineReaderServer extends CompositeService {
|
||||||
private static final Log LOG = LogFactory.getLog(TimelineReaderServer.class);
|
private static final Log LOG = LogFactory.getLog(TimelineReaderServer.class);
|
||||||
private static final int SHUTDOWN_HOOK_PRIORITY = 30;
|
private static final int SHUTDOWN_HOOK_PRIORITY = 30;
|
||||||
private static final String TIMELINE_READER_MANAGER_ATTR =
|
static final String TIMELINE_READER_MANAGER_ATTR =
|
||||||
"timeline.reader.manager";
|
"timeline.reader.manager";
|
||||||
|
|
||||||
private HttpServer2 readerWebServer;
|
private HttpServer2 readerWebServer;
|
||||||
|
|
|
@ -18,42 +18,283 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.Produces;
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.WebApplicationException;
|
||||||
import javax.ws.rs.core.Context;
|
import javax.ws.rs.core.Context;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
import org.apache.hadoop.classification.InterfaceStability.Unstable;
|
||||||
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout;
|
||||||
|
import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntity;
|
||||||
|
import org.apache.hadoop.yarn.server.timeline.GenericObjectMapper;
|
||||||
|
import org.apache.hadoop.yarn.server.timelineservice.storage.TimelineReader.Field;
|
||||||
import org.apache.hadoop.yarn.util.timeline.TimelineUtils;
|
import org.apache.hadoop.yarn.util.timeline.TimelineUtils;
|
||||||
|
import org.apache.hadoop.yarn.webapp.BadRequestException;
|
||||||
|
import org.apache.hadoop.yarn.webapp.NotFoundException;
|
||||||
|
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
|
||||||
/** REST end point for Timeline Reader */
|
/** REST end point for Timeline Reader */
|
||||||
@Private
|
@Private
|
||||||
@Unstable
|
@Unstable
|
||||||
@Singleton
|
@Singleton
|
||||||
@Path("/ws/v2/timeline")
|
@Path("/ws/v2/timeline")
|
||||||
public class TimelineReaderWebServices {
|
public class TimelineReaderWebServices {
|
||||||
|
private static final Log LOG =
|
||||||
|
LogFactory.getLog(TimelineReaderWebServices.class);
|
||||||
|
|
||||||
|
@Context private ServletContext ctxt;
|
||||||
|
|
||||||
|
private static final String COMMA_DELIMITER = ",";
|
||||||
|
private static final String COLON_DELIMITER = ":";
|
||||||
|
|
||||||
private void init(HttpServletResponse response) {
|
private void init(HttpServletResponse response) {
|
||||||
response.setContentType(null);
|
response.setContentType(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Set<String> parseValuesStr(String str, String delimiter) {
|
||||||
|
if (str == null || str.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Set<String> strSet = new HashSet<String>();
|
||||||
|
String[] strs = str.split(delimiter);
|
||||||
|
for (String aStr : strs) {
|
||||||
|
strSet.add(aStr.trim());
|
||||||
|
}
|
||||||
|
return strSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static <T> void parseKeyValues(Map<String,T> map, String str,
|
||||||
|
String pairsDelim, String keyValuesDelim, boolean stringValue,
|
||||||
|
boolean multipleValues) {
|
||||||
|
String[] pairs = str.split(pairsDelim);
|
||||||
|
for (String pair : pairs) {
|
||||||
|
if (pair == null || pair.trim().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String[] pairStrs = pair.split(keyValuesDelim);
|
||||||
|
if (pairStrs.length < 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!stringValue) {
|
||||||
|
try {
|
||||||
|
Object value =
|
||||||
|
GenericObjectMapper.OBJECT_READER.readValue(pairStrs[1].trim());
|
||||||
|
map.put(pairStrs[0].trim(), (T) value);
|
||||||
|
} catch (IOException e) {
|
||||||
|
map.put(pairStrs[0].trim(), (T) pairStrs[1].trim());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String key = pairStrs[0].trim();
|
||||||
|
if (multipleValues) {
|
||||||
|
Set<String> values = new HashSet<String>();
|
||||||
|
for (int i = 1; i < pairStrs.length; i++) {
|
||||||
|
values.add(pairStrs[i].trim());
|
||||||
|
}
|
||||||
|
map.put(key, (T) values);
|
||||||
|
} else {
|
||||||
|
map.put(key, (T) pairStrs[1].trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Set<String>> parseKeyStrValuesStr(String str,
|
||||||
|
String pairsDelim, String keyValuesDelim) {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, Set<String>> map = new HashMap<String, Set<String>>();
|
||||||
|
parseKeyValues(map, str,pairsDelim, keyValuesDelim, true, true);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> parseKeyStrValueStr(String str,
|
||||||
|
String pairsDelim, String keyValDelim) {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
parseKeyValues(map, str, pairsDelim, keyValDelim, true, false);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> parseKeyStrValueObj(String str,
|
||||||
|
String pairsDelim, String keyValDelim) {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Map<String, Object> map = new HashMap<String, Object>();
|
||||||
|
parseKeyValues(map, str, pairsDelim, keyValDelim, false, false);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static EnumSet<Field> parseFieldsStr(String str, String delimiter) {
|
||||||
|
if (str == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String[] strs = str.split(delimiter);
|
||||||
|
EnumSet<Field> fieldList = EnumSet.noneOf(Field.class);
|
||||||
|
for (String s : strs) {
|
||||||
|
fieldList.add(Field.valueOf(s.trim().toUpperCase()));
|
||||||
|
}
|
||||||
|
return fieldList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Long parseLongStr(String str) {
|
||||||
|
return str == null ? null : Long.parseLong(str.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parseStr(String str) {
|
||||||
|
return str == null ? null : str.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UserGroupInformation getUser(HttpServletRequest req) {
|
||||||
|
String remoteUser = req.getRemoteUser();
|
||||||
|
UserGroupInformation callerUGI = null;
|
||||||
|
if (remoteUser != null) {
|
||||||
|
callerUGI = UserGroupInformation.createRemoteUser(remoteUser);
|
||||||
|
}
|
||||||
|
return callerUGI;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimelineReaderManager getTimelineReaderManager() {
|
||||||
|
return (TimelineReaderManager)
|
||||||
|
ctxt.getAttribute(TimelineReaderServer.TIMELINE_READER_MANAGER_ATTR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the description of the timeline reader web services.
|
* Return the description of the timeline reader web services.
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@Produces({ MediaType.APPLICATION_JSON /* , MediaType.APPLICATION_XML */})
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public TimelineAbout about(
|
public TimelineAbout about(
|
||||||
@Context HttpServletRequest req,
|
@Context HttpServletRequest req,
|
||||||
@Context HttpServletResponse res) {
|
@Context HttpServletResponse res) {
|
||||||
init(res);
|
init(res);
|
||||||
return TimelineUtils.createTimelineAbout("Timeline Reader API");
|
return TimelineUtils.createTimelineAbout("Timeline Reader API");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a set of entities that match the given parameters.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/entities/{clusterId}/{appId}/{entityType}")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Set<TimelineEntity> getEntities(
|
||||||
|
@Context HttpServletRequest req,
|
||||||
|
@Context HttpServletResponse res,
|
||||||
|
@PathParam("clusterId") String clusterId,
|
||||||
|
@PathParam("appId") String appId,
|
||||||
|
@PathParam("entityType") String entityType,
|
||||||
|
@QueryParam("userId") String userId,
|
||||||
|
@QueryParam("flowId") String flowId,
|
||||||
|
@QueryParam("flowRunId") String flowRunId,
|
||||||
|
@QueryParam("limit") String limit,
|
||||||
|
@QueryParam("createdTimeStart") String createdTimeStart,
|
||||||
|
@QueryParam("createdTimeEnd") String createdTimeEnd,
|
||||||
|
@QueryParam("modifiedTimeStart") String modifiedTimeStart,
|
||||||
|
@QueryParam("modifiedTimeEnd") String modifiedTimeEnd,
|
||||||
|
@QueryParam("relatesto") String relatesTo,
|
||||||
|
@QueryParam("isrelatedto") String isRelatedTo,
|
||||||
|
@QueryParam("infofilters") String infofilters,
|
||||||
|
@QueryParam("conffilters") String conffilters,
|
||||||
|
@QueryParam("metricfilters") String metricfilters,
|
||||||
|
@QueryParam("eventfilters") String eventfilters,
|
||||||
|
@QueryParam("fields") String fields) {
|
||||||
|
init(res);
|
||||||
|
TimelineReaderManager timelineReaderManager = getTimelineReaderManager();
|
||||||
|
UserGroupInformation callerUGI = getUser(req);
|
||||||
|
try {
|
||||||
|
return timelineReaderManager.getEntities(
|
||||||
|
callerUGI != null && (userId == null || userId.isEmpty()) ?
|
||||||
|
callerUGI.getUserName().trim() : parseStr(userId),
|
||||||
|
parseStr(clusterId), parseStr(flowId),
|
||||||
|
parseLongStr(flowRunId), parseStr(appId), parseStr(entityType),
|
||||||
|
parseLongStr(limit), parseLongStr(createdTimeStart),
|
||||||
|
parseLongStr(createdTimeEnd), parseLongStr(modifiedTimeStart),
|
||||||
|
parseLongStr(modifiedTimeEnd),
|
||||||
|
parseKeyStrValuesStr(relatesTo, COMMA_DELIMITER, COLON_DELIMITER),
|
||||||
|
parseKeyStrValuesStr(isRelatedTo, COMMA_DELIMITER, COLON_DELIMITER),
|
||||||
|
parseKeyStrValueObj(infofilters, COMMA_DELIMITER, COLON_DELIMITER),
|
||||||
|
parseKeyStrValueStr(conffilters, COMMA_DELIMITER, COLON_DELIMITER),
|
||||||
|
parseValuesStr(metricfilters, COMMA_DELIMITER),
|
||||||
|
parseValuesStr(eventfilters, COMMA_DELIMITER),
|
||||||
|
parseFieldsStr(fields, COMMA_DELIMITER));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new BadRequestException(
|
||||||
|
"createdTime or modifiedTime start/end or limit or flowId is not" +
|
||||||
|
" a numeric value.");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new BadRequestException("Requested Invalid Field.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error getting entities", e);
|
||||||
|
throw new WebApplicationException(e,
|
||||||
|
Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single entity of the given entity type and Id.
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@Path("/entity/{clusterId}/{appId}/{entityType}/{entityId}/")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public TimelineEntity getEntity(
|
||||||
|
@Context HttpServletRequest req,
|
||||||
|
@Context HttpServletResponse res,
|
||||||
|
@PathParam("clusterId") String clusterId,
|
||||||
|
@PathParam("appId") String appId,
|
||||||
|
@PathParam("entityType") String entityType,
|
||||||
|
@PathParam("entityId") String entityId,
|
||||||
|
@QueryParam("userId") String userId,
|
||||||
|
@QueryParam("flowId") String flowId,
|
||||||
|
@QueryParam("flowRunId") String flowRunId,
|
||||||
|
@QueryParam("fields") String fields) {
|
||||||
|
init(res);
|
||||||
|
TimelineReaderManager timelineReaderManager = getTimelineReaderManager();
|
||||||
|
UserGroupInformation callerUGI = getUser(req);
|
||||||
|
TimelineEntity entity = null;
|
||||||
|
try {
|
||||||
|
entity = timelineReaderManager.getEntity(
|
||||||
|
callerUGI != null && (userId == null || userId.isEmpty()) ?
|
||||||
|
callerUGI.getUserName().trim() : parseStr(userId),
|
||||||
|
parseStr(clusterId), parseStr(flowId), parseLongStr(flowRunId),
|
||||||
|
parseStr(appId), parseStr(entityType), parseStr(entityId),
|
||||||
|
parseFieldsStr(fields, COMMA_DELIMITER));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new BadRequestException("flowRunId is not a numeric value.");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
throw new BadRequestException("Requested Invalid Field.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LOG.error("Error getting entity", e);
|
||||||
|
throw new WebApplicationException(e,
|
||||||
|
Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
if (entity == null) {
|
||||||
|
throw new NotFoundException("Timeline entity {id: " + parseStr(entityId) +
|
||||||
|
", type: " + parseStr(entityType) + " } is not found");
|
||||||
|
}
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -21,6 +21,7 @@ package org.apache.hadoop.yarn.server.timelineservice.storage;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
@ -397,6 +398,10 @@ public class FileSystemTimelineReaderImpl extends AbstractService
|
||||||
new FileInputStream(entityFile), Charset.forName("UTF-8")))) {
|
new FileInputStream(entityFile), Charset.forName("UTF-8")))) {
|
||||||
TimelineEntity entity = readEntityFromFile(reader);
|
TimelineEntity entity = readEntityFromFile(reader);
|
||||||
return createEntityToBeReturned(entity, fieldsToRetrieve);
|
return createEntityToBeReturned(entity, fieldsToRetrieve);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOG.info("Cannot find entity {id:" + entityId + " , type:" + entityType +
|
||||||
|
"}. Will send HTTP 404 in response.");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,25 +18,37 @@
|
||||||
|
|
||||||
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
package org.apache.hadoop.yarn.server.timelineservice.reader;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.UndeclaredThrowableException;
|
import java.lang.reflect.UndeclaredThrowableException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout;
|
import org.apache.hadoop.yarn.api.records.timeline.TimelineAbout;
|
||||||
|
import org.apache.hadoop.yarn.api.records.timelineservice.TimelineEntity;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.webapp.YarnJacksonJaxbJsonProvider;
|
import org.apache.hadoop.yarn.webapp.YarnJacksonJaxbJsonProvider;
|
||||||
|
import org.apache.hadoop.yarn.server.timelineservice.storage.TestFileSystemTimelineReaderImpl;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.sun.jersey.api.client.Client;
|
import com.sun.jersey.api.client.Client;
|
||||||
import com.sun.jersey.api.client.ClientResponse;
|
import com.sun.jersey.api.client.ClientResponse;
|
||||||
|
import com.sun.jersey.api.client.ClientResponse.Status;
|
||||||
|
import com.sun.jersey.api.client.GenericType;
|
||||||
import com.sun.jersey.api.client.config.ClientConfig;
|
import com.sun.jersey.api.client.config.ClientConfig;
|
||||||
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
import com.sun.jersey.api.client.config.DefaultClientConfig;
|
||||||
import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
|
import com.sun.jersey.client.urlconnection.HttpURLConnectionFactory;
|
||||||
|
@ -46,12 +58,23 @@ public class TestTimelineReaderWebServices {
|
||||||
private int serverPort;
|
private int serverPort;
|
||||||
private TimelineReaderServer server;
|
private TimelineReaderServer server;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() throws Exception {
|
||||||
|
TestFileSystemTimelineReaderImpl.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDown() throws Exception {
|
||||||
|
TestFileSystemTimelineReaderImpl.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void init() throws Exception {
|
public void init() throws Exception {
|
||||||
try {
|
try {
|
||||||
Configuration config = new YarnConfiguration();
|
Configuration config = new YarnConfiguration();
|
||||||
config.set(YarnConfiguration.TIMELINE_SERVICE_WEBAPP_ADDRESS,
|
config.set(YarnConfiguration.TIMELINE_SERVICE_WEBAPP_ADDRESS,
|
||||||
"localhost:0");
|
"localhost:0");
|
||||||
|
config.set(YarnConfiguration.RM_CLUSTER_ID, "cluster1");
|
||||||
server = new TimelineReaderServer();
|
server = new TimelineReaderServer();
|
||||||
server.init(config);
|
server.init(config);
|
||||||
server.start();
|
server.start();
|
||||||
|
@ -69,6 +92,22 @@ public class TestTimelineReaderWebServices {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static TimelineEntity newEntity(String type, String id) {
|
||||||
|
TimelineEntity entity = new TimelineEntity();
|
||||||
|
entity.setIdentifier(new TimelineEntity.Identifier(type, id));
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void verifyHttpResponse(Client client, URI uri,
|
||||||
|
Status status) {
|
||||||
|
ClientResponse resp =
|
||||||
|
client.resource(uri).accept(MediaType.APPLICATION_JSON)
|
||||||
|
.type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||||
|
assertNotNull(resp);
|
||||||
|
assertTrue("Response from server should have been " + status,
|
||||||
|
resp.getClientResponseStatus().equals(status));
|
||||||
|
}
|
||||||
|
|
||||||
private static Client createClient() {
|
private static Client createClient() {
|
||||||
ClientConfig cfg = new DefaultClientConfig();
|
ClientConfig cfg = new DefaultClientConfig();
|
||||||
cfg.getClasses().add(YarnJacksonJaxbJsonProvider.class);
|
cfg.getClasses().add(YarnJacksonJaxbJsonProvider.class);
|
||||||
|
@ -76,14 +115,19 @@ public class TestTimelineReaderWebServices {
|
||||||
new DummyURLConnectionFactory()), cfg);
|
new DummyURLConnectionFactory()), cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ClientResponse getResponse(Client client, URI uri) throws Exception {
|
private static ClientResponse getResponse(Client client, URI uri)
|
||||||
|
throws Exception {
|
||||||
ClientResponse resp =
|
ClientResponse resp =
|
||||||
client.resource(uri).accept(MediaType.APPLICATION_JSON)
|
client.resource(uri).accept(MediaType.APPLICATION_JSON)
|
||||||
.type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
.type(MediaType.APPLICATION_JSON).get(ClientResponse.class);
|
||||||
if (resp == null ||
|
if (resp == null ||
|
||||||
resp.getClientResponseStatus() != ClientResponse.Status.OK) {
|
resp.getClientResponseStatus() != ClientResponse.Status.OK) {
|
||||||
System.out.println(resp.getClientResponseStatus());
|
String msg = new String();
|
||||||
throw new IOException("Incorrect response from timeline reader.");
|
if (resp != null) {
|
||||||
|
msg = resp.getClientResponseStatus().toString();
|
||||||
|
}
|
||||||
|
throw new IOException("Incorrect response from timeline reader. " +
|
||||||
|
"Status=" + msg);
|
||||||
}
|
}
|
||||||
return resp;
|
return resp;
|
||||||
}
|
}
|
||||||
|
@ -102,8 +146,7 @@ public class TestTimelineReaderWebServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAbout()
|
public void testAbout() throws Exception {
|
||||||
throws IOException {
|
|
||||||
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/");
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/");
|
||||||
Client client = createClient();
|
Client client = createClient();
|
||||||
try {
|
try {
|
||||||
|
@ -111,9 +154,406 @@ public class TestTimelineReaderWebServices {
|
||||||
TimelineAbout about = resp.getEntity(TimelineAbout.class);
|
TimelineAbout about = resp.getEntity(TimelineAbout.class);
|
||||||
Assert.assertNotNull(about);
|
Assert.assertNotNull(about);
|
||||||
Assert.assertEquals("Timeline Reader API", about.getAbout());
|
Assert.assertEquals("Timeline Reader API", about.getAbout());
|
||||||
} catch (Exception re) {
|
} finally {
|
||||||
throw new IOException(
|
client.destroy();
|
||||||
"Failed to get the response from timeline reader.", re);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntityDefaultView() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entity/cluster1/app1/app/id_1");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
TimelineEntity entity = resp.getEntity(TimelineEntity.class);
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entity);
|
||||||
|
assertEquals("id_1", entity.getId());
|
||||||
|
assertEquals("app", entity.getType());
|
||||||
|
assertEquals(1425016502000L, entity.getCreatedTime());
|
||||||
|
assertEquals(1425016503000L, entity.getModifiedTime());
|
||||||
|
// Default view i.e. when no fields are specified, entity contains only
|
||||||
|
// entity id, entity type, created and modified time.
|
||||||
|
assertEquals(0, entity.getConfigs().size());
|
||||||
|
assertEquals(0, entity.getMetrics().size());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntityWithUserAndFlowInfo() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entity/cluster1/app1/app/id_1?userId=user1&" +
|
||||||
|
"flowId=flow1&flowRunId=1");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
TimelineEntity entity = resp.getEntity(TimelineEntity.class);
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entity);
|
||||||
|
assertEquals("id_1", entity.getId());
|
||||||
|
assertEquals("app", entity.getType());
|
||||||
|
assertEquals(1425016502000L, entity.getCreatedTime());
|
||||||
|
assertEquals(1425016503000L, entity.getModifiedTime());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntityCustomFields() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
// Fields are case insensitive.
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entity/cluster1/app1/app/id_1?fields=CONFIGS,Metrics,info");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
TimelineEntity entity = resp.getEntity(TimelineEntity.class);
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entity);
|
||||||
|
assertEquals("id_1", entity.getId());
|
||||||
|
assertEquals("app", entity.getType());
|
||||||
|
assertEquals(3, entity.getConfigs().size());
|
||||||
|
assertEquals(3, entity.getMetrics().size());
|
||||||
|
assertEquals(1, entity.getInfo().size());
|
||||||
|
// No events will be returned as events are not part of fields.
|
||||||
|
assertEquals(0, entity.getEvents().size());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntityAllFields() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entity/cluster1/app1/app/id_1?fields=ALL");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
TimelineEntity entity = resp.getEntity(TimelineEntity.class);
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entity);
|
||||||
|
assertEquals("id_1", entity.getId());
|
||||||
|
assertEquals("app", entity.getType());
|
||||||
|
assertEquals(3, entity.getConfigs().size());
|
||||||
|
assertEquals(3, entity.getMetrics().size());
|
||||||
|
assertEquals(1, entity.getInfo().size());
|
||||||
|
assertEquals(2, entity.getEvents().size());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntityNotPresent() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entity/cluster1/app1/app/id_10");
|
||||||
|
verifyHttpResponse(client, uri, Status.NOT_FOUND);
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntities() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(4, entities.size());
|
||||||
|
assertTrue("Entities id_1, id_2, id_3 and id_4 should have been" +
|
||||||
|
" present in response",
|
||||||
|
entities.contains(newEntity("app", "id_1")) &&
|
||||||
|
entities.contains(newEntity("app", "id_2")) &&
|
||||||
|
entities.contains(newEntity("app", "id_3")) &&
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesWithLimit() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?limit=2");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
// Entities returned are based on most recent created time.
|
||||||
|
assertTrue("Entities with id_1 and id_4 should have been present " +
|
||||||
|
"in response based on entity created time.",
|
||||||
|
entities.contains(newEntity("app", "id_1")) &&
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?limit=3");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
// Even though 2 entities out of 4 have same created time, one entity
|
||||||
|
// is left out due to limit
|
||||||
|
assertEquals(3, entities.size());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesBasedOnCreatedTime() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?createdTimeStart=1425016502030&"
|
||||||
|
+ "createdTimeEnd=1425016502060");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_4 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?createdTimeEnd=1425016502010");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(3, entities.size());
|
||||||
|
assertFalse("Entity with id_4 should not have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?createdTimeStart=1425016502010");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_4 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesBasedOnModifiedTime() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?modifiedTimeStart=1425016502090"
|
||||||
|
+ "&modifiedTimeEnd=1425016503020");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
assertTrue("Entities with id_1 and id_4 should have been" +
|
||||||
|
" present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")) &&
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?modifiedTimeEnd=1425016502090");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
assertTrue("Entities with id_2 and id_3 should have been " +
|
||||||
|
"present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_2")) &&
|
||||||
|
entities.contains(newEntity("app", "id_3")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?modifiedTimeStart=1425016503005");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_4 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_4")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesByRelations() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?relatesto=flow:flow1");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_1 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?isrelatedto=type1:tid1_2,type2:" +
|
||||||
|
"tid2_1%60");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_1 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")));
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app?isrelatedto=type1:tid1_1:tid1_2" +
|
||||||
|
",type2:tid2_1%60");
|
||||||
|
resp = getResponse(client, uri);
|
||||||
|
entities = resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_1 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesByConfigFilters() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?conffilters=config_1:123," +
|
||||||
|
"config_3:abc");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
assertTrue("Entities with id_1 and id_3 should have been present" +
|
||||||
|
" in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")) &&
|
||||||
|
entities.contains(newEntity("app", "id_3")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesByInfoFilters() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?infofilters=info2:3.5");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_3 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_3")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesByMetricFilters() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?metricfilters=metric3");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(2, entities.size());
|
||||||
|
assertTrue("Entities with id_1 and id_2 should have been present" +
|
||||||
|
" in response.",
|
||||||
|
entities.contains(newEntity("app", "id_1")) &&
|
||||||
|
entities.contains(newEntity("app", "id_2")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesByEventFilters() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?eventfilters=event_2,event_4");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(1, entities.size());
|
||||||
|
assertTrue("Entity with id_3 should have been present in response.",
|
||||||
|
entities.contains(newEntity("app", "id_3")));
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetEntitiesNoMatch() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?metricfilters=metric7&" +
|
||||||
|
"isrelatedto=type1:tid1_1;tid1_2,type2:tid2_1%60&relatesto=" +
|
||||||
|
"flow:flow1&eventfilters=event_2,event_4&infofilters=info2:3.5" +
|
||||||
|
"&createdTimeStart=1425016502030&createdTimeEnd=1425016502060");
|
||||||
|
ClientResponse resp = getResponse(client, uri);
|
||||||
|
Set<TimelineEntity> entities =
|
||||||
|
resp.getEntity(new GenericType<Set<TimelineEntity>>(){});
|
||||||
|
assertEquals(MediaType.APPLICATION_JSON_TYPE, resp.getType());
|
||||||
|
assertNotNull(entities);
|
||||||
|
assertEquals(0, entities.size());
|
||||||
|
} finally {
|
||||||
|
client.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidValuesHandling() throws Exception {
|
||||||
|
Client client = createClient();
|
||||||
|
try {
|
||||||
|
URI uri = URI.create("http://localhost:" + serverPort + "/ws/v2/" +
|
||||||
|
"timeline/entities/cluster1/app1/app?flowRunId=a23b");
|
||||||
|
verifyHttpResponse(client, uri, Status.BAD_REQUEST);
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entity/cluster1/app1/app/id_1?flowRunId=2ab15");
|
||||||
|
verifyHttpResponse(client, uri, Status.BAD_REQUEST);
|
||||||
|
|
||||||
|
uri = URI.create("http://localhost:" + serverPort + "/ws/v2/timeline/" +
|
||||||
|
"entities/cluster1/app1/app/?limit=#$561av");
|
||||||
|
verifyHttpResponse(client, uri, Status.BAD_REQUEST);
|
||||||
} finally {
|
} finally {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue