/**
* Copyright 2015 StreamSets Inc.
*
* Licensed under 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 com.streamsets.datacollector.restapi;
import com.streamsets.datacollector.execution.AclManager;
import com.streamsets.datacollector.execution.Manager;
import com.streamsets.datacollector.execution.PipelineState;
import com.streamsets.datacollector.execution.PipelineStatus;
import com.streamsets.datacollector.execution.Runner;
import com.streamsets.datacollector.execution.SnapshotInfo;
import com.streamsets.datacollector.execution.alerts.AlertInfo;
import com.streamsets.datacollector.main.RuntimeInfo;
import com.streamsets.datacollector.main.UserGroupManager;
import com.streamsets.datacollector.restapi.bean.AlertInfoJson;
import com.streamsets.datacollector.restapi.bean.BeanHelper;
import com.streamsets.datacollector.restapi.bean.ErrorMessageJson;
import com.streamsets.datacollector.restapi.bean.MetricRegistryJson;
import com.streamsets.datacollector.restapi.bean.MultiStatusResponseJson;
import com.streamsets.datacollector.restapi.bean.PipelineStateJson;
import com.streamsets.datacollector.restapi.bean.RecordJson;
import com.streamsets.datacollector.restapi.bean.SampledRecordJson;
import com.streamsets.datacollector.restapi.bean.SnapshotDataJson;
import com.streamsets.datacollector.restapi.bean.SnapshotInfoJson;
import com.streamsets.datacollector.restapi.bean.UserJson;
import com.streamsets.datacollector.runner.PipelineRuntimeException;
import com.streamsets.datacollector.store.AclStoreTask;
import com.streamsets.datacollector.store.PipelineInfo;
import com.streamsets.datacollector.store.PipelineStoreTask;
import com.streamsets.datacollector.util.AuthzRole;
import com.streamsets.datacollector.util.ContainerError;
import com.streamsets.datacollector.util.PipelineException;
import com.streamsets.lib.security.http.SSOPrincipal;
import com.streamsets.pipeline.api.ExecutionMode;
import com.streamsets.pipeline.api.StageException;
import com.streamsets.pipeline.api.impl.Utils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.Authorization;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.inject.Inject;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
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 javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Path("/v1")
@Api(value = "manager")
@DenyAll
public class ManagerResource {
private final String user;
private final Manager manager;
private final PipelineStoreTask store;
private static final Logger LOG = LoggerFactory.getLogger(ManagerResource.class);
@Inject
public ManagerResource(
Manager manager,
Principal principal,
PipelineStoreTask store,
AclStoreTask aclStore,
RuntimeInfo runtimeInfo,
UserGroupManager userGroupManager
) {
this.user = principal.getName();
this.store = store;
UserJson currentUser;
if (runtimeInfo.isDPMEnabled()) {
currentUser = new UserJson((SSOPrincipal)principal);
} else {
currentUser = userGroupManager.getUser(principal);
}
if (runtimeInfo.isAclEnabled()) {
this.manager = new AclManager(manager, aclStore, currentUser);
} else {
this.manager = manager;
}
}
@Path("/pipelines/status")
@GET
@ApiOperation(value = "Returns all Pipeline Status", response = PipelineStateJson.class,
responseContainer = "Map", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
public Response getAllPipelineStatus() throws PipelineException {
RestAPIUtils.injectPipelineInMDC("*");
List<PipelineState> pipelineStateList = manager.getPipelines();
Map<String, PipelineStateJson> pipelineStateMap = new HashMap<>();
for(PipelineState pipelineState: pipelineStateList) {
pipelineStateMap.put(pipelineState.getPipelineId(), BeanHelper.wrapPipelineState(pipelineState, true));
}
return Response.ok().type(MediaType.APPLICATION_JSON).entity(pipelineStateMap).build();
}
@Path("/pipeline/{pipelineId}/status")
@GET
@ApiOperation(value = "Returns Pipeline Status for the given pipeline", response = PipelineStateJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
public Response getPipelineStatus(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if(pipelineId != null) {
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok()
.type(MediaType.APPLICATION_JSON)
.entity(BeanHelper.wrapPipelineState(runner.getState())).build();
}
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/start")
@POST
@ApiOperation(value = "Start Pipeline", response = PipelineStateJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response startPipeline(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@ApiParam(
name = "runtimeParameters",
value = "Runtime Parameters to override Pipeline Parameters value"
) Map<String, Object> runtimeParameters
) throws StageException, PipelineException {
if(pipelineId != null) {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, rev)) {
throw new PipelineException(ContainerError.CONTAINER_01101, "START_PIPELINE", pipelineId);
}
try {
Runner runner = manager.getRunner(pipelineId, rev);
Utils.checkState(runner.getState().getExecutionMode() != ExecutionMode.SLAVE,
"This operation is not supported in SLAVE mode");
if (runtimeParameters != null && !runtimeParameters.isEmpty()) {
Utils.checkState(runner.getState().getExecutionMode() == ExecutionMode.STANDALONE,
Utils.format("Using runtime constants is not supported in {} mode", runner.getState().getExecutionMode()));
runner.start(user, runtimeParameters);
} else {
runner.start(user);
}
return Response.ok()
.type(MediaType.APPLICATION_JSON)
.entity(BeanHelper.wrapPipelineState(runner.getState())).build();
} catch (PipelineRuntimeException ex) {
if (ex.getErrorCode() == ContainerError.CONTAINER_0165) {
return Response.status(Response.Status.BAD_REQUEST).type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapIssues(ex.getIssues())).build();
} else {
throw ex;
}
}
}
return Response.noContent().build();
}
@Path("/pipelines/start")
@POST
@ApiOperation(value = "Start multiple Pipelines", response = MultiStatusResponseJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response startPipelines(List<String> pipelineIds) throws StageException, PipelineException {
List<PipelineState> successEntities = new ArrayList<>();
List<String> errorMessages = new ArrayList<>();
for (String pipelineId: pipelineIds) {
if (pipelineId != null) {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, "0")) {
errorMessages.add("Cannot start a remote pipeline: " + pipelineId);
continue;
}
Runner runner = manager.getRunner( pipelineId, "0");
try {
Utils.checkState(runner.getState().getExecutionMode() != ExecutionMode.SLAVE,
"This operation is not supported in SLAVE mode");
runner.start(user);
successEntities.add(runner.getState());
} catch (Exception ex) {
errorMessages.add("Failed starting pipeline: " + pipelineId + ". Error: " + ex.getMessage());
}
}
}
return Response.status(207)
.type(MediaType.APPLICATION_JSON)
.entity(new MultiStatusResponseJson<>(successEntities, errorMessages)).build();
}
@Path("/pipeline/{pipelineId}/stop")
@POST
@ApiOperation(value = "Stop Pipeline", response = PipelineStateJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response stopPipeline(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@Context SecurityContext context
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, rev) && !context.isUserInRole(AuthzRole.ADMIN) &&
!context.isUserInRole(AuthzRole.ADMIN_REMOTE)) {
throw new PipelineException(ContainerError.CONTAINER_01101, "STOP_PIPELINE", pipelineId);
}
Runner runner = manager.getRunner(pipelineId, rev);
Utils.checkState(runner.getState().getExecutionMode() != ExecutionMode.SLAVE,
"This operation is not supported in SLAVE mode");
runner.stop(user);
return Response.ok()
.type(MediaType.APPLICATION_JSON)
.entity(BeanHelper.wrapPipelineState(runner.getState())).build();
}
@Path("/pipelines/stop")
@POST
@ApiOperation(value = "Stop multiple Pipelines", response = MultiStatusResponseJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response stopPipelines(
List<String> pipelineIds,
@Context SecurityContext context
) throws StageException, PipelineException {
List<PipelineState> successEntities = new ArrayList<>();
List<String> errorMessages = new ArrayList<>();
for (String pipelineId: pipelineIds) {
if (pipelineId != null) {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, "0") && !context.isUserInRole(AuthzRole.ADMIN) &&
!context.isUserInRole(AuthzRole.ADMIN_REMOTE)) {
errorMessages.add("Cannot stop a remote pipeline: " + pipelineId);
continue;
}
Runner runner = manager.getRunner(pipelineId, "0");
try {
Utils.checkState(runner.getState().getExecutionMode() != ExecutionMode.SLAVE,
"This operation is not supported in SLAVE mode");
runner.stop(user);
successEntities.add(runner.getState());
} catch (Exception ex) {
errorMessages.add("Failed stopping pipeline: " + pipelineId + ". Error: " + ex.getMessage());
}
}
}
return Response.status(207)
.type(MediaType.APPLICATION_JSON)
.entity(new MultiStatusResponseJson<>(successEntities, errorMessages)).build();
}
@Path("/pipeline/{pipelineId}/forceStop")
@POST
@ApiOperation(value = "Force Stop Pipeline", response = PipelineStateJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response forceStopPipeline(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@Context SecurityContext context) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, rev)) {
if (!context.isUserInRole(AuthzRole.ADMIN) && !context.isUserInRole(AuthzRole.ADMIN_REMOTE)) {
throw new PipelineException(ContainerError.CONTAINER_01101, "FORCE_QUIT_PIPELINE", pipelineId);
}
}
Runner runner = manager.getRunner(pipelineId, rev);
Utils.checkState(runner.getState().getExecutionMode() == ExecutionMode.STANDALONE,
Utils.format("This operation is not supported in {} mode", runner.getState().getExecutionMode()));
runner.forceQuit(user);
return Response.ok()
.type(MediaType.APPLICATION_JSON)
.entity(BeanHelper.wrapPipelineState(runner.getState())).build();
}
@Path("/pipelines/forceStop")
@POST
@ApiOperation(value = "Force Stop multiple Pipelines", response = MultiStatusResponseJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response forceStopPipelines(List<String> pipelineIds, @Context SecurityContext context) throws PipelineException {
List<PipelineState> successEntities = new ArrayList<>();
List<String> errorMessages = new ArrayList<>();
for (String pipelineId: pipelineIds) {
if (pipelineId != null) {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, "0")) {
if (!context.isUserInRole(AuthzRole.ADMIN) && !context.isUserInRole(AuthzRole.ADMIN_REMOTE)) {
errorMessages.add("Cannot force stop a remote pipeline: " + pipelineId);
continue;
}
}
Runner runner = manager.getRunner(pipelineId, "0");
try {
Utils.checkState(runner.getState().getExecutionMode() == ExecutionMode.STANDALONE,
Utils.format("This operation is not supported in {} mode", runner.getState().getExecutionMode()));
runner.forceQuit(user);
successEntities.add(runner.getState());
} catch (Exception ex) {
errorMessages.add("Failed to force stop pipeline: " + pipelineId + ". Error: " + ex.getMessage());
}
}
}
return Response.status(207)
.type(MediaType.APPLICATION_JSON)
.entity(new MultiStatusResponseJson<>(successEntities, errorMessages)).build();
}
@Path("/pipeline/{pipelineId}/committedOffsets")
@GET
@ApiOperation(value = "Return Committed Offsets. Note: Returned offset format will change between releases.",
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getCommittedOffsets(
@PathParam("pipelineId") String name,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(name);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(name, rev);
return Response.ok(runner.getCommittedOffsets()).build();
}
@Path("/pipeline/{pipelineId}/resetOffset")
@POST
@ApiOperation(value = "Reset Origin Offset", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response resetOffset(
@PathParam("pipelineId") String name,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(name);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(name, rev)) {
throw new PipelineException(ContainerError.CONTAINER_01101, "RESET_OFFSET", name);
}
Runner runner = manager.getRunner(name, rev);
runner.resetOffset("user");
return Response.ok().build();
}
@Path("/pipelines/resetOffsets")
@POST
@ApiOperation(value = "Reset Origin Offset for multiple pipelines", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response resetOffsets(List<String> pipelineIds) throws PipelineException {
for (String pipelineId: pipelineIds) {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, "0")) {
throw new PipelineException(ContainerError.CONTAINER_01101, "RESET_OFFSETS", pipelineId);
}
Runner runner = manager.getRunner(pipelineId, "0");
runner.resetOffset(user);
}
return Response.ok().build();
}
@Path("/pipeline/{pipelineId}/metrics")
@GET
@ApiOperation(value = "Return Pipeline Metrics", response = MetricRegistryJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
public Response getMetrics(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if(pipelineId != null) {
Runner runner = manager.getRunner(pipelineId, rev);
if (runner != null && runner.getState().getStatus().isActive()) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(runner.getMetrics()).build();
}
if (runner != null) {
LOG.debug("Status is " + runner.getState().getStatus());
} else {
LOG.debug("Runner is null");
}
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/snapshot/{snapshotName}")
@PUT
@ApiOperation(value = "Capture Snapshot", authorizations = @Authorization(value = "basic"))
@RolesAllowed({ AuthzRole.MANAGER, AuthzRole.ADMIN, AuthzRole.MANAGER_REMOTE, AuthzRole.ADMIN_REMOTE })
public Response captureSnapshot(
@PathParam("pipelineId") String pipelineId,
@PathParam("snapshotName") String snapshotName,
@QueryParam("snapshotLabel") String snapshotLabel,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam("batches") @DefaultValue("1") int batches,
@QueryParam("batchSize") @DefaultValue("10") int batchSize,
@QueryParam("startPipeline") @DefaultValue("false") boolean startPipeline,
Map<String, Object> runtimeParameters
) throws PipelineException, StageException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
if (startPipeline && runner != null) {
runner.startAndCaptureSnapshot(user, runtimeParameters, snapshotName, snapshotLabel, batches, batchSize);
} else {
Utils.checkState(runner != null && runner.getState().getStatus() == PipelineStatus.RUNNING,
"Pipeline doesn't exist or it is not running currently");
runner.captureSnapshot(user, snapshotName, snapshotLabel, batches, batchSize);
}
return Response.ok().build();
}
@Path("/pipeline/{pipelineId}/snapshot/{snapshotName}")
@POST
@ApiOperation(value = "Update Snapshot Label", authorizations = @Authorization(value = "basic"))
@RolesAllowed({ AuthzRole.MANAGER, AuthzRole.ADMIN, AuthzRole.MANAGER_REMOTE, AuthzRole.ADMIN_REMOTE })
public Response updateSnapshotLabel(
@PathParam("pipelineId") String pipelineId,
@PathParam("snapshotName") String snapshotName,
@QueryParam("snapshotLabel") String snapshotLabel,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
runner.updateSnapshotLabel(snapshotName, snapshotLabel);
return Response.ok().build();
}
@Path("/pipelines/snapshots")
@GET
@ApiOperation(value = "Returns all Snapshot Info", response = SnapshotInfoJson.class, responseContainer = "List",
authorizations = @Authorization(value = "basic"))
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.CREATOR,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.CREATOR_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getAllSnapshotsInfo() throws PipelineException {
RestAPIUtils.injectPipelineInMDC("*");
List<SnapshotInfo> snapshotInfoList = new ArrayList<>();
for(PipelineState pipelineState: manager.getPipelines()) {
Runner runner = manager.getRunner(pipelineState.getPipelineId(), pipelineState.getRev());
if(runner != null) {
snapshotInfoList.addAll(runner.getSnapshotsInfo());
}
}
return Response.ok().type(MediaType.APPLICATION_JSON).entity(BeanHelper.wrapSnapshotInfoNewAPI(
snapshotInfoList)).build();
}
@Path("/pipeline/{pipelineId}/snapshots")
@GET
@ApiOperation(value = "Returns Snapshot Info for the given pipeline", response = SnapshotInfoJson.class,
responseContainer = "List", authorizations = @Authorization(value = "basic"))
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.CREATOR,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.CREATOR_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getSnapshotsInfo(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(BeanHelper.wrapSnapshotInfoNewAPI(
runner.getSnapshotsInfo())).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/snapshot/{snapshotName}/status")
@GET
@ApiOperation(value = "Return Snapshot status", response = SnapshotInfoJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getSnapshotStatus(
@PathParam("pipelineId") String pipelineId,
@PathParam("snapshotName") String snapshotName,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapSnapshotInfoNewAPI(runner.getSnapshot(snapshotName).getInfo())).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/snapshot/{snapshotName}")
@GET
@ApiOperation(value = "Return Snapshot data", response = SnapshotDataJson.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.CREATOR,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.CREATOR_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getSnapshot(
@PathParam("pipelineId") String pipelineId,
@PathParam("snapshotName") String snapshotName,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(runner.getSnapshot(snapshotName).getOutput()).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/snapshot/{snapshotName}")
@DELETE
@ApiOperation(value = "Delete Snapshot data", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response deleteSnapshot(
@PathParam("pipelineId") String pipelineId,
@PathParam("snapshotName") String snapshotName,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
runner.deleteSnapshot(snapshotName);
}
return Response.ok().build();
}
@Path("/pipeline/{pipelineId}/history")
@DELETE
@ApiOperation(value = "Delete history by pipeline name", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response deleteHistory(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
if (manager.isRemotePipeline(pipelineId, rev)) {
throw new PipelineException(ContainerError.CONTAINER_01101, "DELETE_HISTORY", pipelineId);
}
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
runner.deleteHistory();
}
return Response.ok().build();
}
@Path("/pipeline/{pipelineId}/errorRecords")
@GET
@ApiOperation(value = "Returns error records by stage instance name and size", response = RecordJson.class,
responseContainer = "List", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getErrorRecords(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam ("stageInstanceName") @DefaultValue("") String stageInstanceName,
@QueryParam ("size") @DefaultValue("10") int size
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
size = size > 100 ? 100 : size;
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapRecords(runner.getErrorRecords(stageInstanceName, size))).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/errorMessages")
@GET
@ApiOperation(value = "Returns error messages by stage instance name and size", response = ErrorMessageJson.class,
responseContainer = "List", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getErrorMessages(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam ("stageInstanceName") @DefaultValue("") String stageInstanceName,
@QueryParam ("size") @DefaultValue("10") int size
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
size = size > 100 ? 100 : size;
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapErrorMessages(runner.getErrorMessages(stageInstanceName, size))).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/history")
@GET
@ApiOperation(value = "Find history by pipeline name", response = PipelineStateJson.class, responseContainer = "List",
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@PermitAll
public Response getHistory(
@PathParam("pipelineId") String name,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam("fromBeginning") @DefaultValue("false") boolean fromBeginning) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(name);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
Runner runner = manager.getRunner(name, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapPipelineStatesNewAPI(runner.getHistory(), false)).build();
}
return Response.noContent().build();
}
@Path("/pipeline/{pipelineId}/sampledRecords")
@GET
@ApiOperation(value = "Returns Sampled records by sample ID and size", response = SampledRecordJson.class,
responseContainer = "List", authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response getSampledRecords(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam ("sampleId") String sampleId,
@QueryParam ("sampleSize") @DefaultValue("10") int sampleSize
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
sampleSize = sampleSize > 100 ? 100 : sampleSize;
Runner runner = manager.getRunner(pipelineId, rev);
if(runner != null) {
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
BeanHelper.wrapSampledRecords(runner.getSampledRecords(sampleId, sampleSize))).build();
}
return Response.noContent().build();
}
@Path("/pipelines/alerts")
@GET
@ApiOperation(value = "Returns alerts triggered for all pipelines", response = AlertInfoJson.class,
responseContainer = "List", authorizations = @Authorization(value = "basic"))
@PermitAll
public Response getAllAlerts()
throws PipelineException {
RestAPIUtils.injectPipelineInMDC("*");
List<AlertInfo> alertInfoList = new ArrayList<>();
if (store.getPipelines().size() < 100) {
// get alerts for all pipelines only if number of pipelines is less than 100
for(PipelineState pipelineState: manager.getPipelines()) {
Runner runner = manager.getRunner(pipelineState.getPipelineId(), pipelineState.getRev());
if(runner != null && runner.getState().getStatus().isActive()) {
alertInfoList.addAll(runner.getAlerts());
}
}
}
return Response.ok().type(MediaType.APPLICATION_JSON).entity(BeanHelper.wrapAlertInfoList(
alertInfoList)).build();
}
@Path("/pipeline/{pipelineId}/alerts")
@DELETE
@ApiOperation(value = "Delete alert by Pipeline name, revision and Alert ID", response = Boolean.class,
authorizations = @Authorization(value = "basic"))
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed({
AuthzRole.MANAGER,
AuthzRole.ADMIN,
AuthzRole.MANAGER_REMOTE,
AuthzRole.ADMIN_REMOTE
})
public Response deleteAlert(
@PathParam("pipelineId") String pipelineId,
@QueryParam("rev") @DefaultValue("0") String rev,
@QueryParam("alertId") String alertId
) throws PipelineException {
PipelineInfo pipelineInfo = store.getInfo(pipelineId);
RestAPIUtils.injectPipelineInMDC(pipelineInfo.getTitle(), pipelineInfo.getPipelineId());
return Response.ok().type(MediaType.APPLICATION_JSON).entity(
manager.getRunner(pipelineId, rev).deleteAlert(alertId)).build();
}
}