use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method getServiceAvailability.
/**
* Return the availability (i.e. discoverable registration) status of a service.
*/
@GET
@Path("/apps/{app-name}/versions/{app-version}/{service-type}/{program-name}/available")
public void getServiceAvailability(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId, @PathParam("app-name") String appName, @PathParam("app-version") String appVersion, @PathParam("service-type") String serviceType, @PathParam("program-name") String programName) throws Exception {
// Currently we only support services and sparks as the service-type
ProgramType programType = ProgramType.valueOfCategoryName(serviceType);
if (!ServiceDiscoverable.getUserServiceTypes().contains(programType)) {
throw new BadRequestException("Only service or spark is support for service availability check");
}
ProgramId programId = new ProgramId(new ApplicationId(namespaceId, appName, appVersion), programType, programName);
ProgramStatus status = lifecycleService.getProgramStatus(programId);
if (status == ProgramStatus.STOPPED) {
throw new ServiceUnavailableException(programId.toString(), "Service is stopped. Please start it.");
}
// Construct discoverable name and return 200 OK if discoverable is present. If not return 503.
String discoverableName = ServiceDiscoverable.getName(programId);
// TODO: CDAP-12959 - Should use the UserServiceEndpointStrategy and discover based on the version
// and have appVersion nullable for the non versioned endpoint
EndpointStrategy endpointStrategy = new RandomEndpointStrategy(discoveryServiceClient.discover(discoverableName));
if (endpointStrategy.pick(300L, TimeUnit.MILLISECONDS) == null) {
LOG.trace("Discoverable endpoint {} not found", discoverableName);
throw new ServiceUnavailableException(programId.toString(), "Service is running but not accepting requests at this time.");
}
responder.sendString(HttpResponseStatus.OK, "Service is available to accept requests.");
}
use of co.cask.cdap.proto.ProgramStatus in project cdap by caskdata.
the class ProgramLifecycleHttpHandler method deleteQueues.
@DELETE
@Path("/queues")
public synchronized void deleteQueues(HttpRequest request, HttpResponder responder, @PathParam("namespace-id") String namespaceId) throws NamespaceNotFoundException {
// synchronized to avoid a potential race condition here:
// 1. the check for state returns that all flows are STOPPED
// 2. The API deletes queues because
// Between 1. and 2., a flow is started using the /namespaces/{namespace-id}/apps/{app-id}/flows/{flow-id}/start API
// Averting this race condition by synchronizing this method. The resource that needs to be locked here is
// runtimeService. This should work because the method that is used to start a flow - startStopProgram - is also
// synchronized on this.
// This synchronization works in HA mode because even in HA mode there is only one leader at a time.
NamespaceId namespace = validateAndGetNamespace(namespaceId);
try {
List<ProgramRecord> flows = lifecycleService.list(validateAndGetNamespace(namespaceId), ProgramType.FLOW);
for (ProgramRecord flow : flows) {
String appId = flow.getApp();
String flowId = flow.getName();
ProgramId programId = new ProgramId(namespaceId, appId, ProgramType.FLOW, flowId);
ProgramStatus status = lifecycleService.getProgramStatus(programId);
if (ProgramStatus.STOPPED != status) {
responder.sendString(HttpResponseStatus.FORBIDDEN, String.format("Flow '%s' from application '%s' in namespace '%s' is running, " + "please stop it first.", flowId, appId, namespaceId));
return;
}
}
queueAdmin.dropAllInNamespace(namespace);
// delete process metrics that are used to calculate the queue size (system.queue.pending metric)
FlowUtils.deleteFlowPendingMetrics(metricStore, namespaceId, null, null);
responder.sendStatus(HttpResponseStatus.OK);
} catch (Exception e) {
LOG.error("Error while deleting queues in namespace " + namespace, e);
responder.sendString(HttpResponseStatus.INTERNAL_SERVER_ERROR, e.getMessage());
}
}
Aggregations