package org.cad.interruptus.rest; import com.espertech.esper.client.EPStatementState; import com.wordnik.swagger.annotations.Api; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam; import com.wordnik.swagger.annotations.ApiResponse; import com.wordnik.swagger.annotations.ApiResponses; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.inject.Inject; import javax.inject.Singleton; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; 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.core.MediaType; import javax.ws.rs.core.Response; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.cad.interruptus.core.EntityNotFoundException; import org.cad.interruptus.core.esper.StatementConfiguration; import org.cad.interruptus.entity.Statement; import org.cad.interruptus.repository.StatementRepository; import org.cad.interruptus.repository.zookeeper.listener.ConfigurationEventDispatcher; @Singleton @Path("/statement") @Produces({MediaType.APPLICATION_JSON}) @Consumes({MediaType.APPLICATION_JSON}) @Api(value = "/statement", description = "Statement operations") public class StatementResource { @Inject StatementRepository repository; @Inject StatementConfiguration configuration; @Inject ConfigurationEventDispatcher dispatcher; Log logger = LogFactory.getLog(getClass()); @GET @ApiOperation( value = "List all statements", notes = "List all statements, whether is runnig or not", response = Statement.class, responseContainer = "List" ) public List<Statement> list() { try { return repository.findAll(); } catch (Exception ex) { logger.error(this, ex); throw new ResourceException(Response.Status.SERVICE_UNAVAILABLE, ex.getMessage()); } } @POST @ApiOperation( value = "Save a statement configuration", notes = "Save a statement configuration, if the statement already exists will be overwritten", response = Boolean.class ) public Boolean save(Statement entity) { try { configuration.save(entity); repository.save(entity); dispatcher.dispatchSave(entity); return Boolean.TRUE; } catch (Exception ex) { logger.error(this, ex); throw new ResourceException(Response.Status.SERVICE_UNAVAILABLE, ex.getMessage()); } } @GET @Path("/{name}") @ApiOperation( value = "Retreives a statement configuration", notes = "Retreives a statement configuration, throws exception if does not exists", response = Statement.class ) @ApiResponses({ @ApiResponse(code = 404, message = "Flow doesn't exists") }) public Statement show(@ApiParam(value = "Flow name to lookup for", required = true) @PathParam("name") String name) { try { return repository.findById(name); } catch (EntityNotFoundException ex) { throw new ResourceException(ex); } catch (Exception ex) { logger.error(this, ex); throw new ResourceException(Response.Status.SERVICE_UNAVAILABLE, ex.getMessage()); } } @DELETE @Path("/{name}") @ApiOperation( value = "Removes a statement configuration", notes = "Removes a statement configuration, throws exception if does not exists", response = Statement.class ) @ApiResponses({ @ApiResponse(code = 404, message = "Flow doesn't exists") }) public Boolean remove(@ApiParam(value = "Flow name to lookup for", required = true) @PathParam("name") String name) { try { final Statement entity = repository.findById(name); configuration.stop(name); repository.remove(name); dispatcher.dispatchDelete(entity); return true; } catch (EntityNotFoundException ex) { throw new ResourceException(ex); } catch (Exception ex) { logger.error(this, ex); throw new ResourceException(Response.Status.SERVICE_UNAVAILABLE, ex.getMessage()); } } @POST @Path("/{name}/start") @ApiOperation( value = "Start a statement in esper", notes = "Stop a existing in esper, throws exception if does not exists", response = Statement.class ) @ApiResponses({ @ApiResponse(code = 404, message = "Flow doesn't exists") }) public Boolean startStatement(@ApiParam(value = "Flow name to lookup for", required = true) @PathParam("name") String name) throws Exception { final Statement entity = repository.findById(name); entity.setStarted(true); dispatcher.dispatchSave(entity); repository.save(entity); return true; } @POST @Path("/{name}/stop") @ApiOperation( value = "Stop a statement in esper", notes = "Stop a existing statement in esper, throws exception if does not exists", response = Statement.class ) @ApiResponses({ @ApiResponse(code = 404, message = "Flow doesn't exists") }) public Boolean stopStatement(@ApiParam(value = "Flow name to lookup for", required = true) @PathParam("name") String name) throws Exception { final Statement entity = repository.findById(name); if ( ! configuration.stop(name)) { return false; } entity.setStarted(false); repository.save(entity); dispatcher.dispatchSave(entity); return true; } @GET @Path("/{name}/state") @ApiOperation( value = "Retrives the state for a statement", notes = "Retrives the state for a statement, throws exception if does not exists", response = Statement.class ) @ApiResponses({ @ApiResponse(code = 404, message = "Flow doesn't exists") }) public Map<String, String> getStatementState(@ApiParam(value = "Flow name to lookup for", required = true) @PathParam("name") String name) throws Exception { final Map<String, String> map = new HashMap<>(); final EPStatementState state = configuration.getStatementState(name); map.put("name", name); map.put("status", EPStatementState.STOPPED.toString()); if (state != null) { map.put("status", state.toString()); } if (repository.findById(name) == null) { throw new EntityNotFoundException(name); } return map; } }