Browse Source

Various bugfix & enhancement

Better checks for datasources initialisation
The dyncode were not bootstraped by bootstrap.site_load() function
Yann Weber 7 years ago
parent
commit
6d8d3fd021

+ 4
- 0
lodel/bootstrap.py View File

213
     LodelContext.expose_modules(globals(), {
213
     LodelContext.expose_modules(globals(), {
214
         'lodel.plugins.multisite.loader_utils': ['FAST_APP_EXPOSAL_CACHE']})
214
         'lodel.plugins.multisite.loader_utils': ['FAST_APP_EXPOSAL_CACHE']})
215
     FAST_APP_EXPOSAL_CACHE[ctx_name] = app
215
     FAST_APP_EXPOSAL_CACHE[ctx_name] = app
216
+    #Switching back in handled site context in order to bootsrap it's 
217
+    #dyncode
218
+    LodelContext.set(ctx_name)
219
+    dyncode_bootstraping()
216
     #a dirty & quick attempt to fix context unwanted exite via
220
     #a dirty & quick attempt to fix context unwanted exite via
217
     #hooks
221
     #hooks
218
     for name in ( 'Plugin', 'LodelHook', 'logger', 'core_hooks',
222
     for name in ( 'Plugin', 'LodelHook', 'logger', 'core_hooks',

+ 3
- 0
lodel/exceptions.py View File

31
 class LodelFatalError(Exception):
31
 class LodelFatalError(Exception):
32
     pass
32
     pass
33
 
33
 
34
+class LodelFatalErrors(LodelFatalError, LodelExceptions):
35
+    pass
36
+
34
 ##@brief Designed to be a catched exception.
37
 ##@brief Designed to be a catched exception.
35
 #
38
 #
36
 #@note Designed to be raised in DataHandler
39
 #@note Designed to be raised in DataHandler

+ 9
- 7
lodel/leapi/lefactory.py View File

90
 # @brief Given an EmField returns the data_handler constructor suitable for dynamic code
90
 # @brief Given an EmField returns the data_handler constructor suitable for dynamic code
91
 # @param a EmField instance
91
 # @param a EmField instance
92
 # @return a string
92
 # @return a string
93
-
94
-
95
 def data_handler_constructor(emfield):
93
 def data_handler_constructor(emfield):
96
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
94
     #dh_module_name = DataHandler.module_name(emfield.data_handler_name)+'.DataHandler'
97
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
95
     get_handler_class_instr = 'DataField.from_name(%s)' % repr(emfield.data_handler_name)
112
 # @brief Return a python repr of option values
110
 # @brief Return a python repr of option values
113
 # @param A value of any type which represents option
111
 # @param A value of any type which represents option
114
 # @return a string
112
 # @return a string
115
-
116
-
117
 def forge_optval(optval):
113
 def forge_optval(optval):
118
     if isinstance(optval, dict):
114
     if isinstance(optval, dict):
119
         return '{' + (', '.join(['%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
115
         return '{' + (', '.join(['%s: %s' % (repr(name), forge_optval(val)) for name, val in optval.items()])) + '}'
120
 
116
 
121
     if isinstance(optval, (set, list, tuple)):
117
     if isinstance(optval, (set, list, tuple)):
122
         return '[' + (', '.join([forge_optval(val) for val in optval])) + ']'
118
         return '[' + (', '.join([forge_optval(val) for val in optval])) + ']'
123
-
124
-    if isinstance(optval, EmField):
119
+    
120
+    ##@todo better class test & name retrieval possible using inspect or type
121
+    if hasattr(optval, '__class__'):
122
+        cls_name = optval.__class__.__name__
123
+    else:
124
+        cls_name = optval.__name__
125
+
126
+    if cls_name == 'EmField':
125
         return "{leobject}.data_handler({fieldname})".format(
127
         return "{leobject}.data_handler({fieldname})".format(
126
             leobject=LeObject.name2objname(optval._emclass.uid),
128
             leobject=LeObject.name2objname(optval._emclass.uid),
127
             fieldname=repr(optval.uid)
129
             fieldname=repr(optval.uid)
128
         )
130
         )
129
-    if isinstance(optval, EmClass):
131
+    elif cls_name == 'EmClass':
130
         return LeObject.name2objname(optval.uid)
132
         return LeObject.name2objname(optval.uid)
131
 
133
 
132
     return repr(optval)
134
     return repr(optval)

+ 24
- 19
lodel/leapi/leobject.py View File

17
                                'LeApiQueryErrors'],
17
                                'LeApiQueryErrors'],
18
     'lodel.plugin.exceptions': ['PluginError', 'PluginTypeError',
18
     'lodel.plugin.exceptions': ['PluginError', 'PluginTypeError',
19
                                 'LodelScriptError', 'DatasourcePluginError'],
19
                                 'LodelScriptError', 'DatasourcePluginError'],
20
-    'lodel.exceptions': ['LodelFatalError'],
20
+    'lodel.exceptions': ['LodelFatalError', 'LodelFatalErrors'],
21
     'lodel.plugin.hooks': ['LodelHook'],
21
     'lodel.plugin.hooks': ['LodelHook'],
22
     'lodel.plugin': ['Plugin', 'DatasourcePlugin'],
22
     'lodel.plugin': ['Plugin', 'DatasourcePlugin'],
23
     'lodel.leapi.datahandlers.base_classes': ['DatasConstructor', 'Reference']})
23
     'lodel.leapi.datahandlers.base_classes': ['DatasConstructor', 'Reference']})
270
             rw_ds = ro_ds = cls._datasource_name
270
             rw_ds = ro_ds = cls._datasource_name
271
         else:
271
         else:
272
             ro_ds, rw_ds = cls._datasource_name
272
             ro_ds, rw_ds = cls._datasource_name
273
+        errors = []
273
         # Read only datasource initialisation
274
         # Read only datasource initialisation
274
-        cls._ro_datasource = DatasourcePlugin.init_datasource(ro_ds, True)
275
-        if cls._ro_datasource is None:
276
-            log_msg = "No read only datasource set for LeObject %s"
277
-            log_msg %= cls.__name__
278
-            logger.error(log_msg)
279
-        else:
280
-            log_msg = "Read only datasource '%s' initialized for LeObject %s"
281
-            log_msg %= (ro_ds, cls.__name__)
282
-            logger.debug(log_msg)
275
+        try:
276
+            cls._ro_datasource = DatasourcePlugin.init_datasource(ro_ds, True)
277
+            if cls._ro_datasource is not None:
278
+                log_msg = "Read only datasource '%s' initialized for LeObject %s"
279
+                log_msg %= (ro_ds, cls.__name__)
280
+                logger.debug(log_msg)
281
+        except LodelFatalError as e:
282
+            errors.append(e)
283
+            
283
         # Read write datasource initialisation
284
         # Read write datasource initialisation
284
-        cls._rw_datasource = DatasourcePlugin.init_datasource(rw_ds, False)
285
-        if cls._ro_datasource is None:
286
-            log_msg = "No read/write datasource set for LeObject %s"
287
-            log_msg %= cls.__name__
288
-            logger.error(log_msg)
289
-        else:
290
-            log_msg = "Read/write datasource '%s' initialized for LeObject %s"
291
-            log_msg %= (ro_ds, cls.__name__)
292
-            logger.debug(log_msg)
285
+        try:
286
+            cls._rw_datasource = DatasourcePlugin.init_datasource(rw_ds, False)
287
+            if cls._ro_datasource is not None:
288
+                log_msg = "Read/write datasource '%s' initialized for LeObject %s"
289
+                log_msg %= (ro_ds, cls.__name__)
290
+                logger.debug(log_msg)
291
+        except LodelFatalError as e:
292
+            errors.append(e)
293
+        
294
+        if len(errors) > 0:
295
+            raise LodelFatalErrors(msg = 'Unable to instanciate datasources \
296
+for LeObject %s' % cls.__name__, exceptions = errors)
297
+            
293
 
298
 
294
     # @brief Return the uid of the current LeObject instance
299
     # @brief Return the uid of the current LeObject instance
295
     #@return the uid value
300
     #@return the uid value

+ 9
- 3
lodel/plugin/datasource_plugin.py View File

1
 from lodel.context import LodelContext
1
 from lodel.context import LodelContext
2
 LodelContext.expose_modules(globals(), {
2
 LodelContext.expose_modules(globals(), {
3
     'lodel.plugin.plugins': ['Plugin'],
3
     'lodel.plugin.plugins': ['Plugin'],
4
+    'lodel.plugin.hooks': ['LodelHook'],
4
     'lodel.plugin.exceptions': ['PluginError', 'PluginTypeError',
5
     'lodel.plugin.exceptions': ['PluginError', 'PluginTypeError',
5
-        'LodelScriptError', 'DatasourcePluginError'],
6
+    'LodelScriptError', 'DatasourcePluginError'],
6
     'lodel.validator.validator': ['Validator'],
7
     'lodel.validator.validator': ['Validator'],
7
     'lodel.exceptions': ['LodelException', 'LodelExceptions',
8
     'lodel.exceptions': ['LodelException', 'LodelExceptions',
8
-        'LodelFatalError', 'DataNoneValid', 'FieldValidationError']})
9
+    'LodelFatalError', 'DataNoneValid', 'FieldValidationError'],
10
+})
9
 
11
 
10
 _glob_typename = 'datasource'
12
 _glob_typename = 'datasource'
11
 
13
 
138
         plugin_name, ds_identifier = cls.plugin_name(ds_name, ro)
140
         plugin_name, ds_identifier = cls.plugin_name(ds_name, ro)
139
         ds_conf = cls._get_ds_connection_conf(ds_identifier, plugin_name)
141
         ds_conf = cls._get_ds_connection_conf(ds_identifier, plugin_name)
140
         ds_cls = cls.get_datasource(plugin_name)
142
         ds_cls = cls.get_datasource(plugin_name)
141
-        return ds_cls(**ds_conf)
143
+        res = ds_cls(**ds_conf)
144
+        if res is None:
145
+            raise LodelFatalError("Unable to instanciate a datasource from \
146
+name : '%s'" % ds_name)
147
+        return res
142
     
148
     
143
     ##@brief Return an initialized MigrationHandler instance
149
     ##@brief Return an initialized MigrationHandler instance
144
     #@param ds_name str : The datasource name
150
     #@param ds_name str : The datasource name

+ 1
- 1
lodel/validator/validator.py View File

348
 
348
 
349
     @LodelHook('lodel2_dyncode_bootstraped')
349
     @LodelHook('lodel2_dyncode_bootstraped')
350
     def emfield_conf_check(hookname, caller, payload):
350
     def emfield_conf_check(hookname, caller, payload):
351
-        import leapi_dyncode as dyncode  # <-- dirty & quick
351
+        LodelContext.expose_dyncode(globals(), 'dyncode')
352
         classnames = {cls.__name__.lower(): cls for cls in dyncode.dynclasses}
352
         classnames = {cls.__name__.lower(): cls for cls in dyncode.dynclasses}
353
         if value[0].lower() not in classnames:
353
         if value[0].lower() not in classnames:
354
             msg = "Following dynamic class do not exists in current EM : %s"
354
             msg = "Following dynamic class do not exists in current EM : %s"

Loading…
Cancel
Save