source: trunk/src/groovy/dbnp/rest/common/CommunicationManager.groovy @ 636

Last change on this file since 636 was 636, checked in by jahn, 11 years ago

Updated CommunicationManager? to support URL generation for SAM views.
The REST methods and Grails views used in inter module communcation
are now added in the CommunicationManager? from BootStrap?.

File size: 7.2 KB
Line 
1package dbnp.rest.common
2
3import grails.converters.JSON
4import java.net.URLEncoder
5import org.codehaus.groovy.grails.web.json.*
6
7
8/**  CommunicationManager
9 *
10 *   @author Jahn
11 *
12 *   This class manages communication between dbNP modules such as GSCF and SAM.
13 *   By communication we mean two ways of exchanging information: (1) via Rest resources,
14 *   and (2) via Grails views that a module can make available to another module.
15 *
16 *   For Rest communication this class implements a Rest client that fetches data
17 *   from other modules' Rest resources. The Rest implementation transfers data in JSON.
18 *
19 *   Note: Do not use this class directly to fetch data. Instead use your module's
20 *   rest wrapper methods. Use this module, to create these rest wrapper methods.
21 *   For instance, use dbnp.rest.sam.registerRestWrapperMethodsGSCFtoSAM to register new methods
22 *   for accessing GSCF's Rest service in SAM; your new method shoud then use this class.
23 */
24
25
26class CommunicationManager {
27
28    def static Encoding     = "UTF-8" 
29    def public static SAMServerURL = "localhost:8182/sam"
30    def public static GSCFServerURL = "localhost:8080/gscf"
31
32     
33
34    /**
35     * Get the results of provided by a rest Rest resource.
36     *
37     * @params String resource The name of the resource, e.g. importer/pages
38     * @params Map params      A Map of parmater names and values., e.g. ['externalAssayID':12]
39     * @return String url   
40     */
41    public static Object getRestResource( RestServerURL, resource, params ) {
42                def url = getRestURL( RestServerURL, resource, params )
43                return  JSON.parse( url.newReader() )
44    }
45
46
47    /**
48     * Convenience method for constructing URLs for SAM that need parameters.
49     * Note that parameters are first convereted to strings by calling their toString() method
50     * and then Encoded to protect special characters.
51     *
52     * @params String resource The name of the resource, e.g. importer/pages
53     * @params Map params      A Map of parmater names and values., e.g. ['externalAssayID':12]
54     * @return String url   
55     */
56    public static URL getRestURL( RestServerURL, resource, params ) {
57        def url = RestServerURL + '/' + resource
58                def first = true
59                params.each { name, value ->
60                        if(first) {
61                                first = false
62                                url += '/nil?' + name + "=" + URLEncoder.encode( value.toString(), Encoding )
63                        }
64                        else { 
65                                url += '&' + name + "=" + URLEncoder.encode( value.toString(), Encoding  )
66                        }
67                }
68                return new URL( url )
69    }
70
71
72
73    /**
74     * This method dynamically adds a static method to the CommunicationManager.
75     * 
76     * @params String serverURL         A rest server URL.
77     * @params String restName          The name of a rest resource on the server.     
78     * @params Map params               A list of parameter names to be passed to this resource.
79     * @return String url   
80     * 
81     * Given a rest resource at serverURL called resourceName, we register a static method
82     * for the CommunicationManager. The new method has the same name and arity as the resource.
83     * 
84     * Example: Suppopse http://localhost:8080/gscf/rest/getSamples is a Rest resource.
85     * 
86     * In our grails app, we would like to connect to this service. We want to have a
87     * method getSamples() that fetches the result from the service. We do this by calling
88     * 
89     *          CommunicationManager.addRestWrapper( 'http://localhost:8080/gscf/rest', 'getSamples', ['externalStudyID'] )
90     * 
91     * This registers a new method:
92     * 
93         *               public static Object CommunicationManager.getSamples( Object arg )
94     * 
95     * This method has arrity 1 and expects to be given a map. The map is the parameter map
96     * of the rest service getSamples. It maps parameter called "externalStudyID" to some object
97     * that is passed. So, it can be called like as follows:
98     * 
99     *      def sampleList = CommunicationManager.getSamples( [externalStudyID:4711] )
100     * 
101     *  The call will deliver the results of the parameterized rest resource given at:
102     * 
103     *          http://localhost:8080/gscf/rest/nil?externalStudyID=4711
104     *
105     */
106
107    public static addRestWrapper( serverURL, restName, params = [] ) {
108                CommunicationManager.metaClass.registerStaticMethod( restName ) { Object [] strangeGroovyArgs ->
109                        def map = [:]
110                    def args = strangeGroovyArgs[0]        // groovy nests the parameters of the methods in some other array
111                        for( i in 0..(params.size-1) ) {
112                                def param = params[i]
113                            map[param] = args[i]
114                        }
115                        return getRestResource( serverURL, restName, map )
116                }
117    }
118
119
120
121    /**
122     * This method dynamically registers a static method to the CommunicationManager. The new method
123     * gives url for a Grails view on some server and takes as arguments the arguments required
124     * as params by the view.
125     * 
126     * @params String methodname        The name for method to be registered.
127     * @params String serverURL         The server's URL.
128     * @params String viewName          The view's name, e.g., '/Assay/show'
129     * @params Map params               The parameter list required by this view.
130     * @return String URL
131     * 
132     */ 
133    public static addViewWrapper( methodName, serverURL, viewName, params = [] ) {
134
135                CommunicationManager.metaClass.registerStaticMethod( methodName ) { Object [] strangeGroovyArgs ->
136                        def map = [:]
137                    def args = strangeGroovyArgs[0]        // groovy nests the parameters of the methods in some other array
138                        for( i in 0..(params.size-1) ) {
139                                def param = params[i]
140                            map[param] = args[i]
141                        }
142                        return getRestURL( serverURL, viewName, map )
143                }
144    }
145
146
147    /**
148     *  This creates on run time new methods for accessing Rest resources that GSCF provides for SAM.
149     *  This method should be called in grails-app/conf/BootStrap.groovy in the SAM module.
150     */ 
151    public static registerRestWrapperMethodsGSCFtoSAM() {
152        def url = GSCFServerURL
153                addRestWrapper( url , 'getStudies' )
154                addRestWrapper( url , 'getSubjects', ['externalStudyID'] )
155                addRestWrapper( url , 'getAssays',   ['externalStudyID'] )
156                addRestWrapper( url , 'getSamples',  ['externalAssayID'] )
157    }
158
159
160    /**
161     *  This method creates on run time new methods for accessing Grails views that SAM provides for GSCF.
162     *  This method should be called in grails-app/conf/BootStrap.groovy in the GSCF module.
163     */ 
164    public static registerRestWrapperMethodsSAMtoGSCF() {
165                def url = SAMServerURL
166
167                // register method that links to the SAM view for importing a SimpleAssay.
168        // parameters: externalAssayID, an externalAssayID
169                addViewWrapper( 'getAssayImportURL', url, 'importer/pages', ['externalAssayID', 'externalStudyID'] )
170
171                // register method that links to the SAM view for showing a SimpleAssay
172        // parameters: externalAssayID
173                addViewWrapper( 'getAssayShowURL', url, 'simpleAssay/show', ['externalAssayID'] )
174
175                // register method that links to the SAM view for editing a SimpleAssay
176        // parameters: externalAssayID
177                addViewWrapper( 'getAssayEditURL', url, 'simpleAssay/show', ['externalAssayID'] )
178
179                // register method that links to the SAM view for editing a SimpleAssay
180        // parameters: externalAssayID
181                addViewWrapper( 'getMeasurementTypesURL', url, 'simpleAssayMeasurementType/list', ['externalStudyID'] )
182    }
183
184}
Note: See TracBrowser for help on using the repository browser.