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

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

Resolved two bugs in synchronization:

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