Java tutorial
package de.zib.gndms.GORFX.service; import de.zib.gndms.common.GORFX.service.TaskFlowService; import de.zib.gndms.common.model.gorfx.types.*; import de.zib.gndms.common.rest.*; import de.zib.gndms.common.stuff.devel.NotYetImplementedException; import de.zib.gndms.gndmc.gorfx.TaskClient; import de.zib.gndms.infra.GridConfig; import de.zib.gndms.kit.security.SpringSecurityContextHolder; import de.zib.gndms.kit.util.WidAux; import de.zib.gndms.logic.model.TaskAction; import de.zib.gndms.logic.model.TaskExecutionService; import de.zib.gndms.logic.model.gorfx.taskflow.TaskFlowAux; import de.zib.gndms.logic.model.gorfx.taskflow.TaskFlowFactory; import de.zib.gndms.logic.model.gorfx.taskflow.TaskFlowProvider; import de.zib.gndms.logic.model.gorfx.taskflow.UnsatisfiableOrderException; import de.zib.gndms.model.common.NoSuchResourceException; import de.zib.gndms.model.common.PermissionInfo; import de.zib.gndms.model.common.PersistentContract; import de.zib.gndms.model.gorfx.types.DelegatingOrder; import de.zib.gndms.neomodel.common.Dao; import de.zib.gndms.neomodel.gorfx.TaskBuilder; import de.zib.gndms.neomodel.gorfx.TaskFlow; import de.zib.gndms.neomodel.gorfx.Taskling; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.*; /* * Copyright 2008-2011 Zuse Institute Berlin (ZIB) * * Licensed 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. */ /** * @author try ma ik jo rr a zib * @date 13.01.2011 15:17:47 * * @brief A controller for a REST taskflow resource which implements the * TaskFlowService interface. * * The taskflow service acts as interface to instantiated taskflow * resources. The instantiation or creation happens through the GORFX * service itself. * * This implicates that all method invocation concern a single * taskflow, not the service as a whole. */ @Controller @RequestMapping("/gorfx") public class TaskFlowServiceImpl implements TaskFlowService { // private ORQDao orqDao; private String localBaseUrl; private String baseUrl; // inject or read from properties, doesn't contain gorfx postfix private TaskFlowProvider taskFlowProvider; private final List<String> facetsNames = new ArrayList<String>(6); private UriFactory uriFactory; private TaskClient taskClient; private final Logger logger = LoggerFactory.getLogger(this.getClass()); private TaskExecutionService executorService; private Dao dao; private GridConfig gridConfig; @PostConstruct public void init() { facetsNames.add("order"); facetsNames.add("quote"); facetsNames.add("task"); facetsNames.add("result"); facetsNames.add("status"); facetsNames.add("errors"); uriFactory = new UriFactory(baseUrl); taskClient.setServiceURL(localBaseUrl); } @RequestMapping(value = "/_{type}/_{id}", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<Facets> getFacets(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn) { Map<String, String> uriargs = taskFlowUriMap(type, id); GNDMSResponseHeader header = new GNDMSResponseHeader(uriFactory.taskFlowTypeUri(uriargs, null), null, baseUrl, dn, null); if (taskFlowProvider.exists(type)) { TaskFlow tf = taskFlowProvider.getFactoryForTaskFlow(type).find(id); if (tf != null) { ArrayList<Facet> fl = new ArrayList<Facet>(6); for (String f : facetsNames) { String fn = uriFactory.taskFlowUri(uriargs, f); fl.add(new Facet(f, fn)); } return new ResponseEntity<Facets>(new Facets(fl), header, HttpStatus.OK); } else logger.debug("request for non existing " + type + ": " + id); } else logger.debug("request for non existing type " + type + ": " + id); return new ResponseEntity<Facets>(new Facets(), header, HttpStatus.NOT_FOUND); } @RequestMapping(value = "/_{type}/_{id}", method = RequestMethod.DELETE) @Secured("ROLE_USER") public ResponseEntity<Integer> deleteTaskflow(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { logger.debug("removing " + type + " taskflow: " + id); HttpStatus hs = HttpStatus.NOT_FOUND; if (taskFlowProvider.exists(type)) { TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow(type); TaskFlow tf = tff.find(id); if (tf != null) { if (tf.hasTaskling()) taskClient.deleteTask(tf.getTaskling().getId(), dn, wid); tff.delete(id); hs = HttpStatus.OK; } } return new ResponseEntity<Integer>(new Integer(0), getHeader(type, id, null, dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/order", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<Order> getOrder(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; Order order = null; try { TaskFlow tf = findTF(type, id); order = tf.getOrder().getOrderBean(); if (order != null) hs = HttpStatus.OK; } catch (NoSuchResourceException e) { /* intentionally */ } return new ResponseEntity<Order>(order, getHeader(type, id, "order", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/order", method = RequestMethod.POST) @Secured("ROLE_USER") public ResponseEntity<Integer> setOrder(@PathVariable String type, @PathVariable String id, @RequestBody Order orq, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; if (taskFlowProvider.exists(type)) { final TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow(type); final TaskFlow tf = tff.find(id); if (tf != null) hs = TaskFlowServiceAux.setAndValidateOrder(orq, tf, tff); } return new ResponseEntity<Integer>(0, getHeader(type, id, "order", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/quote", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<List<Specifier<Quote>>> getQuotes(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { WidAux.initWid(wid); logger.debug("quote called"); HttpStatus hs = HttpStatus.NOT_FOUND; List<Specifier<Quote>> res = null; if (taskFlowProvider.exists(type)) { TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow(type); TaskFlow tf = tff.find(id); if (tf != null) { try { List<Quote> quoteList = TaskFlowServiceAux.createQuotes(tff, tf); // set origin of quotes if not already set for (Quote quote : quoteList) { if (quote.getSite() == null) quote.setSite(getGridConfig().getBaseUrl()); } res = new ArrayList<Specifier<Quote>>(quoteList.size()); HashMap<String, String> urimap = new HashMap<String, String>(3); urimap.put("service", "gorfx"); urimap.put(UriFactory.TASKFLOW_ID, id); urimap.put("type", type); for (int i = 0; i < quoteList.size(); ++i) { urimap.put("idx", String.valueOf(i)); Specifier<Quote> sq = new Specifier<Quote>(); sq.setUriMap(Collections.unmodifiableMap(urimap)); sq.setUrl(uriFactory.quoteUri(urimap)); sq.setPayload(quoteList.get(i)); res.add(sq); } hs = HttpStatus.OK; } catch (UnsatisfiableOrderException e) { DelegatingOrder o = tf.getOrder(); logger.debug("Unsatisfiable order: " + o.getLoggableDescription()); logger.debug(e.getStackTrace().toString()); tf.setUnfulfillableOrder(true); hs = HttpStatus.BAD_REQUEST; } catch (Exception e) { logger.warn("Exception on order calculation for " + tf.getOrder().getLoggableDescription(), e); throw new RuntimeException("Could not calculate quotes for order: " + e.getMessage(), e); } } } WidAux.removeWid(); return new ResponseEntity<List<Specifier<Quote>>>(res, getHeader(type, id, "quote", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/quote", method = RequestMethod.POST) @Secured("ROLE_USER") public ResponseEntity<Integer> setQuote(@PathVariable String type, @PathVariable String id, @RequestBody Quote cont, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; try { TaskFlow tf = findTF(type, id); tf.setPreferredQuote(cont); hs = HttpStatus.OK; } catch (NoSuchResourceException e) { } return new ResponseEntity<Integer>(37, getHeader(type, id, "quote", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/quote/_{idx}", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<Quote> getQuote(@PathVariable String type, @PathVariable String id, @PathVariable int idx, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; Quote quote = null; try { TaskFlow tf = findTF(type, id); List<Quote> quoteList = tf.getQuotes(); if (quoteList != null && idx >= 0 && idx < quoteList.size()) { quote = quoteList.get(idx); hs = HttpStatus.OK; } } catch (NoSuchResourceException e) { // intentionally } return new ResponseEntity<Quote>(quote, getHeader(type, id, "quote", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/quote/_{idx}", method = RequestMethod.DELETE) @Secured("ROLE_USER") public ResponseEntity<Integer> deleteQuotes(@PathVariable String type, @PathVariable String id, @PathVariable int idx, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { throw new NotYetImplementedException(); // together with the ProperlyNeverWillBeException } @RequestMapping(value = "/_{type}/_{id}/task", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<Specifier<Facets>> getTask(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; Specifier<Facets> spec = null; WidAux.initWid(wid); try { TaskFlow tf = findTF(type, id); Taskling t = tf.getTaskling(); if (t != null) { logger.debug("getTask task called"); spec = TaskClient.TaskServiceAux.getTaskSpecifier(taskClient, t.getId(), uriFactory, taskFlowUriMap(type, id), dn); hs = HttpStatus.OK; } } catch (Exception e) { logger.warn("Exception while getting task", e); } logger.debug("returning with " + hs.name()); WidAux.removeWid(); return new ResponseEntity<Specifier<Facets>>(spec, getHeader(type, id, "task", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/task", method = RequestMethod.PUT) @Secured("ROLE_USER") public ResponseEntity<Specifier<Facets>> createTask(@PathVariable String type, @PathVariable String id, @RequestParam(value = "quote", required = false) Integer quoteId, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; WidAux.initWid(wid); logger.debug("create task called"); HttpHeaders headers = getHeader(type, id, "task", dn, wid); if (taskFlowProvider.exists(type)) { TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow(type); TaskFlow tf = tff.find(id); if (tf != null) { if (tf.getTaskling() != null) hs = HttpStatus.CONFLICT; else { tf.getOrder().setSecurityContextHolder( new SpringSecurityContextHolder(SecurityContextHolder.getContext())); TaskAction ta; Taskling taskling; if (tf.hasQuotes()) { logger.debug("submitting using quote: " + quoteId); ta = tff.createAction((Quote) tf.getQuotes().get(quoteId == null ? 0 : quoteId)); taskling = submitTaskActionWithQuotes(quoteId, tf, ta, wid); } else { ta = tff.createAction(); taskling = executorService.submitTaskAction(dao, ta, tf.getOrder(), wid); } hs = HttpStatus.CREATED; Specifier<Facets> spec = null; try { spec = TaskClient.TaskServiceAux.getTaskSpecifier(taskClient, taskling.getId(), uriFactory, taskFlowUriMap(type, id), dn); } catch (Exception e) { logger.warn("Exception while getting task", e); } return new ResponseEntity<Specifier<Facets>>(spec, headers, hs); } } } logger.debug("Problem, returning " + hs.name()); WidAux.removeWid(); return new ResponseEntity<Specifier<Facets>>(null, headers, hs); } private Taskling submitTaskActionWithQuotes(final Integer quoteId, final TaskFlow tf, final TaskAction ta, final String wid) { Taskling taskling; List<Quote> quotes = tf.getQuotes(); Quote quote = quoteId != null && quoteId >= 0 && quoteId < quotes.size() ? quotes.get(quoteId) : quotes.get(0); taskling = executorService.submitTaskAction(dao, ta, new TaskBuilder().setOrder(tf.getOrder()).setContract(PersistentContract.acceptQuoteNow(quote)) .setPermissionInfo(new PermissionInfo("default", "PermissionConfiglet")) , wid); return taskling; } @RequestMapping(value = "/_{type}/_{id}/status", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<TaskFlowStatus> getStatus(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; TaskFlowStatus tfs = null; try { TaskFlow tf = findTF(type, id); tfs = TaskFlowAux.statusFromTaskFlow(dao, tf); Taskling t = tf.getTaskling(); if (t != null) { // maybe call task client Specifier<Void> spec = new Specifier<Void>(); Map<String, String> urimap = taskUriMap(type, id, t); spec.setUrl(uriFactory.taskUri(urimap, "status")); spec.setUriMap(urimap); tfs.setTaskSpecifier(spec); hs = HttpStatus.OK; } } catch (NoSuchResourceException e) { // intentionally } return new ResponseEntity<TaskFlowStatus>(tfs, getHeader(type, id, "status", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/result", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<Specifier<TaskResult>> getResult(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; Specifier<TaskResult> spec = null; try { spec = createTaskSpecifier(TaskResult.class, type, id, "result"); ResponseEntity<TaskResult> res = taskClient.getResult(spec.getUriMap().get("taskId"), dn, wid); if (HttpStatus.OK.equals(res.getStatusCode())) { spec.setPayload(res.getBody()); hs = HttpStatus.OK; } else spec = null; } catch (NoSuchResourceException e) { // intentionally } return new ResponseEntity<Specifier<TaskResult>>(spec, getHeader(type, id, "result", dn, wid), hs); } @RequestMapping(value = "/_{type}/_{id}/errors", method = RequestMethod.GET) @Secured("ROLE_USER") public ResponseEntity<TaskFlowFailure> getErrors(@PathVariable String type, @PathVariable String id, @RequestHeader("DN") String dn, @RequestHeader("WId") String wid) { HttpStatus hs = HttpStatus.NOT_FOUND; TaskFlowFailureImpl taskFlowFailure = new TaskFlowFailureImpl(); try { Specifier<TaskFailure> spec = createTaskSpecifier(TaskFailure.class, type, id, "errors"); ResponseEntity<TaskFailure> res = taskClient.getErrors(spec.getUriMap().get("taskId"), dn, wid); if (res.getStatusCode() == HttpStatus.OK) { spec.setPayload(res.getBody()); hs = HttpStatus.OK; } } catch (NoSuchResourceException e) { // intentionally } return new ResponseEntity<TaskFlowFailure>(taskFlowFailure, getHeader(type, id, "result", dn, wid), hs); } protected GNDMSResponseHeader getHeader(String type, String id, String facet, String dn, String wid) { Map<String, String> uriargs = taskFlowUriMap(type, id); return new GNDMSResponseHeader(uriFactory.taskFlowTypeUri(uriargs, facet), facet, baseUrl, dn, wid); } private Map<String, String> taskFlowUriMap(String type, String id) { HashMap<String, String> urimap = new HashMap<String, String>(3); urimap.put(UriFactory.SERVICE, "gorfx"); urimap.put(UriFactory.TASKFLOW_TYPE, type); urimap.put(UriFactory.TASKFLOW_ID, id); return urimap; } private Map<String, String> taskUriMap(String type, String id, Taskling t) { return TaskClient.TaskServiceAux.taskUriMap(t.getId(), taskFlowUriMap(type, id)); } private <T> Specifier<T> createTaskSpecifier(Class<T> resClass, String type, String id, String facet) throws NoSuchResourceException { final TaskFlow tf = findTF(type, id); final Taskling t = tf.getTaskling(); final Map<String, String> urimap = taskUriMap(type, id, t); final Specifier<T> spec; if (t != null) { spec = new Specifier<T>(); spec.setUrl(uriFactory.taskUri(urimap, facet)); spec.setUriMap(urimap); } else throw new NoSuchResourceException("task", urimap); return spec; } protected TaskFlow findTF(String type, String id) throws NoSuchResourceException { if (taskFlowProvider.exists(type)) { TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow(type); TaskFlow tf = tff.find(id); if (tf != null) return tf; else return TaskFlowServiceAux.fromTask(dao, taskFlowProvider, type, id); } throw new NoSuchResourceException(); } public Dao getDao() { return dao; } @Inject public void setDao(Dao dao) { this.dao = dao; } public TaskExecutionService getExecutorService() { return executorService; } @Inject public void setExecutorService(TaskExecutionService executorService) { this.executorService = executorService; } public void setBaseUrl(String baseUrl) { this.baseUrl = baseUrl; } public void setLocalBaseUrl(String localBaseUrl) { this.localBaseUrl = localBaseUrl; } @Inject public void setTaskFlowProvider(TaskFlowProvider taskFlowProvider) { this.taskFlowProvider = taskFlowProvider; } @Inject public void setTaskClient(TaskClient taskClient) { this.taskClient = taskClient; } public GridConfig getGridConfig() { return gridConfig; } @Inject public void setGridConfig(GridConfig gridConfig) { this.gridConfig = gridConfig; } }