blob: 8f41c483fa5a4798e212dcb68034472eaaed4985 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.falcon.resource.proxy;
import org.apache.commons.lang.StringUtils;
import org.apache.falcon.FalconException;
import org.apache.falcon.FalconWebException;
import org.apache.falcon.entity.EntityUtil;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.entity.v0.EntityType;
import org.apache.falcon.entity.v0.cluster.Cluster;
import org.apache.falcon.extensions.jdbc.ExtensionMetaStore;
import org.apache.falcon.extensions.store.ExtensionStore;
import org.apache.falcon.monitors.Dimension;
import org.apache.falcon.monitors.Monitored;
import org.apache.falcon.resource.APIResult;
import org.apache.falcon.resource.AbstractExtensionManager;
import org.apache.falcon.resource.AbstractSchedulableEntityManager;
import org.apache.falcon.resource.EntityList;
import org.apache.falcon.resource.EntitySummaryResult;
import org.apache.falcon.resource.FeedLookupResult;
import org.apache.falcon.resource.SchedulableEntityInstanceResult;
import org.apache.falcon.util.DeploymentUtil;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A proxy implementation of the schedulable entity operations.
*/
@Path("entities")
public class SchedulableEntityManagerProxy extends AbstractSchedulableEntityManager {
static final String PRISM_TAG = "prism";
static final String FALCON_TAG = "falcon";
private EntityProxyUtil entityProxyUtil = new EntityProxyUtil();
private boolean embeddedMode = DeploymentUtil.isEmbeddedMode();
private String currentColo = DeploymentUtil.getCurrentColo();
private BufferedRequest getBufferedRequest(HttpServletRequest request) {
if (request instanceof BufferedRequest) {
return (BufferedRequest) request;
}
return new BufferedRequest(request);
}
@GET
@Path("sla-alert/{type}")
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Monitored(event = "entity-sla-misses")
public SchedulableEntityInstanceResult getEntitySLAMissPendingAlerts(
@Dimension("entityType") @PathParam("type") final String entityType,
@Dimension("entityName") @QueryParam("name") final String entityName,
@Dimension("start") @QueryParam("start") final String start,
@Dimension("end") @QueryParam("end") final String end,
@Dimension("colo") @QueryParam("colo") final String colo) {
try {
validateSlaParams(entityType, entityName, start, end, colo);
} catch (Exception e) {
throw FalconWebException.newAPIException(e);
}
return new EntityProxy<SchedulableEntityInstanceResult>(entityType, entityName,
SchedulableEntityInstanceResult.class) {
@Override
protected Set<String> getColosToApply() {
return getApplicableColos(entityType, entityName);
}
@Override
protected SchedulableEntityInstanceResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("getEntitySLAMissPendingAlerts", entityType,
entityName, start, end, colo);
}
}.execute();
}
/**
* Submit the given entity.
* @param request Servlet Request
* @param type Valid options are cluster, feed or process.
* @param ignore colo is ignored
* @return Result of the submission.
*/
@POST
@Path("submit/{type}")
@Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "submit")
@Override
public APIResult submit(
@Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
@Dimension("colo") @QueryParam("colo") final String ignore) {
final HttpServletRequest bufferedRequest = getBufferedRequest(request);
final Entity entity = getEntity(bufferedRequest, type);
Map<String, APIResult> results = new HashMap<>();
final Set<String> colos = getApplicableColos(type, entity);
entityHasExtensionJobTag(entity);
validateEntity(entity, colos);
results.putAll(entityProxyUtil.proxySubmit(type, bufferedRequest, entity, colos));
if (!embeddedMode) {
results.put(PRISM_TAG, super.submit(bufferedRequest, type, currentColo));
}
return consolidateResult(results, APIResult.class);
}
private void validateEntity(Entity entity, Set<String> applicableColos) {
if (entity.getEntityType() != EntityType.CLUSTER || embeddedMode) {
return;
}
// If the submitted entity is a cluster, ensure its spec. has one of the valid colos
String colo = ((Cluster) entity).getColo();
if (!applicableColos.contains(colo)) {
throw FalconWebException.newAPIException("The colo mentioned in the cluster specification, "
+ colo + ", is not listed in Prism runtime.");
}
}
private Entity getEntity(HttpServletRequest request, String type) {
try {
request.getInputStream().reset();
Entity entity = deserializeEntity(request.getInputStream(), EntityType.getEnum(type));
request.getInputStream().reset();
return entity;
} catch (Exception e) {
throw FalconWebException.newAPIException(e);
}
}
/**
* Validates the submitted entity.
* @param request Servlet Request
* @param type Valid options are cluster, feed or process.
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the validation.
*/
@POST
@Path("validate/{type}")
@Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Override
public APIResult validate(@Context final HttpServletRequest request, @PathParam("type") final String type,
@QueryParam("skipDryRun") final Boolean skipDryRun) {
final HttpServletRequest bufferedRequest = getBufferedRequest(request);
EntityType entityType = EntityType.getEnum(type);
final Entity entity;
try {
entity = deserializeEntity(bufferedRequest.getInputStream(), entityType);
bufferedRequest.getInputStream().reset();
} catch (Exception e) {
throw FalconWebException.newAPIException("Unable to parse entity definition");
}
return new EntityProxy(type, entity.getName()) {
@Override
protected Set<String> getColosToApply() {
return getApplicableColos(type, entity);
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("validate", bufferedRequest, type,
skipDryRun);
}
}.execute();
}
/**
* Delete the specified entity.
* @param request Servlet Request
* @param type Valid options are cluster, feed or process.
* @param entityName Name of the entity.
* @param ignore colo is ignored
* @return Results of the delete operation.
*/
@DELETE
@Path("delete/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "delete")
@Override
public APIResult delete(
@Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entityName,
@Dimension("colo") @QueryParam("colo") String ignore) {
try {
isEntityPartOfAnExtension(EntityUtil.getEntity(type, entityName));
} catch (FalconException e) {
throw FalconWebException.newAPIException(e);
}
final HttpServletRequest bufferedRequest = new BufferedRequest(request);
Map<String, APIResult> results = new HashMap<>();
results.putAll(entityProxyUtil.proxyDelete(type, entityName, bufferedRequest));
// delete only if deleted from everywhere
if (!embeddedMode && results.get(FALCON_TAG).getStatus() == APIResult.Status.SUCCEEDED) {
results.put(PRISM_TAG, super.delete(bufferedRequest, type, entityName, currentColo));
}
return consolidateResult(results, APIResult.class);
}
/**
* Updates the submitted entity.
* @param request Servlet Request
* @param type Valid options are feed or process.
* @param entityName Name of the entity.
* @param ignore colo is ignored
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the validation.
*/
@POST
@Path("update/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "update")
@Override
public APIResult update(
@Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entityName,
@Dimension("colo") @QueryParam("colo") String ignore,
@QueryParam("skipDryRun") final Boolean skipDryRun) {
try {
isEntityPartOfAnExtension(EntityUtil.getEntity(type, entityName));
} catch (FalconException e) {
throw FalconWebException.newAPIException(e);
}
final HttpServletRequest bufferedRequest = new BufferedRequest(request);
Entity newEntity = getEntity(bufferedRequest, type);
entityHasExtensionJobTag(newEntity);
Map<String, APIResult> results = new HashMap<>();
boolean result = true;
results.putAll(entityProxyUtil.proxyUpdate(type, entityName, skipDryRun, bufferedRequest, newEntity));
for (APIResult apiResult : results.values()) {
if (apiResult.getStatus() != APIResult.Status.SUCCEEDED) {
result = false;
}
}
// update only if all are updated
if (!embeddedMode && result) {
results.put(PRISM_TAG, super.update(bufferedRequest, type, entityName, currentColo, skipDryRun));
}
return consolidateResult(results, APIResult.class);
}
private void isEntityPartOfAnExtension(Entity entity) {
String tags = entity.getTags();
checkExtensionJobExist(tags);
}
private void entityHasExtensionJobTag(Entity entity) {
String tags = entity.getTags();
if (StringUtils.isNotBlank(tags)) {
String jobName = AbstractExtensionManager.getJobNameFromTag(tags);
if (StringUtils.isNotBlank(jobName)) {
throw FalconWebException.newAPIException("Entity has extension job name in the tag. Such entities need "
+ "to be submitted as extension jobs:" + jobName);
}
}
}
private void checkExtensionJobExist(String tags) {
if (tags != null) {
String jobName = AbstractExtensionManager.getJobNameFromTag(tags);
ExtensionMetaStore extensionMetaStore = ExtensionStore.getMetaStore();
if (jobName != null && extensionMetaStore.checkIfExtensionJobExists(jobName)) {
throw FalconWebException.newAPIException("Entity operation is not allowed on this entity as it is"
+ "part of an extension job:" + jobName);
}
}
}
/**
* Updates the dependent entities of a cluster in workflow engine.
* @param clusterName Name of cluster.
* @param ignore colo.
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the validation.
*/
@POST
@Path("updateClusterDependents/{clusterName}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "updateClusterDependents")
@Override
public APIResult updateClusterDependents(
@Dimension("entityName") @PathParam("clusterName") final String clusterName,
@Dimension("colo") @QueryParam("colo") String ignore,
@QueryParam("skipDryRun") final Boolean skipDryRun) {
final Set<String> allColos = getApplicableColos("cluster", clusterName);
Map<String, APIResult> results = new HashMap<String, APIResult>();
boolean result = true;
if (!allColos.isEmpty()) {
results.put(FALCON_TAG + "/updateClusterDependents", new EntityProxy("cluster", clusterName) {
@Override
protected Set<String> getColosToApply() {
return allColos;
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getConfigSyncChannel(colo).invoke("updateClusterDependents",
clusterName, colo, skipDryRun);
}
}.execute());
}
for (APIResult apiResult : results.values()) {
if (apiResult.getStatus() != APIResult.Status.SUCCEEDED) {
result = false;
}
}
// update only if all are updated
if (!embeddedMode && result) {
results.put(PRISM_TAG, super.updateClusterDependents(clusterName, currentColo, skipDryRun));
}
return consolidateResult(results, APIResult.class);
}
/**
* Force updates the entity.
* @param type Valid options are feed or process.
* @param entityName Name of the entity.
* @param coloExpr Colo on which the query should be run.
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the validation.
*/
@POST
@Path("touch/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "touch")
@Override
public APIResult touch(
@Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entityName,
@Dimension("colo") @QueryParam("colo") final String coloExpr,
@QueryParam("skipDryRun") final Boolean skipDryRun) {
final Set<String> colosFromExp = getColosFromExpression(coloExpr, type, entityName);
return new EntityProxy(type, entityName) {
@Override
protected Set<String> getColosToApply() {
return colosFromExp;
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("touch", type, entityName, colo, skipDryRun);
}
}.execute();
}
/**
* Get status of the entity.
* @param type Valid options are cluster, feed or process.
* @param entity Name of the entity.
* @param coloExpr Colo on which the query should be run.
* @param showScheduler whether the call should return the scheduler on which the entity is scheduled.
* @return Status of the entity.
*/
@GET
@Path("status/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "status")
@Override
public APIResult getStatus(@Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entity,
@Dimension("colo") @QueryParam("colo") final String coloExpr,
@Dimension("showScheduler") @QueryParam("showScheduler") final Boolean showScheduler) {
return new EntityProxy(type, entity) {
@Override
protected Set<String> getColosToApply() {
return getColosFromExpression(coloExpr, type, entity);
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("getStatus", type, entity, colo,
showScheduler);
}
}.execute();
}
/**
* Get dependencies of the entity.
* @param type Valid options are cluster, feed or process.
* @param entity Name of the entity.
* @return Dependencies of the entity.
*/
@GET
@Path("dependencies/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
@Monitored(event = "dependencies")
@Override
public EntityList getDependencies(@Dimension("entityType") @PathParam("type") String type,
@Dimension("entityName") @PathParam("entity") String entity) {
return super.getDependencies(type, entity);
}
/**
* Get definition of the entity.
* @param type Valid options are cluster, feed or process.
* @param entityName Name of the entity.
* @return Definition of the entity.
*/
@GET
@Path("definition/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Override
public String getEntityDefinition(@PathParam("type") String type, @PathParam("entity") String entityName) {
return super.getEntityDefinition(type, entityName);
}
/**
* Schedule an entity.
* @param request Servlet Request
* @param type Valid options are feed or process.
* @param entity Name of the entity.
* @param coloExpr Colo on which the query should be run.
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the schedule command.
*/
@POST
@Path("schedule/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "schedule")
@Override
public APIResult schedule(@Context final HttpServletRequest request,
@Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entity,
@Dimension("colo") @QueryParam("colo") final String coloExpr,
@QueryParam("skipDryRun") final Boolean skipDryRun,
@QueryParam("properties") final String properties) {
final HttpServletRequest bufferedRequest = getBufferedRequest(request);
return new EntityProxy(type, entity) {
@Override
protected Set<String> getColosToApply() {
return getColosFromExpression(coloExpr, type, entity);
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("schedule", bufferedRequest, type, entity,
colo, skipDryRun, properties);
}
}.execute();
}
/**
* Submits and schedules an entity.
* @param request Servlet Request
* @param type Valid options are feed or process.
* @param coloExpr Colo on which the query should be run.
* @param skipDryRun Optional query param, Falcon skips oozie dryrun when value is set to true.
* @return Result of the submit and schedule command.
*/
@POST
@Path("submitAndSchedule/{type}")
@Consumes({MediaType.TEXT_XML, MediaType.TEXT_PLAIN})
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "submitAndSchedule")
@Override
public APIResult submitAndSchedule(
@Context HttpServletRequest request, @Dimension("entityType") @PathParam("type") String type,
@Dimension("colo") @QueryParam("colo") String coloExpr,
@QueryParam("skipDryRun") Boolean skipDryRun,
@QueryParam("properties") String properties) {
BufferedRequest bufferedRequest = new BufferedRequest(request);
final Entity entity = getEntity(bufferedRequest, type);
String entityName = entity.getName();
entityHasExtensionJobTag(entity);
Map<String, APIResult> results = new HashMap<String, APIResult>();
results.put("submit", submit(bufferedRequest, type, coloExpr));
results.put("schedule", schedule(bufferedRequest, type, entityName, coloExpr, skipDryRun, properties));
return consolidateResult(results, APIResult.class);
}
/**
* Suspend an entity.
* @param request Servlet Requests
* @param type Valid options are feed or process.
* @param entity Name of the entity.
* @param coloExpr Colo on which the query should be run.
* @return Status of the entity.
*/
@POST
@Path("suspend/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "suspend")
@Override
public APIResult suspend(@Context final HttpServletRequest request,
@Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entity,
@Dimension("colo") @QueryParam("colo") final String coloExpr) {
final HttpServletRequest bufferedRequest = new BufferedRequest(request);
return new EntityProxy(type, entity) {
@Override
protected Set<String> getColosToApply() {
return getColosFromExpression(coloExpr, type, entity);
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("suspend", bufferedRequest, type, entity,
colo);
}
}.execute();
}
/**
* Resume a supended entity.
* @param request Servlet Request
* @param type Valid options are feed or process.
* @param entity Name of the entity.
* @param coloExpr Colo on which the query should be run.
* @return Result of the resume command.
*/
@POST
@Path("resume/{type}/{entity}")
@Produces({MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Monitored(event = "resume")
@Override
public APIResult resume(
@Context final HttpServletRequest request, @Dimension("entityType") @PathParam("type") final String type,
@Dimension("entityName") @PathParam("entity") final String entity,
@Dimension("colo") @QueryParam("colo") final String coloExpr) {
final HttpServletRequest bufferedRequest = new BufferedRequest(request);
return new EntityProxy(type, entity) {
@Override
protected Set<String> getColosToApply() {
return getColosFromExpression(coloExpr, type, entity);
}
@Override
protected APIResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("resume", bufferedRequest, type, entity,
colo);
}
}.execute();
}
//SUSPEND CHECKSTYLE CHECK ParameterNumberCheck
/**
*
* Get list of the entities.
* We have two filtering parameters for entity tags: "tags" and "tagkeys".
* "tags" does the exact match in key=value fashion, while "tagkeys" finds all the entities with the given key as a
* substring in the tags. This "tagkeys" filter is introduced for the user who doesn't remember the exact tag but
* some keywords in the tag. It also helps users to save the time of typing long tags.
* The returned entities will match all the filtering criteria.
* @param type Comma-separated entity types. Can be empty. Valid entity types are cluster, feed or process.
* @param fields <optional param> Fields of entity that the user wants to view, separated by commas.
* Valid options are STATUS, TAGS, PIPELINES, CLUSTERS.
* @param nameSubsequence <optional param> Subsequence of entity name. Not case sensitive.
* The entity name needs to contain all the characters in the subsequence in the same order.
* Example 1: "sample1" will match the entity named "SampleFeed1-2".
* Example 2: "mhs" will match the entity named "New-My-Hourly-Summary".
* @param tagKeywords <optional param> Keywords in tags, separated by comma. Not case sensitive.
* The returned entities will have tags that match all the tag keywords.
* @param tags <optional param> Return list of entities that have specified tags, separated by a comma.
* Query will do AND on tag values.
* Example: tags=consumer=consumer@xyz.com,owner=producer@xyz.com
* @param filterBy <optional param> Filter results by list of field:value pairs.
* Example: filterBy=STATUS:RUNNING,PIPELINES:clickLogs
* Supported filter fields are NAME, STATUS, PIPELINES, CLUSTER.
* Query will do an AND among filterBy fields.
* @param orderBy <optional param> Field by which results should be ordered.
* Supports ordering by "name".
* @param sortOrder <optional param> Valid options are "asc" and "desc"
* @param offset <optional param> Show results from the offset, used for pagination. Defaults to 0.
* @param resultsPerPage <optional param> Number of results to show per request, used for pagination. Only
* integers > 0 are valid, Default is 10.
* @return Total number of results and a list of entities.
*/
@GET
@Path("list{type : (/[^/]+)?}")
@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
@Monitored(event = "list")
@Override
public EntityList getEntityList(@PathParam("type") String type,
@DefaultValue("") @QueryParam("fields") String fields,
@DefaultValue("") @QueryParam("nameseq") String nameSubsequence,
@DefaultValue("") @QueryParam("tagkeys") String tagKeywords,
@DefaultValue("") @QueryParam("tags") String tags,
@DefaultValue("") @QueryParam("filterBy") String filterBy,
@DefaultValue("") @QueryParam("orderBy") String orderBy,
@DefaultValue("asc") @QueryParam("sortOrder") String sortOrder,
@DefaultValue("0") @QueryParam("offset") Integer offset,
@QueryParam("numResults") Integer resultsPerPage,
@QueryParam("doAs") String doAsUser) {
if (StringUtils.isNotEmpty(type)) {
type = type.substring(1);
}
resultsPerPage = resultsPerPage == null ? getDefaultResultsPerPage() : resultsPerPage;
return super.getEntityList(fields, nameSubsequence, tagKeywords, type, tags, filterBy,
orderBy, sortOrder, offset, resultsPerPage, doAsUser);
}
/**
* Given an EntityType and cluster, get list of entities along with summary of N recent instances of each entity.
* @param type Valid options are feed or process.
* @param clusterName Show entities that belong to this cluster.
* @param startStr <optional param> Show entity summaries from this date. Date format is yyyy-MM-dd'T'HH:mm'Z'.
* By default, it is set to (end - 2 days).
* @param endStr <optional param> Show entity summary up to this date. Date format is yyyy-MM-dd'T'HH:mm'Z'.
* Default is set to now.
* @param entityFields <optional param> Fields of entity that the user wants to view, separated by commas.
* Valid options are STATUS, TAGS, PIPELINES.
* @param entityFilter <optional param> Filter results by list of field:value pairs.
* Example: filterBy=STATUS:RUNNING,PIPELINES:clickLogs
* Supported filter fields are NAME, STATUS, PIPELINES, CLUSTER.
* Query will do an AND among filterBy fields.
* @param entityTags <optional param> Return list of entities that have specified tags, separated by a comma.
* Query will do AND on tag values.
* Example: tags=consumer=consumer@xyz.com,owner=producer@xyz.com
* @param entityOrderBy <optional param> Field by which results should be ordered.
* Supports ordering by "name".
* @param entitySortOrder <optional param> Valid options are "asc" and "desc"
* @param entityOffset <optional param> Show results from the offset, used for pagination. Defaults to 0.
* @param numEntities <optional param> Number of results to show per request, used for pagination. Only
* integers > 0 are valid, Default is 10.
* @param numInstanceResults <optional param> Number of recent instances to show per entity. Only integers > 0 are
* valid, Default is 7.
* @return Show entities along with summary of N instances for each entity.
*/
@GET
@Path("summary/{type}")
@Produces({MediaType.TEXT_XML, MediaType.APPLICATION_JSON})
@Monitored(event = "summary")
@Override
public EntitySummaryResult getEntitySummary(
@Dimension("type") @PathParam("type") final String type,
@Dimension("cluster") @QueryParam("cluster") final String clusterName,
@DefaultValue("") @QueryParam("start") final String startStr,
@DefaultValue("") @QueryParam("end") final String endStr,
@DefaultValue("") @QueryParam("fields") final String entityFields,
@DefaultValue("") @QueryParam("filterBy") final String entityFilter,
@DefaultValue("") @QueryParam("tags") final String entityTags,
@DefaultValue("") @QueryParam("orderBy") final String entityOrderBy,
@DefaultValue("asc") @QueryParam("sortOrder") final String entitySortOrder,
@DefaultValue("0") @QueryParam("offset") final Integer entityOffset,
@DefaultValue("10") @QueryParam("numResults") final Integer numEntities,
@DefaultValue("7") @QueryParam("numInstances") final Integer numInstanceResults,
@DefaultValue("") @QueryParam("doAs") final String doAsUser) {
final String entityName = null;
return new EntityProxy<EntitySummaryResult>(type, null, EntitySummaryResult.class) {
@Override
protected Set<String> getColosToApply() {
Set<String> result = new HashSet<>();
try {
Cluster cluster = EntityUtil.getEntity(EntityType.CLUSTER, clusterName);
result.add(cluster.getColo());
} catch (FalconException e) {
// ignore, just return blank result
}
return result;
}
@Override
protected EntitySummaryResult doExecute(String colo) throws FalconException {
EntitySummaryResult es = entityProxyUtil.getEntityManager(colo).invoke("getEntitySummary", type,
clusterName, startStr, endStr, entityFields, entityFilter, entityTags, entityOrderBy,
entitySortOrder, entityOffset, numEntities, numInstanceResults, doAsUser);
return es;
}
}.execute();
}
/**
* Get the name of the feed along with the location type(meta/data/stats) and cluster on which the given path
* belongs to this feed.
* @param type Valid option is feed.
* @param path path of the instance for which you want to determine the feed
* Example: /data/project1/2014/10/10/23/ Path has to be the complete path and can't be a part of it.
* @return Returns the name of the feed along with the location type(meta/data/stats) and cluster on which the given
* path belongs to this feed.
*/
@GET
@Path("lookup/{type}")
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@Monitored(event = "reverse-lookup")
public FeedLookupResult reverseLookup(
@Dimension("type") @PathParam("type") final String type,
@Dimension("path") @QueryParam("path") final String path) {
String entity = "DummyEntity"; // A dummy entity name to get around
return new EntityProxy<FeedLookupResult>(type, entity, FeedLookupResult.class) {
@Override
protected Set<String> getColosToApply() {
return getAllColos();
}
@Override
protected FeedLookupResult doExecute(String colo) throws FalconException {
return entityProxyUtil.getEntityManager(colo).invoke("reverseLookup", type, path);
}
}.execute();
}
//RESUME CHECKSTYLE CHECK ParameterNumberCheck
}