|
27 | 27 | class TornadoService(BaseRequestHandler): # pylint: disable=abstract-method
|
28 | 28 | """
|
29 | 29 | Base class for all the sevices handlers.
|
30 |
| - It directly inherits from :py:class:`DIRAC.Core.Tornado.Server.BaseRequestHandler.BaseRequestHandler` |
31 | 30 |
|
32 |
| - Each HTTP request is served by a new instance of this class. |
| 31 | + For compatibility with the existing :py:class:`DIRAC.Core.DISET.TransferClient.TransferClient`, |
| 32 | + the handler can define a method ``export_streamToClient``. This is the method that will be called |
| 33 | + whenever ``TransferClient.receiveFile`` is called. It is the equivalent of the DISET ``transfer_toClient``. |
| 34 | + Note that this is here only for compatibility, and we discourage using it for new purposes, as it is |
| 35 | + bound to disappear. |
33 | 36 |
|
34 |
| - In order to create a handler for your service, it has to |
35 |
| - follow a certain skeleton:: |
| 37 | + In order to create a handler for your service, it has to follow a certain skeleton. |
36 | 38 |
|
37 |
| - from DIRAC.Core.Tornado.Server.TornadoService import TornadoService |
38 |
| - class yourServiceHandler(TornadoService): |
| 39 | + .. code-block:: python |
39 | 40 |
|
40 |
| - # Called only once when the first |
41 |
| - # request for this handler arrives |
42 |
| - # Useful for initializing DB or so. |
43 |
| - # You don't need to use super or to call any parents method, it's managed by the server |
44 |
| - @classmethod |
45 |
| - def initializeHandler(cls, infosDict): |
46 |
| - '''Called only once when the first |
47 |
| - request for this handler arrives |
48 |
| - Useful for initializing DB or so. |
49 |
| - You don't need to use super or to call any parents method, it's managed by the server |
50 |
| - ''' |
51 |
| - pass |
52 | 41 |
|
| 42 | + from DIRAC.Core.Tornado.Server.TornadoService import TornadoService |
| 43 | + class yourServiceHandler(TornadoService): |
53 | 44 |
|
54 |
| - def initializeRequest(self): |
55 |
| - ''' |
56 |
| - Called at the beginning of each request |
57 |
| - ''' |
58 |
| - pass |
| 45 | + @classmethod |
| 46 | + def initializeHandler(cls, infosDict): |
| 47 | + '''Called only once when the first request for this handler arrives. |
| 48 | + Useful for initializing DB or so. |
| 49 | + You don't need to use super or to call any parents method, it's managed by the server |
| 50 | + ''' |
| 51 | + pass |
59 | 52 |
|
60 |
| - # Specify the default permission for the method |
61 |
| - # See :py:class:`DIRAC.Core.DISET.AuthManager.AuthManager` |
62 |
| - auth_someMethod = ['authenticated'] |
| 53 | + def initializeRequest(self): |
| 54 | + '''Called at the beginning of each request |
| 55 | + ''' |
| 56 | + pass |
63 | 57 |
|
| 58 | + # Specify the default permission for the method |
| 59 | + # See :py:class:`DIRAC.Core.DISET.AuthManager.AuthManager` |
| 60 | + auth_someMethod = ['authenticated'] |
64 | 61 |
|
65 |
| - def export_someMethod(self): |
66 |
| - '''The method you want to export. |
67 |
| - It must start with ``export_`` |
68 |
| - and it must return an S_OK/S_ERROR structure |
69 |
| - ''' |
70 |
| - return S_ERROR() |
| 62 | + def export_someMethod(self): |
| 63 | + '''The method you want to export. It must start with ``export_`` |
| 64 | + and it must return an S_OK/S_ERROR structure |
| 65 | + ''' |
| 66 | + return S_ERROR() |
71 | 67 |
|
| 68 | + def export_streamToClient(self, myDataToSend, token): |
| 69 | + ''' Automatically called when ``Transfer.receiveFile`` is called. |
| 70 | + Contrary to the other ``export_`` methods, it does not need to return a DIRAC structure. |
| 71 | + ''' |
72 | 72 |
|
73 |
| - def export_streamToClient(self, myDataToSend, token): |
74 |
| - ''' Automatically called when ``Transfer.receiveFile`` is called. |
75 |
| - Contrary to the other ``export_`` methods, it does not need |
76 |
| - to return a DIRAC structure. |
77 |
| - ''' |
| 73 | + # Do whatever with the token |
78 | 74 |
|
79 |
| - # Do whatever with the token |
80 |
| -
|
81 |
| - with open(myFileToSend, 'r') as fd: |
82 |
| - return fd.read() |
| 75 | + with open(myFileToSend, 'r') as fd: |
| 76 | + return fd.read() |
83 | 77 |
|
84 | 78 |
|
85 | 79 | Note that because we inherit from :py:class:`tornado.web.RequestHandler`
|
86 | 80 | and we are running using executors, the methods you export cannot write
|
87 |
| - back directly to the client. Please see inline comments for more details. |
| 81 | + back directly to the client. Please see inline comments in |
| 82 | + :py:class:`BaseRequestHandler <DIRAC.Core.Tornado.Server.private.BaseRequestHandler.BaseRequestHandler>` for more details. |
88 | 83 |
|
89 | 84 | In order to pass information around and keep some states, we use instance attributes.
|
90 | 85 | These are initialized in the :py:meth:`.initialize` method.
|
@@ -132,41 +127,34 @@ def export_streamToClient(self, myDataToSend, token):
|
132 | 127 |
|
133 | 128 | """
|
134 | 129 |
|
135 |
| - # To access DIRAC services, RPC requests are used only through the HTTP POST method |
136 |
| - SUPPORTED_METHODS = ["POST"] |
137 |
| - |
138 | 130 | @classmethod
|
139 |
| - def _getServiceName(cls, request): |
140 |
| - """Search service name in request. |
141 |
| -
|
142 |
| - :param object request: tornado Request |
143 |
| -
|
144 |
| - :return: str |
145 |
| - """ |
| 131 | + def _initializeHandler(cls): |
| 132 | + """Pre-initialization""" |
146 | 133 | # Expected path: ``/<System>/<Component>``
|
147 |
| - return request.path[1:] |
| 134 | + cls._serviceName = cls._fullComponentName |
148 | 135 |
|
149 | 136 | @classmethod
|
150 |
| - def _getServiceInfo(cls, serviceName, request): |
| 137 | + def _getComponentInfoDict(cls, serviceName, fullURL): |
151 | 138 | """Fill service information.
|
152 | 139 |
|
153 |
| - :param str serviceName: service name |
154 |
| - :param object request: tornado Request |
155 |
| -
|
| 140 | + :param str serviceName: service name, see :py:meth:`_getFullComponentName` |
| 141 | + :param str fullURL: incoming request path |
156 | 142 | :return: dict
|
157 | 143 | """
|
158 |
| - return { |
| 144 | + path = PathFinder.getServiceSection(serviceName) |
| 145 | + cls._serviceInfoDict = { |
159 | 146 | "serviceName": serviceName,
|
160 |
| - "serviceSectionPath": PathFinder.getServiceSection(serviceName), |
161 |
| - "csPaths": [PathFinder.getServiceSection(serviceName)], |
162 |
| - "URL": request.full_url(), |
| 147 | + "serviceSectionPath": path, |
| 148 | + "csPaths": [path], |
| 149 | + "URL": fullURL, |
163 | 150 | }
|
| 151 | + return cls._serviceInfoDict |
164 | 152 |
|
165 | 153 | @classmethod
|
166 |
| - def _getServiceAuthSection(cls, serviceName): |
| 154 | + def _getCSAuthorizarionSection(cls, serviceName): |
167 | 155 | """Search service auth section.
|
168 | 156 |
|
169 |
| - :param str serviceName: service name |
| 157 | + :param str serviceName: service name, see :py:meth:`_getFullComponentName` |
170 | 158 |
|
171 | 159 | :return: str
|
172 | 160 | """
|
|
0 commit comments