package ee.telekom.workflow.web.console; import java.lang.invoke.MethodHandles; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.Errors; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import ee.telekom.workflow.core.common.UnexpectedStatusException; import ee.telekom.workflow.core.common.WorkflowEngineConfiguration; import ee.telekom.workflow.facade.WorkflowEngineFacade; import ee.telekom.workflow.facade.model.WorkItemState; import ee.telekom.workflow.util.JsonUtil; import ee.telekom.workflow.web.console.form.ExecuteWorkItemForm; /** * Controller for the workflow item details view. */ @Controller @RequestMapping("/console") public class WorkItemController{ private static final Logger log = LoggerFactory.getLogger( MethodHandles.lookup().lookupClass() ); @Autowired private WorkflowEngineConfiguration configuration; @Autowired private WorkflowEngineFacade facade; @RequestMapping(method = RequestMethod.GET, value = "/workflow/instances/{woinRefNum}/item/{woitRefNum}") public String view( Model model, @PathVariable long woinRefNum, @PathVariable long woitRefNum, @ModelAttribute("skipTimer") ExecuteWorkItemForm skipTimerForm ){ WorkItemState workItem = facade.findWorkItem( woitRefNum, null ); if( workItem == null || workItem.getWoinRefNum() != woinRefNum ){ throw new IllegalArgumentException( "Cannot find work item" ); } model.addAttribute( "workItem", workItem ); return "console/workflow/item"; } @PreAuthorize("hasRole('ROLE_TWE_ADMIN')") @RequestMapping(method = RequestMethod.POST, value = "/workflow/instances/{woinRefNum}/item/{woitRefNum}") public String handleAction( RedirectAttributes model, @PathVariable long woinRefNum, @PathVariable long woitRefNum, @ModelAttribute("form") ExecuteWorkItemForm form, Errors result ){ WorkItemState workItem = facade.findWorkItem( woitRefNum, null ); if( workItem == null || workItem.getWoinRefNum() != woinRefNum ){ throw new IllegalArgumentException( "Cannot find work item" ); } // parsing form result field Object formResult = null; try{ formResult = JsonUtil.deserialize( form.getResult() ); } catch( Exception e ){ log.info( e.getMessage(), e ); result.rejectValue( "result", "workflow.item.error.result." + workItem.getType() ); } // perform action if( !result.hasErrors() ){ try{ doAction( workItem, formResult ); } catch( UnexpectedStatusException e ){ log.info( e.getMessage(), e ); model.addFlashAttribute( "errorMessage", "workflow.item.error.status" ); return "redirect:" + configuration.getConsoleMappingPrefix() + "/console/workflow/instances/" + workItem.getWoinRefNum(); } catch( Exception e ){ log.warn( "Unable to perform action on work item " + woitRefNum, e ); model.addFlashAttribute( "errorMessage", "workflow.item.error.action." + workItem.getType() ); model.addFlashAttribute( "error", e.getMessage() ); } } // redirect if( result.hasErrors() || model.getFlashAttributes().containsKey( "error" ) ){ model.addFlashAttribute( "form", form ); // XXX Errors object was never intended to be put into flash/session for POST-REDIRECT-GET: https://jira.spring.io/browse/SPR-8282 model.addFlashAttribute( "org.springframework.validation.BindingResult.form", result ); return "redirect:" + configuration.getConsoleMappingPrefix() + "/console/workflow/instances/" + workItem.getWoinRefNum() + "/item/" + workItem.getRefNum(); } else{ model.addFlashAttribute( "successMessage", "workflow.item.success." + workItem.getType() ); return "redirect:" + configuration.getConsoleMappingPrefix() + "/console/workflow/instances/" + workItem.getWoinRefNum(); } } private void doAction( WorkItemState workItem, Object result ){ switch( workItem.getType() ) { case SIGNAL: facade.sendSignalToWorkItem( workItem.getRefNum(), workItem.getSignal(), result ); break; case TIMER: facade.skipTimer( workItem.getRefNum() ); break; case TASK: facade.submitTask( workItem.getRefNum(), result ); break; case HUMAN_TASK: facade.submitHumanTask( workItem.getRefNum(), result ); break; } } @ModelAttribute("form") public ExecuteWorkItemForm createForm(){ return new ExecuteWorkItemForm(); } }