source: trunk/grails-app/services/nl/tno/metagenomics/integration/GscfService.groovy @ 19

Last change on this file since 19 was 19, checked in by robert@…, 8 years ago

Resolved session timeouts as mentioned in #20

File size: 12.5 KB
Line 
1package nl.tno.metagenomics.integration
2
3import grails.converters.JSON
4import org.codehaus.groovy.grails.commons.ConfigurationHolder
5import org.springframework.web.context.request.RequestContextHolder;
6
7/**
8 * EDP (External Data Provider) for GSCF
9 *
10 * @author Robert Horlings (robert@isdat.nl)
11 * @version 0.9
12 * @see nmcdsp.GscfService
13 */
14class GscfService {
15        def config = ConfigurationHolder.config
16
17        static transactional = true
18
19        /**
20         * Returns the URL to let the user login at GSCF
21         *
22         * @param params        Parameters of the action called
23         * @param token         Session token
24         * @return                      URL to redirect the user to
25         */
26        public String urlAuthRemote( def params, def token ) {
27                def redirectURL = "${config.gscf.baseURL}/login/auth_remote?moduleURL=${this.moduleURL()}&consumer=${this.consumerID()}&token=${token}&"
28
29                def returnUrl = config.grails.serverURL
30                if (params.controller != null){
31                        returnUrl += "/${params.controller}"
32                        if (params.action != null){
33                                returnUrl += "/${params.action}"
34                                if (params.id != null){
35                                        returnUrl += "/${params.id}"
36                                }
37                        }
38                }
39
40                // Append other parameters
41                returnUrl += "?" + params.collect {
42                        if( it.key != "controller" && it.key != "action" && it.key != "id" )
43                                return it.key.toString().encodeAsURL() + "=" + it.value.toString().encodeAsURL();
44                        else
45                                return ""
46                }.findAll { it }.join( "&" );
47               
48                return redirectURL + "returnUrl=" + returnUrl.encodeAsURL();
49        }
50
51        /**
52         * Returns the url to show details of a study in GSCF
53         *
54         * @param study         Study object to view in GSCF
55         * @return                      URL to redirect the user to
56         */
57        public String urlViewStudy( String studyToken ) {
58                return "${config.gscf.baseURL}/study/showByToken/" + studyToken
59        }
60
61        /**
62         * Returns the url to add a new study in GSCF
63         *
64         * @return                      URL to redirect the user to
65         */
66        public String urlAddStudy( String studyToken ) {
67                return config.gscf.baseURL + config.gscf.addStudyPath
68        }
69
70        /**
71         * Retrieves the currently logged in user from GSCF
72         *
73         * @param sessionToken String
74         *
75         * @return Map
76         */
77        public Map getUser(String sessionToken) throws Exception {
78                def user = [:]
79                try {
80                        this.callGSCF(sessionToken, "getUser").each {
81                                user[ it.key ] = it.value;
82                        }
83                        return user
84                } catch( Exception e ) {
85                        e.printStackTrace();
86                        return null
87                        throw new Exception( "Retrieving user details from GSCF failed", e );
88                }
89        }
90
91        /**
92         * Retrieve a list of Studies from the GSCF
93         *
94         * @param sessionToken String
95         *
96         * @return ArrayList
97         */
98        public ArrayList getStudies(String sessionToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception {
99                return this.callGSCF(sessionToken, "getStudies")
100        }
101
102
103        /**
104         * Retrieve a list of Studies from the GSCF
105         *
106         * @param sessionToken String
107         *
108         * @return ArrayList
109         */
110        public ArrayList getStudies(String sessionToken, ArrayList studyTokens ) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
111                return this.callGSCF(sessionToken, "getStudies", [ "studyToken": studyTokens ] );
112        }
113
114        /**
115         * Retrieve a single Study from the GSCF
116         *
117         * @param sessionToken String
118         * @param study Study
119         *
120         * @return ArrayList
121         */
122        public def getStudy(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
123                def list
124
125                try {
126                        list = this.callGSCF(sessionToken, "getStudies", ["studyToken": studyToken])
127                } catch( NotAuthorizedException e ) {
128                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
129                } catch( ResourceNotFoundException e ) {
130                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF" )
131                } // Other exceptions are thrown as they appear
132
133                // Return only the first element of the list, since we are only interested in one study
134                if( list?.size() ) {
135                        return list[0];
136                } else {
137                        return []
138                }
139        }
140
141        /**
142         * Retrieve a list of Assays from the GSCF
143         *
144         * @param sessionToken String
145         * @param study Study
146         *
147         * @return ArrayList
148         */
149        public ArrayList getAssays(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
150                try {
151                        return this.callGSCF(sessionToken, "getAssays", ["studyToken": studyToken])
152                } catch( NotAuthorizedException e ) {
153                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
154                } catch( ResourceNotFoundException e ) {
155                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF" )
156                } // Other exceptions are thrown as they appear
157        }
158
159        /**
160         * Retrieve a single Assay from the GSCF
161         *
162         * @param sessionToken String
163         * @param study Study
164         * @param assay Assay
165         *
166         * @return ArrayList
167         */     
168        public def getAssay(String sessionToken, String studyToken, String assayToken )throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
169                def list
170                try {
171                        list = this.callGSCF(sessionToken, "getAssays", ["studyToken": studyToken, "assayToken": assayToken])
172                } catch( NotAuthorizedException e ) {
173                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
174                } catch( ResourceNotFoundException e ) {
175                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
176                } // Other exceptions are thrown as they appear
177
178                // Return only the first element of the list, since we are only interested in one assay
179                if( list.size() == 0 ) {
180                        return []
181                } else {
182                        return list[0];
183                }
184        }
185
186       
187        /**
188         * Retrieve a single Sample from the GSCF
189         *
190         * @param sessionToken String
191         * @param assay Assay
192         * @param sample Sample
193         *
194         * @return ArrayList
195         */
196        public def getSample(String sessionToken, String assayToken, String sampleToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
197                def list
198
199                try {
200                        list = this.callGSCF(sessionToken, "getSamples", ["assayToken": assayToken , "sampleToken": sampleToken])
201                } catch( NotAuthorizedException e ) {
202                        throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken )
203                } catch( ResourceNotFoundException e ) {1
204                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
205                } // Other exceptions are thrown as they appear
206
207                // Return only the first element of the list, since we are only interested in one sample
208                if( list.size() == 0 )
209                        return []
210                else
211                        return list[ 0 ];
212
213        }
214       
215        /**
216         * Retrieve a list of Samples from the GSCF
217         *
218         * @param sessionToken String
219         * @param assay Assay (parameter assay is optional, only used when you want to limit the list of samples of an Assay within a Study)
220         *
221         * @return ArrayList
222         */
223        public ArrayList getSamples(String sessionToken, String assayToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
224                // Samples of a Study limited to a single Assay
225                try {
226                        return this.callGSCF(sessionToken, "getSamples", ["assayToken":assayToken])
227                } catch( NotAuthorizedException e ) {
228                        throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken )
229                } catch( ResourceNotFoundException e ) {1
230                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
231                } // Other exceptions are thrown as they appear
232
233        }
234
235        /**
236         * Retrieve a list of samples from the GSCF
237         *
238         * @param sessionToken String
239         * @param sampleTokens List of sampleTokens
240         *
241         * @return ArrayList
242         */
243        public def getSamples(String sessionToken, List sampleTokens) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
244                def list
245
246                try {
247                        list = this.callGSCF(sessionToken, "getSamples", ["sampleToken": sampleTokens])
248                } catch( NotAuthorizedException e ) {
249                        throw new NotAuthorizedException( "User is not authorized to access samples" )
250                } catch( ResourceNotFoundException e ) {
251                        throw new ResourceNotFoundException( "Samples with token " + sampleTokens + " not found in GSCF" )
252                } // Other exceptions are thrown as they appear
253
254                // Return only the first element of the list, since we are only interested in one sample
255                return list
256        }
257
258
259        /**
260         * Retrieve study access
261         *
262         * @param sessionToken String
263         * @param study Study
264         *
265         * @return ArrayList
266         */
267        public HashMap getAuthorizationLevel(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
268                ArrayList list
269
270                try {
271                        list = this.callGSCF(sessionToken, "getAuthorizationLevel", ["studyToken":studyToken])
272                } catch( ResourceNotFoundException e ) {
273                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF")
274                } // Other exceptions are thrown as they appear
275
276                HashMap map = [:]
277
278                // Convert the list back to a hashmap
279                list.each { entry ->
280                        map[ entry.key ] = entry.value
281                }
282
283                return map
284        }
285
286        /**
287         * Base URL of GSCF Rest Controller/API
288         *
289         * @return      url String
290         */
291        private String restURL() {
292                return "${config.gscf.baseURL}/rest"
293        }
294
295        /**
296         * Call GSCF Service via a secure call
297         *
298         * @param       sessionToken Session token for connection to GSCF
299         * @param       restMethod Method to call on GSCF rest controller
300         * @param       restParams Parameters to provide to the GSCF rest method
301         *
302         * @return      ArrayList
303         */
304        private ArrayList callGSCF(String sessionToken, String restMethod, HashMap restParams = [:]) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception {
305
306                def gscfResponse = []
307
308                //construct addr
309                def addr = "${this.restURL()}/${restMethod}?moduleURL=${this.moduleURL()}&consumer=${this.consumerID()}&token=${sessionToken}"
310
311                // concat all Rest Call specific arguments behind addr
312                restParams.each {parameter ->
313                        // If a list is given as value, the parameter should show up multiple times
314                        if( parameter.value instanceof Collection ) {
315                                parameter.value.each { value ->
316                                        addr += "&${parameter.key}=" + value.toString().encodeAsURL()
317                                }
318                        } else {
319                                addr += "&${parameter.key}=" + parameter.value.toString().encodeAsURL()
320                        }
321                }
322
323                // Open the connection
324                def connection;
325
326                try {
327                        log.info("GSCF REST-CALL: ${addr}")
328                        connection = addr.toURL().openConnection()
329                } catch( Exception e ) {
330                        log.error("GSCF Call failed when calling service: ${addr}",e)
331                        throw new Exception( "Calling GSCF Rest method ${restMethod} failed. Please check log for more information.", e )
332                }
333               
334                switch( connection.responseCode ) {
335                        case 400:       // Bad request
336                                throw new BadRequestException( "Bad request made to GSCF server: " + addr );
337                                break;
338                        case 401:       // Not allowed to access this resource
339                                throw new NotAuthorizedException( "User is not authorized to access the resource " + addr );
340                                break;
341                        case 403:       // Incorrect authentication
342                                println "Not authenticated (" + addr + "): " + connection.responseCode
343                               
344                                // The user is logged in to the metagenomics module, but not to GSCF. We log the user out of the module
345                                RequestContextHolder.currentRequestAttributes().getSession().user = null
346                               
347                                throw new NotAuthenticatedException( "User is not authenticated with GSCF." );
348                                break;
349                        case 404:       // Resource not found
350                                throw new ResourceNotFoundException( "Specified resource could not be found: "  + addr );
351                                break;
352                        case 500:       // Internal server error
353                                throw new Exception( "An unknown error occured when calling service: " + addr + " - " + connection.responseMessage )
354                                break;
355                        default:
356                                try {
357                                        def jsonResponse = JSON.parse(connection.content.text)
358                                        jsonResponse.each { jsonProperty ->
359                                                gscfResponse << jsonProperty
360                                        }
361
362                                        log.info("GSCF REST-RESP: ${jsonResponse}")
363                                } catch(Exception e) {
364                                        log.error("Parsing GSCF JSON response failed at ${addr}. Reponse was " + connection.content.text,e)
365                                        throw new Exception( "Parsing GSCF JSON response failed at ${addr}.  Please check log for more information.", e )
366                                }
367                                break;
368                }
369
370                return gscfResponse
371        }
372
373
374        /**
375         * Consumer ID for connection to of GSCF Rest Controller/API
376         *
377         * @return      consumerID      String
378         */
379        private String consumerID() {
380                return config.metagenomics.consumerID
381        }
382
383        /**
384         * Module URL for connection to of GSCF Rest Controller/API
385         *
386         * @return      moduleURL       String
387         */
388        private String moduleURL() {
389                return config.grails.serverURL
390        }
391
392}
Note: See TracBrowser for help on using the repository browser.