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

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

Implemented improved authorization (#16)
Built in select all checkboxes (#25)

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