source: trunk/grails-app/controllers/RestController.groovy @ 934

Last change on this file since 934 was 934, checked in by j.saito@…, 11 years ago

Adjusted CommunicationManager? to match closer with CommunicationManager? in SAM.
Added support for "token" notation of REST services directly in Study and Assay domain classes.
Cleaned up and tested communication further.

File size: 9.9 KB
Line 
1/**
2 * RestController
3 *
4 * This controler provides a REST service.
5 * The names of the RESET resources are the same as the names of this
6 * controller's actions. E.g., the resources called getStudies simply
7 * corresponds to the action getStudies. Some of the resources are parameterized.
8 * The parameters are passed as parameters in the url and are available in the
9 * params respecting Grails' conventions. In this file, we adher to the javadoc 
10 * convention for describing parameters ("@param"), but actually we mean
11 * key-value pairs in the params object of each Grails action we comment on.
12 *
13 * @author      Jahn-Takeshi Saito
14 * @since       20100601
15 *
16 */
17
18import dbnp.studycapturing.Study
19import dbnp.studycapturing.Assay
20import grails.converters.*
21import nl.metabolomicscentre.dsp.http.BasicAuthentication
22
23
24class RestController {
25
26
27
28       /**************************************************/
29      /** Rest resources for Simple Assay Module (SAM) **/
30     /**************************************************/
31
32        def authService
33        def beforeInterceptor = [action:this.&auth,except:["isUser"]]
34        def credentials
35        def requestUser
36
37        /**
38         * Authorization closure, which is run before executing any of the REST resource actions
39         * It fetches a username/password combination from basic HTTP authentication and checks whether
40         * that is an active (nimble) account
41         * @return
42         */
43        private def auth() {
44
45            credentials = BasicAuthentication.credentialsFromRequest(request)
46                requestUser = authService.authUser(credentials.u,credentials.p)
47                if(!requestUser) {
48                    response.sendError(403)
49                return false
50            }
51                else {
52                        return true
53                }
54        }
55
56        /**
57        * REST resource for data modules.
58        * Username and password should be supplied via HTTP Basic Authentication.
59        * Determines whether the given user/password combination is a valid GSCF account.
60        *
61        * @return bool {"authenticated":true} when user/password is a valid GSCF account, {"authenticated":false} otherwise.
62        */
63        def isUser= {
64                boolean isUser
65                credentials = BasicAuthentication.credentialsFromRequest(request)
66                def reqUser = authService.authUser(credentials.u,credentials.p)
67                if (reqUser) {
68                        isUser = true
69                }
70                else {
71                        isUser = false
72                }
73                def reply = ['authenticated':isUser]
74                render reply as JSON
75        }
76
77        /**
78        * REST resource for data modules.
79        * Username and password should be supplied via HTTP Basic Authentication.
80        * Provide a list of all studies owned by the supplied user.
81        *
82        * @return JSON object list containing 'studyToken', and 'name' (title) for each study
83        */
84        def getStudies = {
85                List studies = [] 
86                def user = params.user
87                Study.findAllByOwner(requestUser).each { study ->
88                        studies.push( [ 'title':study.title, 'studyToken':study.getToken()] )
89                }
90                render studies as JSON
91        }
92
93
94        /**
95        * REST resource for data modules.
96        * Username and password should be supplied via HTTP Basic Authentication.
97        * Provide a list of all subjects belonging to a study.
98        *
99        * @param studyToken String The external study id (code) of the target GSCF Study object
100        * @return JSON object list of subject names
101        */
102        def getSubjects = {
103                List subjects = [] 
104                if( params.studyToken ) {
105                        def id = params.studyToken
106                        def study = Study.find( "from Study as s where s.code=?", [id])
107                        if(study) study.subjects.each { subjects.push it.name }
108                }
109                render subjects as JSON
110        }
111
112
113        /**
114        * REST resource for data modules.
115        * Username and password should be supplied via HTTP Basic Authentication.
116        * Provide a list of all assays for a given study
117        *
118        * Example call of the getAssays REST resource:
119        * http://localhost:8080/gscf/rest/getAssays?studyToken=PPSH&moduleURL=http://localhost:8182/sam
120        *
121        * @param stuyToken String The external study id (code) of the target GSCF Study object
122        * @param moduleURL String The base URL of the calling dbNP module
123        * @return list of assays in the study as JSON object list, filtered to only contain assays
124        *         for the specified module, with 'assayToken' and 'name' for each assay
125        */
126        def getAssays = {
127                List assays = [] 
128                if( params.studyToken ) {
129                        def id = params.studyToken
130                        def study = Study.find( "from Study as s where s.code=?", [id] )
131                        if(study && study.owner == requestUser) study.assays.each{ assay ->
132                                //if (assay.module.url.equals(params.moduleURL)) {
133                                def map = ['name':assay.name, 'assayToken':assay.getToken()]
134                                        assays.push( map )
135                                //}
136                        }
137                }
138                render assays as JSON
139        }
140
141
142        /**
143        * REST resource for data modules.
144        * Username and password should be supplied via HTTP Basic Authentication.
145        * Provide all samples of a given Assay. The result is an enriched list with additional information for each sample.
146        *
147        * @param assayToken String (assayToken of some Assay in GSCF)
148        * @return As a JSON object list, for each sample in that assay:
149        * @return 'name' (Sample name, which is unique)
150        * @return 'material' (Sample material)
151        * @return 'subject' (The name of the subject from which the sample was taken)
152        * @return 'event' (the name of the template of the SamplingEvent describing the sampling)
153        * @return 'startTime' (the time the sample was taken relative to the start of the study, as a string)
154        */
155        def getSamples = {
156                def items = []
157                if( params.assayToken ) {
158                        def assay = Assay.find( "from Assay as a where externalAssayID=?",[params.assayToken])
159                        assay.getSamples().each { sample ->
160                                def item = [ 
161                                        'sampleToken' : sample.name,
162                                        'material'        : sample.material.name,
163                                        'subject'         : sample.parentSubject.name,
164                                        'event'           : sample.parentEvent.template.name,
165                                        'startTime'       : sample.parentEvent.getStartTimeString()
166                                ]
167                                items.push item
168                        }
169                }
170                render items as JSON
171        }
172
173
174        /**
175        * REST resource for dbNP modules.
176        *
177        * @param studyToken String, the external identifier of the study
178        * @return List of all fields of this study
179        * @return
180        *
181        * Example REST call (without authentication):
182    * http://localhost:8080/gscf/rest/getStudy/study?studyToken=PPSH
183    *
184        * Returns the JSON object:
185        * {"title":"NuGO PPS human study","studyToken":"PPSH","startDate":"2008-01-13T23:00:00Z",
186        * "Description":"Human study performed at RRI; centres involved: RRI, IFR, TUM, Maastricht U.",
187        * "Objectives":null,"Consortium":null,"Cohort name":null,"Lab id":null,"Institute":null,
188        * "Study protocol":null}
189        */
190        def getStudy = {
191                def items = [:]
192                if( params.studyToken ) {
193                        def study = Study.find( "from Study as s where code=?",[params.studyToken])
194                        study.giveFields().each { field ->
195                                def name = field.name
196                                def value = study.getFieldValue( name )
197                                items[name] = value
198                        }
199        }
200                render items as JSON
201        }
202
203
204
205        /**
206        * REST resource for dbNP modules.
207        *
208        * @param assayToken String, the external identifier of the study
209        * @return List of all fields of this assay
210        *
211        * Example REST call (without authentication):
212    * http://localhost:8080/gscf/rest/getAssay/assay?assayToken=PPS3_SAM
213    *
214        * Returns the JSON object: {"name":"Lipid profiling","module":{"class":"dbnp.studycapturing.AssayModule","id":1,
215        * "name":"SAM module for clinical data","platform":"clinical measurements","url":"http://sam.nmcdsp.org"},
216        * "assayToken":"PPS3_SAM","Description":null}
217        */
218        def getAssay = {
219                def items = [:]
220                if( params.assayToken ) {
221                        def assay = Assay.find( "from Assay as a where externalAssayID=?",[params.assayToken])
222                        assay.giveFields().each { field ->
223                                def name = field.name
224                                def value = assay.getFieldValue( name )
225                                items[name] = value
226                        }
227        }
228                render items as JSON
229        }
230
231
232
233        /**
234        * REST resource for data modules.
235        * Username and password should be supplied via HTTP Basic Authentication.
236        * One specific sample of a given Assay.
237        *
238        * @param assayToken String (id of some Assay in GSCF)
239        * @return As a JSON object list, for each sample in that assay:
240        * @return 'name' (Sample name, which is unique)
241        * @return 'material' (Sample material)
242        * @return 'subject' (The name of the subject from which the sample was taken)
243        * @return 'event' (the name of the template of the SamplingEvent describing the sampling)
244        * @return 'startTime' (the time the sample was taken relative to the start of the study, as a string)
245        *
246        * Example REST call (without authentication):
247    * http://localhost:8080/gscf/rest/getSample/sam?assayToken=PPS3_SAM&sampleToken=A30_B
248    *
249        * Returns the JSON object:
250        * {"subject":"A30","event":"Liver extraction","startTime":"1 week, 1 hour",
251        * "sampleToken":"A30_B","material":{"class":"dbnp.data.Term","id":6,"accession":"BTO:0000131",
252        * "name":"blood plasma","ontology":{"class":"Ontology","id":2}},"Remarks":null,
253        * "Text on vial":"T70.91709057820039","Sample measured volume":null}
254        */
255        def getSample = {
256                def items = [:]
257                if( params.assayToken && params.sampleToken ) {
258                        def assay = Assay.find( "from Assay as a where externalAssayID=?",[params.assayToken])
259                        assay.getSamples().each { sample ->
260                                if( sample.name == params.sampleToken ) {
261                                        items = [ 
262                                                'subject'             : sample.parentSubject.name,
263                                                'event'               : sample.parentEvent.template.name,
264                                                'startTime'           : sample.parentEvent.getStartTimeString()
265                                        ]
266                                        sample.giveFields().each { field ->
267                                                def name = field.name
268                                                def value = sample.getFieldValue( name )
269                                                items[name] = value
270                        }
271                                }
272                        }
273                }
274                render items as JSON
275        }
276
277        /**
278        * REST resource for dbNP modules.
279        *
280        * @param studyToken String, the external identifier of the study
281        * @return List of all fields of this study
282        * @return
283        *
284        * Example REST call (without authentication):
285        * http://localhost:8080/gscf/rest/getStudy/study?studyToken=PPSH
286        *
287        * Returns the JSON object:
288        * {"title":"NuGO PPS human study","studyToken":"PPSH","startDate":"2008-01-13T23:00:00Z",
289        * "Description":"Human study performed at RRI; centres involved: RRI, IFR, TUM, Maastricht U.",
290        * "Objectives":null,"Consortium":null,"Cohort name":null,"Lab id":null,"Institute":null,
291        * "Study protocol":null}
292        */
293        def getAuthorizationLevel = {
294                def items = [:]
295                /*if( params.studyToken ) {
296                        def study = Study.find( "from Study as s where code=?",[params.studyToken])
297                       
298                }
299        render items as JSON*/
300        }
301}
Note: See TracBrowser for help on using the repository browser.