package org.jvalue.ods.rest; import com.google.inject.Inject; import org.jvalue.commons.auth.RestrictedTo; import org.jvalue.commons.auth.Role; import org.jvalue.commons.auth.User; import org.jvalue.commons.rest.RestUtils; import org.jvalue.ods.api.processors.ProcessorReferenceChain; import org.jvalue.ods.api.processors.ProcessorReferenceChainDescription; import org.jvalue.ods.api.sources.DataSource; import org.jvalue.ods.data.DataSourceManager; import org.jvalue.ods.processor.ProcessorChainManager; import java.util.EnumSet; import java.util.List; import java.util.concurrent.TimeUnit; import javax.validation.Valid; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path(AbstractApi.BASE_URL + "/{sourceId}/filterChains") @Produces(MediaType.APPLICATION_JSON) public final class ProcessorChainApi extends AbstractApi { // avoid executing filter chains faster than every second private static final EnumSet<TimeUnit> validExecutionIntervalUnits = EnumSet.of(TimeUnit.SECONDS, TimeUnit.MINUTES, TimeUnit.HOURS, TimeUnit.DAYS); private final DataSourceManager sourceManager; private final ProcessorChainManager chainManager; @Inject public ProcessorChainApi( DataSourceManager sourceManager, ProcessorChainManager chainManager) { this.sourceManager = sourceManager; this.chainManager = chainManager; } @GET public List<ProcessorReferenceChain> getAllProcessorChains( @PathParam("sourceId") String sourceId) { DataSource source = sourceManager.findBySourceId(sourceId); return chainManager.getAll(source); } @GET @Path("/{filterChainId}") public ProcessorReferenceChain getProcessorChain( @PathParam("sourceId") String sourceId, @PathParam("filterChainId") String filterChainId) { DataSource source = sourceManager.findBySourceId(sourceId); return chainManager.get(source, filterChainId); } @PUT @Path("/{filterChainId}") public ProcessorReferenceChain addProcessorChain( @RestrictedTo(Role.ADMIN) User user, @PathParam("sourceId") String sourceId, @PathParam("filterChainId") String filterChainId, @Valid ProcessorReferenceChainDescription processorChain) { if (processorChain.getExecutionInterval() != null) { assertIsValidTimeUnit(processorChain.getExecutionInterval().getUnit()); } DataSource source = sourceManager.findBySourceId(sourceId); if (chainManager.contains(source, filterChainId)) throw RestUtils.createJsonFormattedException("filter chain with id " + filterChainId + " already exists", 409); ProcessorReferenceChain chainReference = new ProcessorReferenceChain( filterChainId, processorChain.getProcessors(), processorChain.getExecutionInterval()); if (processorChain.getExecutionInterval() != null) chainManager.add(source, sourceManager.getDataRepository(source), chainReference); else chainManager.executeOnce(source, sourceManager.getDataRepository(source), chainReference); return chainReference; } @DELETE @Path("/{filterChainId}") public void deleteProcessorChain( @RestrictedTo(Role.ADMIN) User user, @PathParam("sourceId") String sourceId, @PathParam("filterChainId") String filterChainId) { DataSource source = sourceManager.findBySourceId(sourceId); ProcessorReferenceChain reference = chainManager.get(source, filterChainId); chainManager.remove(source, sourceManager.getDataRepository(source), reference); } private void assertIsValidTimeUnit(TimeUnit unit) { if (!validExecutionIntervalUnits.contains(unit)) { StringBuilder builder = new StringBuilder(); builder.append("time unit must be one of: "); boolean firstIter = true; for (TimeUnit validUnit : validExecutionIntervalUnits) { if (!firstIter) builder.append(", "); else firstIter = false; builder.append(validUnit.toString()); } throw RestUtils.createJsonFormattedException(builder.toString(), 400); } } }