package de.zib.gndms.GORFX.service; /* * Copyright 2008-2010 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.GORFXService; import de.zib.gndms.common.logic.action.ActionMeta; import de.zib.gndms.common.logic.config.ConfigMeta; import de.zib.gndms.common.model.gorfx.types.Order; import de.zib.gndms.common.model.gorfx.types.TaskFlowInfo; import de.zib.gndms.common.rest.Facets; import de.zib.gndms.common.rest.GNDMSResponseHeader; import de.zib.gndms.common.rest.Specifier; import de.zib.gndms.common.rest.UriFactory; import de.zib.gndms.gndmc.gorfx.TaskFlowClient; import de.zib.gndms.logic.action.ActionProvider; import de.zib.gndms.logic.action.NoSuchActionException; import de.zib.gndms.logic.model.config.ConfigActionProvider; import de.zib.gndms.logic.model.gorfx.taskflow.TaskFlowFactory; import de.zib.gndms.logic.model.gorfx.taskflow.TaskFlowProvider; import de.zib.gndms.neomodel.gorfx.TaskFlow; 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.util.MultiValueMap; import org.springframework.web.bind.annotation.*; import javax.annotation.PostConstruct; import javax.inject.Inject; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author try ma ik jo rr a zib * @date: 26.01.11, 12:29 * * @brief Controller class for the gorfx service. * * For detailed method documentation @see GORFXService. */ @Controller @RequestMapping( value = "/gorfx" ) public class GORFXServiceImpl implements GORFXService { protected final Logger logger = LoggerFactory.getLogger( this.getClass() ); private Facets gorfxFacets; ///< List of facets under /gorfx/ private String localBaseUrl; private String baseUrl; ///< The base url something like: \c http://my.host.org/gndms/grid_id private String gorfxBaseUrl; ///< Base url of the GORFX service endpoint private TaskFlowProvider taskFlowProvider; ///< List of task factories, registered through plug-in mech private TaskFlowClient taskFlowClient; private UriFactory uriFactory; private ConfigActionProvider configActionProvider; ///< List of config actions public GORFXServiceImpl() { } public GORFXServiceImpl( final String baseUrl ) { setBaseUrl( baseUrl ); } public void setLocalBaseUrl( final String localBaseUrl) { this.localBaseUrl = localBaseUrl; } public void setBaseUrl( final String baseUrl ) { this.baseUrl = baseUrl; gorfxBaseUrl = baseUrl + "/gorfx/"; } @PostConstruct public void init( ) { taskFlowClient.setServiceURL( localBaseUrl ); uriFactory = new UriFactory( baseUrl ); } @RequestMapping( value = "/", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<Facets> listAvailableFacets( @RequestHeader( "DN" ) String dn ) { GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader(); responseHeaders.setResourceURL( gorfxBaseUrl ); responseHeaders.setParentURL( baseUrl ); if( dn != null ) responseHeaders.setDN( dn ); return new ResponseEntity<Facets>( gorfxFacets, responseHeaders, HttpStatus.OK ); } @RequestMapping( value = "/config", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<List<String>> listConfigActions( @RequestHeader( value="DN", required=false ) String dn ) { GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader(); responseHeaders.setResourceURL( gorfxBaseUrl ); responseHeaders.setFacetURL( gorfxFacets.findFacet( "config" ).getUrl() ); responseHeaders.setParentURL( baseUrl ); if( dn != null ) responseHeaders.setDN( dn ); return new ResponseEntity<List<String>>( configActionProvider.listAvailableActions(), responseHeaders, HttpStatus.OK ); } @RequestMapping( value = "/config/_{actionName:[a-zA-Z._0-9]+}", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<ConfigMeta> getConfigActionInfo( @PathVariable String actionName, @RequestHeader( value="DN", required=false ) String dn ) { HttpStatus hs = HttpStatus.NOT_FOUND ; GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader( gorfxFacets.findFacet( "config" ).getUrl(), null, gorfxBaseUrl, dn, null ); ConfigMeta configMeta = null; try { configMeta = configActionProvider.getMeta( actionName ); hs = HttpStatus.OK; } catch ( NoSuchActionException e ) { logger.info( "", e ); } return new ResponseEntity<ConfigMeta>( configMeta, responseHeaders, hs ); } @RequestMapping( value = "/config/_{actionName:[a-zA-Z._0-9]+}", method = RequestMethod.POST ) @Secured( "ROLE_ADMIN" ) public ResponseEntity<String> callConfigAction( @PathVariable String actionName, @RequestBody String args, @RequestHeader( "DN" ) String dn ) { GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader( gorfxFacets.findFacet( "config" ).getUrl(), null, gorfxBaseUrl, dn, null ); HttpStatus httpStatus = HttpStatus.INTERNAL_SERVER_ERROR; String result = null; try { result = configActionProvider.callConfigAction( actionName, args ); httpStatus = HttpStatus.OK; } catch ( Exception e ) { logger.warn( "config action exception on: " + actionName + ": " + args, e ); } return new ResponseEntity<String>( result, responseHeaders, httpStatus ); } @RequestMapping( value = "/batch", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<List<String>> listBatchActions( String dn ) { // Fires a batch action GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader(); responseHeaders.setResourceURL( gorfxBaseUrl ); responseHeaders.setFacetURL( gorfxFacets.findFacet( "batch" ).getUrl() ); responseHeaders.setParentURL( baseUrl ); return new ResponseEntity<List<String>>( Collections.singletonList( "mock-up" ), responseHeaders, HttpStatus.OK ); } @RequestMapping( value = "/batch/_{actionName}", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<ActionMeta> getBatchActionInfo( @PathVariable String actionName, @RequestHeader( "DN" ) String dn ) { GNDMSResponseHeader headers = new GNDMSResponseHeader(); headers.setResourceURL( gorfxFacets.findFacet( "batch" ).getUrl() ); headers.setParentURL( gorfxBaseUrl ); if( dn != null ) headers.setDN( dn ); if (! actionName.equals( "mock-up" ) ) return new ResponseEntity<ActionMeta>( null, headers, HttpStatus.NOT_FOUND ); return new ResponseEntity<ActionMeta>( new ActionMeta() { public String getName() { return "mock-up"; } public String getHelp() { return "Sorry, I can't even help myself"; } public String getDescription() { return "I just mock you"; } }, headers, HttpStatus.OK ); } @RequestMapping( value = "/batch/_{actionName}/_{id}", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<Specifier<Facets>> getBatchAction( @PathVariable String actionName, @PathVariable String id, @RequestHeader String dn ) { return null; // not required here } @RequestMapping( value = "/batch/_{actionName}", method = RequestMethod.POST ) @Secured( "ROLE_USER" ) public ResponseEntity<Specifier> callBatchAction( @PathVariable String actionName, @RequestBody String args, @RequestHeader( "DN" ) String dn ) { GNDMSResponseHeader headers = new GNDMSResponseHeader( gorfxFacets.findFacet( "batch" ).getUrl(), null, gorfxBaseUrl, dn, null ); if (! actionName.equals( "mock-up" ) ) return new ResponseEntity<Specifier>( null, headers, HttpStatus.NOT_FOUND ); Specifier<String> res = new Specifier<String>(); res.addMapping( "actionName", actionName ); res.setUrl( baseUrl + "/batch/_" + actionName ); res.setPayload( "Feeling lucky?" ); return (ResponseEntity<Specifier>) (Object) new ResponseEntity<Specifier<String>>( res, headers, HttpStatus.OK ); } @RequestMapping( value = "/taskflows", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<List<String>> listTaskFlows( @RequestHeader( "DN" ) String dn ) { if ( taskFlowProvider == null ) throw new IllegalStateException( "provider is null" ); GNDMSResponseHeader responseHeaders = new GNDMSResponseHeader( gorfxBaseUrl, gorfxFacets.findFacet( "taskflows" ).getUrl(), baseUrl, dn, null ); return new ResponseEntity<List<String>>( taskFlowProvider.listTaskFlows(), responseHeaders, HttpStatus.OK ); } @RequestMapping( value = "/_{type}", method = RequestMethod.GET ) @Secured( "ROLE_USER" ) public ResponseEntity<TaskFlowInfo> getTaskFlowInfo( @PathVariable String type, @RequestHeader( "DN" ) String dn ) { GNDMSResponseHeader headers = new GNDMSResponseHeader( gorfxFacets.findFacet( "taskflows" ).getUrl(), null, gorfxBaseUrl, dn, null ); if (! taskFlowProvider.exists( type ) ) return new ResponseEntity<TaskFlowInfo>( null, headers, HttpStatus.NOT_FOUND ); taskFlowProvider.getTaskFlowInfo( type ); return new ResponseEntity<TaskFlowInfo>( taskFlowProvider.getTaskFlowInfo( type ), headers, HttpStatus.OK ); } @RequestMapping( value = "/_{type}", method = RequestMethod.POST ) @Secured( "ROLE_USER" ) public ResponseEntity<Specifier<Facets>> createTaskFlow( @PathVariable String type, @RequestBody Order order, @RequestHeader( "DN" ) String dn, @RequestHeader( "WId" ) String wid, @RequestHeader MultiValueMap<String, String> context ) { GNDMSResponseHeader headers = new GNDMSResponseHeader( gorfxFacets.findFacet( "taskflows" ).getUrl(), null, gorfxBaseUrl, dn, wid ); if(! taskFlowProvider.exists( type ) ) { logger.debug( "Request for not existing TaskFlow: " + type ); return new ResponseEntity<Specifier<Facets>>( null, headers, HttpStatus.NOT_FOUND ); } TaskFlowFactory tff = taskFlowProvider.getFactoryForTaskFlow( type ); TaskFlow tf = tff.create(); TaskFlowServiceAux.setOrderAsDelegate( order, tf, tff ); tf.getOrder().setMyProxyToken( GNDMSResponseHeader.extractTokenFromMap( context ) ); tf.getOrder().setActId( wid ); Map< String, String> ctx = new HashMap<String, String>( 2 ); ctx.put( "DN", dn ); tf.getOrder().setActContext( ctx ); Specifier<Facets> spec = new Specifier<Facets>(); spec.addMapping( "id", tf.getId() ); spec.addMapping( "type", type ); HashMap<String,String> hm = new HashMap<String, String>( spec.getUriMap() ); hm.put( "service", "gorfx" ); spec.setUrl( uriFactory.taskFlowUri( hm, null ) ); ResponseEntity<Facets> re = taskFlowClient.getFacets( type, tf.getId(), dn ); if( re.getStatusCode() == HttpStatus.OK ) spec.setPayload( re.getBody() ); return new ResponseEntity<Specifier<Facets>>( spec, headers, HttpStatus.CREATED ); } public String getBaseUrl() { return baseUrl; } public void setGorfxFacets( Facets gorfxFacets ) { this.gorfxFacets = gorfxFacets; } public Facets getGorfxFacets() { return gorfxFacets; } public ActionProvider getConfigActionProvider() { return configActionProvider; } @Inject public void setConfigActionProvider( ConfigActionProvider configActionProvider ) { this.configActionProvider = configActionProvider; } @Inject public void setTaskFlowProvider( TaskFlowProvider taskFlowProvider ) { logger.debug( "Taskflow provider injected: " + taskFlowProvider.getClass().getName() ); this.taskFlowProvider = taskFlowProvider; } @Inject public void setTaskFlowClient( TaskFlowClient taskFlowClient ) { this.taskFlowClient = taskFlowClient; } }