root/trunk/grails-app/controllers/RestController.groovy @ 831

Revision 831, 8.8 KB (checked in by keesvb, 4 years ago)

first implementation of user-based REST services, only checks whether a user is owner of a study and returns the studies and assays only for his/her owned studies. The other methods are not secured yet, but ought to go via study or assay.

Line 
1/**
2 * RestControler
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]
34        def credentials
35        def requestUser
36// defined as a regular method so its private
37
38        /**
39         * Authorization closure, which is run before executing any of the REST resource actions
40         * It fetches a username/password combination from basic HTTP authentication and checks whether
41         * that is an active (nimble) account
42         * @return
43         */
44        def auth() {
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
58        /**
59        * REST resource for the Simple Assay Module.
60        * Provide a list of all studies.
61        *
62        *
63        * @return as JSON object list of members externalStudyID, and title for all studies
64        */
65        def getStudies = {
66                List studies = []
67                Study.findAllByOwner(requestUser).each { study ->
68                        studies.push( [ 'externalStudyID': study.code, 'name':study.title ] )
69                }
70                render studies as JSON
71        }
72
73
74        /**
75        * REST resource for the Simple Assay Module.
76        * Provide a list of all subjects belonging to a study.
77        *
78        * @param  externalStudyID
79        * @return as JSON object list of subject names
80        */
81        def getSubjects = {
82                List subjects = []
83                if( params.externalStudyID ) {
84                        def id = params.externalStudyID
85                        def study = Study.find( "from Study as s where s.code=?", [id])
86                        if(study) study.subjects.each { subjects.push it.name }
87                }
88                render subjects as JSON
89        }
90
91
92        /**
93        * REST resource for the Simple Assay Module.
94        * Provide a list of all assays for a given study
95        *
96        * Example call of the getAssays REST resource: http://localhost:8080/gscf/rest/getAssays?externalStudyID=PPSH&moduleURL=http://localhost:8182/sam
97        *
98        * @param externalStudyID The external study id (code) of the target GSCF Study object
99        * @param moduleURL The base URL of the calling dbNP module
100        * @return list of assays in the study as JSON object, filtered to only contain assays for the specified module
101        */
102        def getAssays = {
103                List assays = []
104                if( params.externalStudyID ) {
105                        def study = Study.find( "from Study as s where s.owner=? and s.code=?", [requestUser.getId(), params.externalStudyID])
106                        if(study) study.assays.each{ assay ->
107                                if (assay.module.url.equals(params.moduleURL)) {
108                                def map = ['name':assay.name, 'externalAssayID':assay.externalAssayID]
109                                        assays.push( map )
110                                }
111                        }
112                }
113                render assays as JSON
114        }
115
116
117        /**
118        * REST resource for the Simple Assay Module.
119        * Provide all samples of a given Assay. The result is an enriched list with additional informatin on a sample.
120        *
121        * @param  assayID (externalAssayID of some Assay in GSCF)
122        * @return list of element of  Sample.name x Sample.material x Sample.subject.name x Sample.Event.name x Sample.Event.time
123        */
124        def getSamples = {
125                def items = []
126                if( params.externalAssayID ) {
127                        def id = Long.parseLong(params.externalAssayID)
128                        def assay = Assay.find( "from Assay as a where externalAssayID=?",[id])
129                        assay.getSamples().each { sample ->
130                                def item = [
131                                        'name'                : sample.name,
132                                        'material'            : sample.material.name,
133                                        'subject'             : sample.parentSubject.name,
134                                        'event'               : sample.parentEvent.template.name,
135                                        'startTime'           : sample.parentEvent.getStartTimeString(),
136                                        'externalSampleId': sample.externalSampleId
137                                ]
138                                items.push item
139                        }
140                }
141                render items as JSON
142        }
143
144
145
146
147
148       /****************************/
149      /** Rest resources for DSP **/
150     /****************************/
151   
152       
153        /* still not complete!! */
154
155        /**
156        * REST resource for DSP.
157        * call: gscf/rest/isUser/?username=username&password=password
158        *
159        * @param  String username   
160        * @param  String password
161        * @return bool
162        */
163        def isUser= {
164                def isUser = isVerifiedUser( params )
165                render isUser as JSON
166        }
167
168
169        /* still not complete!! */
170        /**
171        * REST resource for DSP.
172        * call: gscf/rest/listStudies/?username=username&password=password
173        *
174        * @param  String username
175        * @param  String password
176        * @return list of studies
177        */
178        def listStudies = {
179
180                if( !isVerifiedUser( params ) ) {
181                        render [:] as JSON
182                        return
183                }
184
185                List studies = []
186
187                // add code for filtering studies that belong to given user
188                // (use Study.findAll( ... ) 
189                // ...
190                Study.list().each {
191                        def map = ["study_token":it.code, "name":it.name]
192                        studies.add( map )
193                }
194               
195                render studies as JSON
196        }
197
198
199
200        /* still not complete!! */
201        /**
202        * REST resource for DSP.
203        * call: gscf/rest/getStudy/?username=username&password=password&study_token=studytoken
204        *
205        * @param  String username
206        * @param  String password
207        * @param  String study_token
208        * @return list of studies
209        */
210        def getStudy = {
211
212                if( !isVerifiedUser( params ) ) {
213                        render [:] as JSON
214                        return
215                }
216
217                List studyResult = [:]
218                def code   = params.study_token
219
220                def query = "from Study as s where s.code = ?"
221                def study = Study.find( query, code )
222                studyResult = [ 'study_token' : study.code, 'name' : study.name ]
223                        /*  still not complete!!
224                                Add features
225                                        ... study_token:”GHyJeR#g”,
226                                        ... created: “20/06/2010 22:34:52”,
227                                        ... meta: [
228                                        ... greenhouse_id: “GH010938.AB.5”,
229                                        ... greenhouse_type: “lean-to, detached, and ridge and gutter connected” ]
230                        */
231               
232                render studyResult as JSON
233        }
234
235
236
237
238        /* still not complete!! */
239        /**
240        * REST resource for DSP.
241        * call: gscf/rest/listStudySamples/?username=username&password=password&study_token=studytoken
242        *
243        * @param  String user name
244        * @param  String password
245        * @param  String a valid GSCF Study.code
246        * @return List of pairs; each pair is a map with keys sample_token and name and values Study.code and Sample.name.
247        */
248        def listStudySamples = {
249
250                if( !isVerifiedUser( params ) ) {
251                        render [:] as JSON
252                        return
253                }
254
255                List samples = [:]
256                def code = params.study_token
257                def query = "from Samples as s where s.study = ?"
258                def study = Study.find( query, code )
259                if(study) study.samples.each { sample ->
260                        def map = [ sample_token:code, name:sample.name ]
261                        samples.add( map )
262                }
263               
264                render samples as JSON
265        }
266
267
268
269        /* still not complete!! */
270        /**
271        * REST resource for DSP.
272        * call: getStudySample/?username=me&password=123&study_token=GHyJeR#g&sample_name=”AHVJwR”)
273        *
274        * @param  String username
275        * @param  String password
276        * @param  String study_token
277        * @param  String sample_name
278        * @return list of studies
279        */
280        def getStudySample = {
281
282                if( !isVerifiedUser( params ) ) {
283                        render [:] as JSON
284                        return
285                }
286
287                List sample = [:]
288                def code = params.study_token
289                def name = params.sample_name
290
291                def query = "from Sample as s where s.name = ? AND s.parentStudy "
292                def study = Sample.find( query, name )
293                sample = [ 'study_token' : sample.code, 'name' : sample.name ]
294                // samples will have unique identifier strings
295                /*  still not complete!!
296                                Add features
297                                [
298                                        study_token:”GHyJeR#g”,
299                                        sample_token:”AHVJwR”,
300                                        name: “Sample SMPL002”,
301                                        created: “25/06/2010 09:14:32”,
302                                        meta: [ subject: “SUB000294-34942.A”, subject_bmi: “29.3”, ... study_token:”GHyJeR#g”,
303                                        ... created: “20/06/2010 22:34:52”, greenhouse_id: “GH010938.AB.5”,
304                                        greenhouse_type: “lean-to, detached, and ridge and gutter connected”
305                                ]
306                        */
307                render sample as JSON
308        }
309
310
311
312
313        /* still not complete!! */
314        /** Convenience method for isUser and listStudies.
315        *   Verify user and password.
316        *   @param  params object with two map keys: (1) 'username', (2) 'password'
317        *   @param  String password
318        *   @return bool
319        */
320        private isVerifiedUser( params ) {
321                def isVerified = false
322                def user = params?.username
323                def pass = params?.password
324
325                if( user && pass ) {
326                        // insert code for verification of user and
327                        // ...
328                        isVerified = true
329                }
330                return isVerified
331        }
332
333
334
335    /* this is just for testing! */
336    def test = {
337                render( dbnp.rest.common.CommunicationManager.getQueryResultWithOperator("Insulin",">",200) )
338    }
339}
Note: See TracBrowser for help on using the browser.