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

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

Fixed issue #11: export of excel sample data is now column wise

File size: 12.3 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                        e.printStackTrace();
85                        return null
86                        throw new Exception( "Retrieving user details from GSCF failed", e );
87                }
88        }
89
90        /**
91         * Retrieve a list of Studies from the GSCF
92         *
93         * @param sessionToken String
94         *
95         * @return ArrayList
96         */
97        public ArrayList getStudies(String sessionToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception {
98                return this.callGSCF(sessionToken, "getStudies")
99        }
100
101
102        /**
103         * Retrieve a list of Studies from the GSCF
104         *
105         * @param sessionToken String
106         *
107         * @return ArrayList
108         */
109        public ArrayList getStudies(String sessionToken, ArrayList studyTokens ) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
110                return this.callGSCF(sessionToken, "getStudies", [ "studyToken": studyTokens ] );
111        }
112
113        /**
114         * Retrieve a single Study from the GSCF
115         *
116         * @param sessionToken String
117         * @param study Study
118         *
119         * @return ArrayList
120         */
121        public def getStudy(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
122                def list
123
124                try {
125                        list = this.callGSCF(sessionToken, "getStudies", ["studyToken": studyToken])
126                } catch( NotAuthorizedException e ) {
127                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
128                } catch( ResourceNotFoundException e ) {
129                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF" )
130                } // Other exceptions are thrown as they appear
131
132                // Return only the first element of the list, since we are only interested in one study
133                if( list?.size() ) {
134                        return list[0];
135                } else {
136                        return []
137                }
138        }
139
140        /**
141         * Retrieve a list of Assays from the GSCF
142         *
143         * @param sessionToken String
144         * @param study Study
145         *
146         * @return ArrayList
147         */
148        public ArrayList getAssays(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
149                try {
150                        return this.callGSCF(sessionToken, "getAssays", ["studyToken": studyToken])
151                } catch( NotAuthorizedException e ) {
152                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
153                } catch( ResourceNotFoundException e ) {
154                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF" )
155                } // Other exceptions are thrown as they appear
156        }
157
158        /**
159         * Retrieve a single Assay from the GSCF
160         *
161         * @param sessionToken String
162         * @param study Study
163         * @param assay Assay
164         *
165         * @return ArrayList
166         */     
167        public def getAssay(String sessionToken, String studyToken, String assayToken )throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
168                def list
169                try {
170                        list = this.callGSCF(sessionToken, "getAssays", ["studyToken": studyToken, "assayToken": assayToken])
171                } catch( NotAuthorizedException e ) {
172                        throw new NotAuthorizedException( "User is not authorized to access study with token " + studyToken )
173                } catch( ResourceNotFoundException e ) {
174                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
175                } // Other exceptions are thrown as they appear
176
177                // Return only the first element of the list, since we are only interested in one assay
178                if( list.size() == 0 ) {
179                        return []
180                } else {
181                        return list[0];
182                }
183        }
184
185       
186        /**
187         * Retrieve a single Sample from the GSCF
188         *
189         * @param sessionToken String
190         * @param assay Assay
191         * @param sample Sample
192         *
193         * @return ArrayList
194         */
195        public def getSample(String sessionToken, String assayToken, String sampleToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
196                def list
197
198                try {
199                        list = this.callGSCF(sessionToken, "getSamples", ["assayToken": assayToken , "sampleToken": sampleToken])
200                } catch( NotAuthorizedException e ) {
201                        throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken )
202                } catch( ResourceNotFoundException e ) {1
203                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
204                } // Other exceptions are thrown as they appear
205
206                // Return only the first element of the list, since we are only interested in one sample
207                if( list.size() == 0 )
208                        return []
209                else
210                        return list[ 0 ];
211
212        }
213       
214        /**
215         * Retrieve a list of Samples from the GSCF
216         *
217         * @param sessionToken String
218         * @param assay Assay (parameter assay is optional, only used when you want to limit the list of samples of an Assay within a Study)
219         *
220         * @return ArrayList
221         */
222        public ArrayList getSamples(String sessionToken, String assayToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
223                // Samples of a Study limited to a single Assay
224                try {
225                        return this.callGSCF(sessionToken, "getSamples", ["assayToken":assayToken])
226                } catch( NotAuthorizedException e ) {
227                        throw new NotAuthorizedException( "User is not authorized to access study for assay with token " + assayToken )
228                } catch( ResourceNotFoundException e ) {1
229                        throw new ResourceNotFoundException( "Assay with token " + assayToken + " not found in GSCF" )
230                } // Other exceptions are thrown as they appear
231
232        }
233
234        /**
235         * Retrieve a list of samples from the GSCF
236         *
237         * @param sessionToken String
238         * @param sampleTokens List of sampleTokens
239         *
240         * @return ArrayList
241         */
242        public def getSamples(String sessionToken, List sampleTokens) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
243                def list
244
245                try {
246                        list = this.callGSCF(sessionToken, "getSamples", ["sampleToken": sampleTokens])
247                } catch( NotAuthorizedException e ) {
248                        throw new NotAuthorizedException( "User is not authorized to access samples" )
249                } catch( ResourceNotFoundException e ) {
250                        throw new ResourceNotFoundException( "Samples with token " + sampleTokens + " not found in GSCF" )
251                } // Other exceptions are thrown as they appear
252
253                // Return only the first element of the list, since we are only interested in one sample
254                return list
255        }
256
257
258        /**
259         * Retrieve study access
260         *
261         * @param sessionToken String
262         * @param study Study
263         *
264         * @return ArrayList
265         */
266        public HashMap getAuthorizationLevel(String sessionToken, String studyToken) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception  {
267                ArrayList list
268
269                try {
270                        list = this.callGSCF(sessionToken, "getAuthorizationLevel", ["studyToken":studyToken])
271                } catch( ResourceNotFoundException e ) {
272                        throw new ResourceNotFoundException( "Study with token " + studyToken + " not found in GSCF")
273                } // Other exceptions are thrown as they appear
274
275                HashMap map = [:]
276
277                // Convert the list back to a hashmap
278                list.each { entry ->
279                        map[ entry.key ] = entry.value
280                }
281
282                return map
283        }
284
285        /**
286         * Base URL of GSCF Rest Controller/API
287         *
288         * @return      url String
289         */
290        private String restURL() {
291                return "${config.gscf.baseURL}/rest"
292        }
293
294        /**
295         * Call GSCF Service via a secure call
296         *
297         * @param       sessionToken Session token for connection to GSCF
298         * @param       restMethod Method to call on GSCF rest controller
299         * @param       restParams Parameters to provide to the GSCF rest method
300         *
301         * @return      ArrayList
302         */
303        private ArrayList callGSCF(String sessionToken, String restMethod, HashMap restParams = [:]) throws BadRequestException, NotAuthenticatedException, NotAuthorizedException, ResourceNotFoundException, Exception {
304
305                def gscfResponse = []
306
307                //construct addr
308                def addr = "${this.restURL()}/${restMethod}?moduleURL=${this.moduleURL()}&consumer=${this.consumerID()}&token=${sessionToken}"
309
310                // concat all Rest Call specific arguments behind addr
311                restParams.each {parameter ->
312                        // If a list is given as value, the parameter should show up multiple times
313                        if( parameter.value instanceof Collection ) {
314                                parameter.value.each { value ->
315                                        addr += "&${parameter.key}=" + value.toString().encodeAsURL()
316                                }
317                        } else {
318                                addr += "&${parameter.key}=" + parameter.value.toString().encodeAsURL()
319                        }
320                }
321
322                // Open the connection
323                def connection;
324
325                try {
326                        log.info("GSCF REST-CALL: ${addr}")
327                        connection = addr.toURL().openConnection()
328                } catch( Exception e ) {
329                        log.error("GSCF Call failed when calling service: ${addr}",e)
330                        throw new Exception( "Calling GSCF Rest method ${restMethod} failed. Please check log for more information.", e )
331                }
332               
333                switch( connection.responseCode ) {
334                        case 400:       // Bad request
335                                throw new BadRequestException( "Bad request made to GSCF server: " + addr );
336                                break;
337                        case 401:       // Not allowed to access this resource
338                                throw new NotAuthorizedException( "User is not authorized to access the resource " + addr );
339                                break;
340                        case 403:       // Incorrect authentication
341                                println "Not authenticated (" + addr + "): " + connection.responseCode
342                                throw new NotAuthenticatedException( "User is not authenticated with GSCF." );
343                                break;
344                        case 404:       // Resource not found
345                                throw new ResourceNotFoundException( "Specified resource could not be found: "  + addr );
346                                break;
347                        case 500:       // Internal server error
348                                throw new Exception( "An unknown error occured when calling service: " + addr + " - " + connection.responseMessage )
349                                break;
350                        default:
351                                try {
352                                        def jsonResponse = JSON.parse(connection.content.text)
353                                        jsonResponse.each { jsonProperty ->
354                                                gscfResponse << jsonProperty
355                                        }
356
357                                        log.info("GSCF REST-RESP: ${jsonResponse}")
358                                } catch(Exception e) {
359                                        log.error("Parsing GSCF JSON response failed at ${addr}. Reponse was " + connection.content.text,e)
360                                        throw new Exception( "Parsing GSCF JSON response failed at ${addr}.  Please check log for more information.", e )
361                                }
362                                break;
363                }
364
365                return gscfResponse
366        }
367
368
369        /**
370         * Consumer ID for connection to of GSCF Rest Controller/API
371         *
372         * @return      consumerID      String
373         */
374        private String consumerID() {
375                return config.metagenomics.consumerID
376        }
377
378        /**
379         * Module URL for connection to of GSCF Rest Controller/API
380         *
381         * @return      moduleURL       String
382         */
383        private String moduleURL() {
384                return config.grails.serverURL
385        }
386
387}
Note: See TracBrowser for help on using the repository browser.