package de.zib.gndms.GORFX.service; /* * 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. */ import de.zib.gndms.common.GORFX.service.TaskService; import de.zib.gndms.common.model.gorfx.types.*; import de.zib.gndms.common.rest.Facet; import de.zib.gndms.common.rest.Facets; import de.zib.gndms.common.rest.GNDMSResponseHeader; import de.zib.gndms.common.rest.UriFactory; import de.zib.gndms.common.stuff.devel.NotYetImplementedException; import de.zib.gndms.logic.model.gorfx.taskflow.TaskTypeConverter; import de.zib.gndms.model.common.NoSuchResourceException; import de.zib.gndms.model.gorfx.types.TaskState; import de.zib.gndms.neomodel.common.Dao; import de.zib.gndms.neomodel.common.Session; import de.zib.gndms.neomodel.gorfx.Task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.annotation.Secured; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.*; /** * @author try ma ik jo rr a zib * @date 01.03.11 12:06 * @brief Controller for the TaskService. */ @Controller @RequestMapping( "/gorfx/tasks" ) public class TaskServiceImpl implements TaskService { protected final Logger logger = LoggerFactory.getLogger( this.getClass() ); private String serviceUrl; private UriFactory uriFactory; private List<String> facets; private Dao dao; @PostConstruct void init( ) { facets = new ArrayList<String>( 3 ); facets.add( "status" ); facets.add( "result" ); facets.add( "errors" ); uriFactory = new UriFactory( serviceUrl ); } @RequestMapping( value = "", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskServiceInfo> getServiceInfo( @RequestHeader( "DN" ) final String dn ) { return new ResponseEntity<TaskServiceInfo>( new TaskServiceInfo(), null, HttpStatus.OK ); } @RequestMapping( value = "/config", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskServiceConfig> getServiceConfig( @RequestHeader( "DN" ) String dn ) { throw new NotYetImplementedException(); } @RequestMapping( value = "/config", method = RequestMethod.POST ) @Secured( "ROLE_ADMIN" ) public ResponseEntity<String> setServiceConfig( @RequestBody TaskServiceConfig cfg, @RequestHeader( "DN" ) String dn ) { throw new NotYetImplementedException(); } @RequestMapping( value = "/_{id}", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<Facets> getTaskFacets( @PathVariable String id, @RequestHeader( "DN" ) String dn ) { logger.debug( "get task called with id " + id ); Session session = dao.beginSession(); try { findTask( id, session ); // ensures that id is valid session.success(); } finally { session.finish(); } Map<String,String> uriargs = new HashMap<String, String>( 2 ); uriargs.put( UriFactory.SERVICE, "gorfx" ); uriargs.put( UriFactory.TASK_ID, id ); ArrayList<Facet> fl = new ArrayList<Facet>( facets.size() ); for( String f : facets ) { String fn = uriFactory.taskUri( uriargs, f ); fl.add( new Facet( f, fn ) ); } return new ResponseEntity<Facets>( new Facets( fl ), getHeader( id, null, dn, null ), HttpStatus.OK ); } @RequestMapping( value = "/_{id}", method = RequestMethod.DELETE ) @Secured( "ROLE_USER" ) public ResponseEntity< Integer > deleteTask( @PathVariable String id, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid ) { logger.debug( "delete task called with id " + id ); Session session = dao.beginSession(); try { // todo check if task for taskling is running Task t = findTask( id, session ); // ensures that id is valid if ( ! t.getTaskState().isDoneState() ) Task.fullDelete( t, session ); session.success(); } finally { session.finish(); } return new ResponseEntity< Integer >( new Integer( 0 ), getHeader( id, null, dn, wid ), HttpStatus.OK ); } @RequestMapping( value = "/_{id}/status", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskStatus> getStatus( @PathVariable String id, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid ) { Session session = dao.beginSession(); try { Task t = findTask( id, session ); t.getTerminationTime(); TaskStatus status = TaskTypeConverter.statusFromTask( t ); session.success(); return new ResponseEntity<TaskStatus>( status, getHeader( id, "status", dn, wid ), HttpStatus.OK ); } finally { session.finish(); } } @RequestMapping( value = "/_{id}/status", method = RequestMethod.POST ) @Secured( "ROLE_USER" ) public ResponseEntity< Integer > changeStatus( @PathVariable String id, @RequestBody TaskControl status, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid ) { // todo set alt status to task return null; } @RequestMapping( value = "/_{id}/result", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskResult> getResult( @PathVariable String id, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid ) { Session session = dao.beginSession(); try { HttpStatus hs = HttpStatus.NOT_FOUND; Task t = findTask( id, session ); TaskResult res = null; if( TaskState.FINISHED.equals( t.getTaskState() ) ) { Object pl = t.getPayload(); if( pl != null ) { res = TaskResult.class.cast( pl ); } else res = new VoidTaskResult(); hs = HttpStatus.OK; } session.success(); return new ResponseEntity<TaskResult>( res, getHeader( id, "result", dn, wid ), hs ); } finally { session.finish(); } } @RequestMapping( value = "/_{id}/errors", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskFailure> getErrors( @PathVariable String id, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid ) { Session session = dao.beginSession(); try { HttpStatus hs = HttpStatus.NOT_FOUND; Task t = findTask( id, session ); TaskFailure fail = null; if( TaskState.FAILED.equals( t.getTaskState() ) ) { LinkedList<Exception> pl = t.getCause(); if( pl != null ) { hs = HttpStatus.OK; fail = TaskTypeConverter.failStackToList( pl ); } } session.success(); return new ResponseEntity<TaskFailure>( fail, getHeader( id, "errors", dn, wid ), hs ); } finally { session.finish(); } } protected Task findTask( String id, Session session ) throws NoSuchResourceException { Task t = session.findTask( id ); if( t == null ) throw new NoSuchResourceException( id ); return t; } protected GNDMSResponseHeader getHeader( String id, String facet, String dn, String wid ) { Map<String,String> uriargs = new HashMap<String, String>( 2 ); uriargs.put( UriFactory.TASK_ID, id ); uriargs.put( UriFactory.SERVICE, "gorfx" ); return new GNDMSResponseHeader( uriFactory.taskServiceUri( uriargs ), uriFactory.taskUri( uriargs, facet ), serviceUrl, dn, wid ); } @ExceptionHandler( NoSuchResourceException.class ) public ResponseEntity<Void> handleNoSuchResourceException( NoSuchResourceException ex ) { logger.debug( "handling exception for: " + ex.getMessage() ); return new ResponseEntity<Void>( null, getHeader( ex.getMessage(), null, null, null ), HttpStatus.NOT_FOUND ); } public void setServiceUrl( String serviceUrl ) { this.serviceUrl = serviceUrl; } @Inject public void setDao( Dao dao ) { this.dao = dao; } }