iris-pex-embedded-python 3.5.5b4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- grongier/__init__.py +0 -0
- grongier/cls/Grongier/PEX/BusinessOperation.cls +8 -0
- grongier/cls/Grongier/PEX/BusinessProcess.cls +13 -0
- grongier/cls/Grongier/PEX/BusinessService.cls +8 -0
- grongier/cls/Grongier/PEX/Common.cls +10 -0
- grongier/cls/Grongier/PEX/Director.cls +10 -0
- grongier/cls/Grongier/PEX/Duplex/Operation.cls +4 -0
- grongier/cls/Grongier/PEX/Duplex/Process.cls +13 -0
- grongier/cls/Grongier/PEX/Duplex/Service.cls +4 -0
- grongier/cls/Grongier/PEX/InboundAdapter.cls +8 -0
- grongier/cls/Grongier/PEX/Message.cls +13 -0
- grongier/cls/Grongier/PEX/OutboundAdapter.cls +8 -0
- grongier/cls/Grongier/PEX/PickleMessage.cls +13 -0
- grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +8 -0
- grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +14 -0
- grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +14 -0
- grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +14 -0
- grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +14 -0
- grongier/cls/Grongier/PEX/Test.cls +10 -0
- grongier/cls/Grongier/PEX/Utils.cls +10 -0
- grongier/cls/Grongier/Service/WSGI.cls +4 -0
- grongier/pex/__init__.py +24 -0
- grongier/pex/__main__.py +4 -0
- grongier/pex/_business_host.py +1 -0
- grongier/pex/_cli.py +4 -0
- grongier/pex/_common.py +1 -0
- grongier/pex/_director.py +1 -0
- grongier/pex/_utils.py +1 -0
- grongier/pex/wsgi/handlers.py +104 -0
- iop/__init__.py +25 -0
- iop/__main__.py +4 -0
- iop/_async_request.py +67 -0
- iop/_business_host.py +256 -0
- iop/_business_operation.py +75 -0
- iop/_business_process.py +224 -0
- iop/_business_service.py +63 -0
- iop/_cli.py +247 -0
- iop/_common.py +334 -0
- iop/_debugpy.py +187 -0
- iop/_decorators.py +49 -0
- iop/_director.py +301 -0
- iop/_dispatch.py +136 -0
- iop/_generator_request.py +30 -0
- iop/_inbound_adapter.py +34 -0
- iop/_iris.py +8 -0
- iop/_log_manager.py +100 -0
- iop/_message.py +40 -0
- iop/_message_validator.py +49 -0
- iop/_outbound_adapter.py +23 -0
- iop/_private_session_duplex.py +103 -0
- iop/_private_session_process.py +41 -0
- iop/_remote.py +91 -0
- iop/_serialization.py +199 -0
- iop/_utils.py +671 -0
- iop/cls/IOP/BusinessOperation.cls +35 -0
- iop/cls/IOP/BusinessProcess.cls +156 -0
- iop/cls/IOP/BusinessService.cls +40 -0
- iop/cls/IOP/Common.cls +569 -0
- iop/cls/IOP/Director.cls +70 -0
- iop/cls/IOP/Duplex/Operation.cls +29 -0
- iop/cls/IOP/Duplex/Process.cls +229 -0
- iop/cls/IOP/Duplex/Service.cls +9 -0
- iop/cls/IOP/Generator/Message/Ack.cls +31 -0
- iop/cls/IOP/Generator/Message/Poll.cls +31 -0
- iop/cls/IOP/Generator/Message/Start.cls +15 -0
- iop/cls/IOP/Generator/Message/StartPickle.cls +15 -0
- iop/cls/IOP/Generator/Message/Stop.cls +32 -0
- iop/cls/IOP/InboundAdapter.cls +22 -0
- iop/cls/IOP/Message/JSONSchema.cls +125 -0
- iop/cls/IOP/Message.cls +754 -0
- iop/cls/IOP/OutboundAdapter.cls +36 -0
- iop/cls/IOP/PickleMessage.cls +58 -0
- iop/cls/IOP/PrivateSession/Duplex.cls +260 -0
- iop/cls/IOP/PrivateSession/Message/Ack.cls +32 -0
- iop/cls/IOP/PrivateSession/Message/Poll.cls +32 -0
- iop/cls/IOP/PrivateSession/Message/Start.cls +31 -0
- iop/cls/IOP/PrivateSession/Message/Stop.cls +48 -0
- iop/cls/IOP/Projection.cls +49 -0
- iop/cls/IOP/Service/Remote/Handler.cls +30 -0
- iop/cls/IOP/Service/Remote/Rest/v1.cls +97 -0
- iop/cls/IOP/Service/WSGI.cls +310 -0
- iop/cls/IOP/Test.cls +85 -0
- iop/cls/IOP/Utils.cls +503 -0
- iop/cls/IOP/Wrapper.cls +58 -0
- iop/wsgi/handlers.py +104 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/METADATA +91 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/RECORD +91 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/WHEEL +5 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/entry_points.txt +2 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/licenses/LICENSE +21 -0
- iris_pex_embedded_python-3.5.5b4.dist-info/top_level.txt +2 -0
iop/_cli.py
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import logging
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from enum import Enum, auto
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Optional, Callable
|
|
10
|
+
from importlib.metadata import version
|
|
11
|
+
|
|
12
|
+
from ._director import _Director
|
|
13
|
+
from ._utils import _Utils
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CommandType(Enum):
|
|
17
|
+
DEFAULT = auto()
|
|
18
|
+
LIST = auto()
|
|
19
|
+
START = auto()
|
|
20
|
+
STOP = auto()
|
|
21
|
+
KILL = auto()
|
|
22
|
+
RESTART = auto()
|
|
23
|
+
STATUS = auto()
|
|
24
|
+
TEST = auto()
|
|
25
|
+
VERSION = auto()
|
|
26
|
+
EXPORT = auto()
|
|
27
|
+
MIGRATE = auto()
|
|
28
|
+
LOG = auto()
|
|
29
|
+
INIT = auto()
|
|
30
|
+
HELP = auto()
|
|
31
|
+
UPDATE = auto()
|
|
32
|
+
|
|
33
|
+
@dataclass
|
|
34
|
+
class CommandArgs:
|
|
35
|
+
"""Container for parsed command arguments"""
|
|
36
|
+
default: Optional[str] = None
|
|
37
|
+
list: bool = False
|
|
38
|
+
start: Optional[str] = None
|
|
39
|
+
detach: bool = False
|
|
40
|
+
stop: bool = False
|
|
41
|
+
kill: bool = False
|
|
42
|
+
restart: bool = False
|
|
43
|
+
status: bool = False
|
|
44
|
+
migrate: Optional[str] = None
|
|
45
|
+
export: Optional[str] = None
|
|
46
|
+
version: bool = False
|
|
47
|
+
log: Optional[str] = None
|
|
48
|
+
init: Optional[str] = None
|
|
49
|
+
test: Optional[str] = None
|
|
50
|
+
classname: Optional[str] = None
|
|
51
|
+
body: Optional[str] = None
|
|
52
|
+
namespace: Optional[str] = None
|
|
53
|
+
force_local: bool = False
|
|
54
|
+
update: bool = False
|
|
55
|
+
|
|
56
|
+
class Command:
|
|
57
|
+
def __init__(self, args: CommandArgs):
|
|
58
|
+
self.args = args
|
|
59
|
+
|
|
60
|
+
if self.args.namespace and self.args.namespace != 'not_set':
|
|
61
|
+
# set environment variable IRISNAMESPACE
|
|
62
|
+
os.environ['IRISNAMESPACE'] = self.args.namespace
|
|
63
|
+
|
|
64
|
+
def _has_primary_command(self) -> bool:
|
|
65
|
+
return any([
|
|
66
|
+
self.args.default,
|
|
67
|
+
self.args.list,
|
|
68
|
+
self.args.start,
|
|
69
|
+
self.args.stop,
|
|
70
|
+
self.args.kill,
|
|
71
|
+
self.args.restart,
|
|
72
|
+
self.args.status,
|
|
73
|
+
self.args.test,
|
|
74
|
+
self.args.version,
|
|
75
|
+
self.args.export,
|
|
76
|
+
self.args.migrate,
|
|
77
|
+
self.args.log,
|
|
78
|
+
self.args.init,
|
|
79
|
+
self.args.update,
|
|
80
|
+
])
|
|
81
|
+
|
|
82
|
+
def execute(self) -> None:
|
|
83
|
+
if self.args.namespace == 'not_set' and not self._has_primary_command():
|
|
84
|
+
print(os.getenv('IRISNAMESPACE', 'not set'))
|
|
85
|
+
return
|
|
86
|
+
|
|
87
|
+
command_type = self._determine_command_type()
|
|
88
|
+
command_handlers = {
|
|
89
|
+
CommandType.DEFAULT: self._handle_default,
|
|
90
|
+
CommandType.LIST: self._handle_list,
|
|
91
|
+
CommandType.START: self._handle_start,
|
|
92
|
+
CommandType.STOP: self._handle_stop,
|
|
93
|
+
CommandType.KILL: self._handle_kill,
|
|
94
|
+
CommandType.RESTART: self._handle_restart,
|
|
95
|
+
CommandType.STATUS: self._handle_status,
|
|
96
|
+
CommandType.TEST: self._handle_test,
|
|
97
|
+
CommandType.VERSION: self._handle_version,
|
|
98
|
+
CommandType.EXPORT: self._handle_export,
|
|
99
|
+
CommandType.MIGRATE: self._handle_migrate,
|
|
100
|
+
CommandType.LOG: self._handle_log,
|
|
101
|
+
CommandType.INIT: self._handle_init,
|
|
102
|
+
CommandType.HELP: self._handle_help,
|
|
103
|
+
CommandType.UPDATE: self._handle_update,
|
|
104
|
+
}
|
|
105
|
+
handler = command_handlers.get(command_type)
|
|
106
|
+
if handler:
|
|
107
|
+
handler()
|
|
108
|
+
|
|
109
|
+
def _determine_command_type(self) -> CommandType:
|
|
110
|
+
if self.args.default: return CommandType.DEFAULT
|
|
111
|
+
if self.args.list: return CommandType.LIST
|
|
112
|
+
if self.args.start: return CommandType.START
|
|
113
|
+
if self.args.stop: return CommandType.STOP
|
|
114
|
+
if self.args.kill: return CommandType.KILL
|
|
115
|
+
if self.args.restart: return CommandType.RESTART
|
|
116
|
+
if self.args.status: return CommandType.STATUS
|
|
117
|
+
if self.args.test: return CommandType.TEST
|
|
118
|
+
if self.args.version: return CommandType.VERSION
|
|
119
|
+
if self.args.export: return CommandType.EXPORT
|
|
120
|
+
if self.args.migrate: return CommandType.MIGRATE
|
|
121
|
+
if self.args.log: return CommandType.LOG
|
|
122
|
+
if self.args.init: return CommandType.INIT
|
|
123
|
+
if self.args.update: return CommandType.UPDATE
|
|
124
|
+
return CommandType.HELP
|
|
125
|
+
|
|
126
|
+
def _handle_default(self) -> None:
|
|
127
|
+
if self.args.default == 'not_set':
|
|
128
|
+
print(_Director.get_default_production())
|
|
129
|
+
elif self.args.default is not None:
|
|
130
|
+
_Director.set_default_production(self.args.default)
|
|
131
|
+
|
|
132
|
+
def _handle_list(self) -> None:
|
|
133
|
+
dikt = _Director.list_productions()
|
|
134
|
+
print(json.dumps(dikt, indent=4))
|
|
135
|
+
|
|
136
|
+
def _handle_start(self) -> None:
|
|
137
|
+
production_name = self.args.start if self.args.start != 'not_set' else _Director.get_default_production()
|
|
138
|
+
if self.args.detach:
|
|
139
|
+
_Director.start_production(production_name)
|
|
140
|
+
print(f"Production {production_name} started")
|
|
141
|
+
else:
|
|
142
|
+
_Director.start_production_with_log(production_name)
|
|
143
|
+
|
|
144
|
+
def _handle_stop(self) -> None:
|
|
145
|
+
_Director.stop_production()
|
|
146
|
+
print(f"Production {_Director.get_default_production()} stopped")
|
|
147
|
+
|
|
148
|
+
def _handle_kill(self) -> None:
|
|
149
|
+
_Director.shutdown_production()
|
|
150
|
+
|
|
151
|
+
def _handle_restart(self) -> None:
|
|
152
|
+
_Director.restart_production()
|
|
153
|
+
|
|
154
|
+
def _handle_status(self) -> None:
|
|
155
|
+
print(json.dumps(_Director.status_production(), indent=4))
|
|
156
|
+
|
|
157
|
+
def _handle_update(self) -> None:
|
|
158
|
+
_Director.update_production()
|
|
159
|
+
|
|
160
|
+
def _handle_test(self) -> None:
|
|
161
|
+
test_name = None if self.args.test == 'not_set' else self.args.test
|
|
162
|
+
response = _Director.test_component(
|
|
163
|
+
test_name,
|
|
164
|
+
classname=self.args.classname if self.args.classname != 'not_set' else None,
|
|
165
|
+
body=self.args.body if self.args.body != 'not_set' else None
|
|
166
|
+
)
|
|
167
|
+
print(response)
|
|
168
|
+
|
|
169
|
+
def _handle_version(self) -> None:
|
|
170
|
+
print(version('iris-pex-embedded-python'))
|
|
171
|
+
|
|
172
|
+
def _handle_export(self) -> None:
|
|
173
|
+
export_name = _Director.get_default_production() if self.args.export == 'not_set' else self.args.export
|
|
174
|
+
print(json.dumps(_Utils.export_production(export_name), indent=4))
|
|
175
|
+
|
|
176
|
+
def _handle_migrate(self) -> None:
|
|
177
|
+
migrate_path = self.args.migrate
|
|
178
|
+
if migrate_path is not None:
|
|
179
|
+
if not os.path.isabs(migrate_path):
|
|
180
|
+
migrate_path = os.path.join(os.getcwd(), migrate_path)
|
|
181
|
+
_Utils.migrate_remote(migrate_path, force_local=self.args.force_local)
|
|
182
|
+
|
|
183
|
+
def _handle_log(self) -> None:
|
|
184
|
+
if self.args.log == 'not_set':
|
|
185
|
+
print(_Director.log_production())
|
|
186
|
+
elif self.args.log is not None:
|
|
187
|
+
print(_Director.log_production_top(int(self.args.log)))
|
|
188
|
+
|
|
189
|
+
def _handle_init(self) -> None:
|
|
190
|
+
_Utils.setup(None)
|
|
191
|
+
|
|
192
|
+
def _handle_help(self) -> None:
|
|
193
|
+
create_parser().print_help()
|
|
194
|
+
try:
|
|
195
|
+
print(f"\nDefault production: {_Director.get_default_production()}")
|
|
196
|
+
print(f"\nNamespace: {os.getenv('IRISNAMESPACE','not set')}")
|
|
197
|
+
except Exception:
|
|
198
|
+
logging.warning("Could not retrieve default production.")
|
|
199
|
+
|
|
200
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
201
|
+
"""Create and configure argument parser"""
|
|
202
|
+
main_parser = argparse.ArgumentParser()
|
|
203
|
+
parser = main_parser.add_mutually_exclusive_group()
|
|
204
|
+
|
|
205
|
+
# Main commands
|
|
206
|
+
parser.add_argument('-d', '--default', help='set the default production', nargs='?', const='not_set')
|
|
207
|
+
parser.add_argument('-l', '--list', help='list productions', action='store_true')
|
|
208
|
+
parser.add_argument('-s', '--start', help='start a production', nargs='?', const='not_set')
|
|
209
|
+
parser.add_argument('-S', '--stop', help='stop a production', action='store_true')
|
|
210
|
+
parser.add_argument('-k', '--kill', help='kill a production', action='store_true')
|
|
211
|
+
parser.add_argument('-r', '--restart', help='restart a production', action='store_true')
|
|
212
|
+
parser.add_argument('-x', '--status', help='status a production', action='store_true')
|
|
213
|
+
parser.add_argument('-m', '-M', '--migrate', help='migrate production and classes with settings file')
|
|
214
|
+
parser.add_argument('-e', '--export', help='export a production', nargs='?', const='not_set')
|
|
215
|
+
parser.add_argument('-v', '--version', help='display version', action='store_true')
|
|
216
|
+
parser.add_argument('-L', '--log', help='display log', nargs='?', const='not_set')
|
|
217
|
+
parser.add_argument('-i', '--init', help='init the pex module in iris', nargs='?', const='not_set')
|
|
218
|
+
parser.add_argument('-t', '--test', help='test the pex module in iris', nargs='?', const='not_set')
|
|
219
|
+
parser.add_argument('-u', '--update', help='update a production', action='store_true')
|
|
220
|
+
|
|
221
|
+
# Command groups
|
|
222
|
+
start = main_parser.add_argument_group('start arguments')
|
|
223
|
+
start.add_argument('-D', '--detach', help='start a production in detach mode', action='store_true')
|
|
224
|
+
|
|
225
|
+
test = main_parser.add_argument_group('test arguments')
|
|
226
|
+
test.add_argument('-C', '--classname', help='test classname', nargs='?', const='not_set')
|
|
227
|
+
test.add_argument('-B', '--body', help='test body', nargs='?', const='not_set')
|
|
228
|
+
|
|
229
|
+
migrate = main_parser.add_argument_group('migrate arguments')
|
|
230
|
+
migrate.add_argument('--force-local', help='force local migration, skip remote even if REMOTE_SETTINGS is present', action='store_true')
|
|
231
|
+
|
|
232
|
+
namespace = main_parser.add_argument_group('namespace arguments')
|
|
233
|
+
namespace.add_argument('-n', '--namespace', help='set namespace', nargs='?', const='not_set')
|
|
234
|
+
|
|
235
|
+
return main_parser
|
|
236
|
+
|
|
237
|
+
def main(argv=None) -> None:
|
|
238
|
+
parser = create_parser()
|
|
239
|
+
args = parser.parse_args(argv)
|
|
240
|
+
cmd_args = CommandArgs(**vars(args))
|
|
241
|
+
|
|
242
|
+
command = Command(cmd_args)
|
|
243
|
+
command.execute()
|
|
244
|
+
sys.exit(0)
|
|
245
|
+
|
|
246
|
+
if __name__ == '__main__':
|
|
247
|
+
main()
|
iop/_common.py
ADDED
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import abc
|
|
2
|
+
import inspect
|
|
3
|
+
import traceback
|
|
4
|
+
from typing import Any, ClassVar, List, Optional, Tuple
|
|
5
|
+
|
|
6
|
+
from . import _iris
|
|
7
|
+
from ._log_manager import LogManager, logging
|
|
8
|
+
from ._debugpy import debugpython
|
|
9
|
+
|
|
10
|
+
class _Common(metaclass=abc.ABCMeta):
|
|
11
|
+
"""Base class that defines common methods for all component types.
|
|
12
|
+
|
|
13
|
+
Provides core functionality like initialization, teardown, connection handling
|
|
14
|
+
and message type checking that is shared across component types.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
INFO_URL: ClassVar[str]
|
|
18
|
+
ICON_URL: ClassVar[str]
|
|
19
|
+
iris_handle: Any = None
|
|
20
|
+
_log_to_console: bool = False
|
|
21
|
+
_logger: Optional[logging.Logger] = None
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def get_adapter_type() -> Optional[str]:
|
|
25
|
+
"""Get the adapter type for this component. Override in subclasses."""
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
@property
|
|
29
|
+
def logger(self) -> logging.Logger:
|
|
30
|
+
if self._logger is None:
|
|
31
|
+
self._logger = LogManager.get_logger(self.__class__.__name__,self.log_to_console)
|
|
32
|
+
return self._logger
|
|
33
|
+
|
|
34
|
+
@logger.setter
|
|
35
|
+
def logger(self, value: logging.Logger) -> None:
|
|
36
|
+
self._logger = value
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def log_to_console(self) -> bool:
|
|
40
|
+
return self._log_to_console
|
|
41
|
+
|
|
42
|
+
@log_to_console.setter
|
|
43
|
+
def log_to_console(self, value: bool) -> None:
|
|
44
|
+
self._log_to_console = value
|
|
45
|
+
self.logger = LogManager.get_logger(self.__class__.__name__,value)
|
|
46
|
+
|
|
47
|
+
# Lifecycle methods
|
|
48
|
+
def on_init(self) -> None:
|
|
49
|
+
"""Initialize component when started."""
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
def on_tear_down(self) -> None:
|
|
53
|
+
"""Clean up component before termination."""
|
|
54
|
+
pass
|
|
55
|
+
|
|
56
|
+
def on_connected(self) -> None:
|
|
57
|
+
"""Handle component connection/reconnection."""
|
|
58
|
+
pass
|
|
59
|
+
|
|
60
|
+
# Internal dispatch methods
|
|
61
|
+
def _dispatch_on_connected(self, host_object: Any) -> None:
|
|
62
|
+
self.on_connected()
|
|
63
|
+
|
|
64
|
+
def _dispatch_on_init(self, host_object: Any) -> None:
|
|
65
|
+
"""Initialize component when started."""
|
|
66
|
+
self.on_init()
|
|
67
|
+
|
|
68
|
+
def _dispatch_on_tear_down(self, host_object: Any) -> None:
|
|
69
|
+
self.on_tear_down()
|
|
70
|
+
|
|
71
|
+
def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
|
|
72
|
+
"""Internal method to set IRIS handles."""
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
def _debugpy(self, host) -> None:
|
|
76
|
+
"""Set up debugpy for debugging."""
|
|
77
|
+
if debugpython is not None:
|
|
78
|
+
debugpython(self=self, host_object=host)
|
|
79
|
+
|
|
80
|
+
# Component information methods
|
|
81
|
+
@classmethod
|
|
82
|
+
def _get_info(cls) -> List[str]:
|
|
83
|
+
"""Get component configuration information.
|
|
84
|
+
|
|
85
|
+
Returns information used to display in Production config UI including:
|
|
86
|
+
- Superclass
|
|
87
|
+
- Description
|
|
88
|
+
- InfoURL
|
|
89
|
+
- IconURL
|
|
90
|
+
- Adapter type (for Business Services/Operations)
|
|
91
|
+
"""
|
|
92
|
+
ret = []
|
|
93
|
+
desc = ""
|
|
94
|
+
info_url = ""
|
|
95
|
+
icon_url = ""
|
|
96
|
+
super_class = ""
|
|
97
|
+
adapter = ""
|
|
98
|
+
try:
|
|
99
|
+
# Get tuple of the class's base classes and loop through them until we find one of the PEX component classes
|
|
100
|
+
classes = inspect.getmro(cls)
|
|
101
|
+
for cl in classes:
|
|
102
|
+
classname = str(cl)[7:-1]
|
|
103
|
+
if classname in ["'iop.BusinessService'","'iop.BusinessOperation'","'iop.DuplexOperation'","'iop.DuplexService'",
|
|
104
|
+
"'grongier.pex.BusinessService'","'grongier.pex.BusinessOperation'","'grongier.pex.DuplexOperation'","'grongier.pex.DuplexService'"] :
|
|
105
|
+
# Remove the apostrophes and set as super_class, then find if it uses an adapter
|
|
106
|
+
super_class = classname[1:-1]
|
|
107
|
+
adapter = cls.get_adapter_type()
|
|
108
|
+
if adapter is None:
|
|
109
|
+
# for retro-compatibility
|
|
110
|
+
adapter = cls.getAdapterType() # type: ignore
|
|
111
|
+
break
|
|
112
|
+
elif classname in ["'iop.BusinessProcess'","'iop.DuplexProcess'","'iop.InboundAdapter'","'iop.OutboundAdapter'",
|
|
113
|
+
"'grongier.pex.BusinessProcess'","'grongier.pex.DuplexProcess'","'grongier.pex.InboundAdapter'","'grongier.pex.OutboundAdapter'"] :
|
|
114
|
+
# Remove the apostrophes and set as super_class
|
|
115
|
+
super_class = classname[1:-1]
|
|
116
|
+
break
|
|
117
|
+
|
|
118
|
+
if ""==super_class:
|
|
119
|
+
return []
|
|
120
|
+
ret.append(super_class)
|
|
121
|
+
|
|
122
|
+
# Get the class documentation, if any
|
|
123
|
+
class_desc = inspect.getdoc(cls)
|
|
124
|
+
super_desc = inspect.getdoc(classes[1])
|
|
125
|
+
if class_desc!=super_desc:
|
|
126
|
+
desc = class_desc
|
|
127
|
+
ret.append(str(desc))
|
|
128
|
+
|
|
129
|
+
info_url = inspect.getattr_static(cls,"INFO_URL","")
|
|
130
|
+
icon_url = inspect.getattr_static(cls,"ICON_URL","")
|
|
131
|
+
|
|
132
|
+
ret.append(info_url)
|
|
133
|
+
ret.append(icon_url)
|
|
134
|
+
|
|
135
|
+
if ""!=adapter:
|
|
136
|
+
ret.append(adapter)
|
|
137
|
+
except Exception as e:
|
|
138
|
+
raise e
|
|
139
|
+
return ret
|
|
140
|
+
|
|
141
|
+
@classmethod
|
|
142
|
+
def _get_properties(cls) -> List[List[Any]]:
|
|
143
|
+
"""Get component properties for Production configuration.
|
|
144
|
+
|
|
145
|
+
Returns list of property definitions containing:
|
|
146
|
+
- Property name
|
|
147
|
+
- Data type
|
|
148
|
+
- Default value
|
|
149
|
+
- Required flag
|
|
150
|
+
- Category
|
|
151
|
+
- Description
|
|
152
|
+
|
|
153
|
+
Only includes non-private class attributes and properties.
|
|
154
|
+
"""
|
|
155
|
+
ret = []
|
|
156
|
+
try:
|
|
157
|
+
# getmembers() returns all the members of an obj
|
|
158
|
+
for member in inspect.getmembers(cls):
|
|
159
|
+
# remove private and protected functions
|
|
160
|
+
if not member[0].startswith('_'):
|
|
161
|
+
# remove other methods and functions
|
|
162
|
+
if not inspect.ismethod(member[1]) and not inspect.isfunction(member[1]) and not inspect.isclass(member[1]):
|
|
163
|
+
if member[0] not in ('INFO_URL','ICON_URL','PERSISTENT_PROPERTY_LIST'
|
|
164
|
+
,'log_to_console','logger','iris_handle'
|
|
165
|
+
,'DISPATCH','adapter','Adapter','buffer'
|
|
166
|
+
,'BusinessHost','business_host','business_host_python'):
|
|
167
|
+
name = member[0]
|
|
168
|
+
req = 0
|
|
169
|
+
cat = "Additional"
|
|
170
|
+
desc = ""
|
|
171
|
+
# get value, set to "" if None or a @property
|
|
172
|
+
val = member[1]
|
|
173
|
+
if isinstance(val,property) or (val is None):
|
|
174
|
+
val = ""
|
|
175
|
+
dt = str(type(val))[8:-2]
|
|
176
|
+
# get datatype from attribute definition, default to String
|
|
177
|
+
data_type = {'int':'Integer','float':'Numeric','complex':'Numeric','bool':'Boolean'}.get(dt,'String')
|
|
178
|
+
# if the user has created a attr_info function, then check the annotation on the return from that for more information about this attribute
|
|
179
|
+
if hasattr(cls,name + '_info') :
|
|
180
|
+
func = getattr(cls,name+'_info')
|
|
181
|
+
if callable(func) :
|
|
182
|
+
annotations = func.__annotations__['return']
|
|
183
|
+
if annotations is not None:
|
|
184
|
+
if bool(annotations.get("ExcludeFromSettings")) :
|
|
185
|
+
# don't add this attribute to the settings list
|
|
186
|
+
continue
|
|
187
|
+
req = bool(annotations.get("IsRequired"))
|
|
188
|
+
cat = annotations.get("Category","Additional")
|
|
189
|
+
desc = annotations.get("Description")
|
|
190
|
+
dt = annotations.get("DataType")
|
|
191
|
+
# only override DataType found
|
|
192
|
+
if (dt is not None) and ("" != dt):
|
|
193
|
+
data_type = {int:'Integer',float:'Number',complex:'Number',bool:'Boolean',str:'String'}.get(dt,str(dt))
|
|
194
|
+
default = func()
|
|
195
|
+
if default is not None:
|
|
196
|
+
val = default
|
|
197
|
+
# create list of information for this specific property
|
|
198
|
+
info = []
|
|
199
|
+
info.append(name) # Name
|
|
200
|
+
info.append(data_type) # DataType
|
|
201
|
+
info.append(val) # Default Value
|
|
202
|
+
info.append(req) # Required
|
|
203
|
+
info.append(cat) # Category
|
|
204
|
+
info.append(desc) # Description
|
|
205
|
+
# add this property to the list
|
|
206
|
+
ret.append(info)
|
|
207
|
+
except:
|
|
208
|
+
pass
|
|
209
|
+
return ret
|
|
210
|
+
|
|
211
|
+
# Logging methods
|
|
212
|
+
def _log(self) -> Tuple[str, Optional[str]]:
|
|
213
|
+
"""Get class and method name for logging.
|
|
214
|
+
|
|
215
|
+
Returns:
|
|
216
|
+
Tuple of (class_name, method_name)
|
|
217
|
+
"""
|
|
218
|
+
current_class = self.__class__.__name__
|
|
219
|
+
current_method = None
|
|
220
|
+
try:
|
|
221
|
+
frame = traceback.extract_stack()[-4]
|
|
222
|
+
current_method = frame.name
|
|
223
|
+
except:
|
|
224
|
+
pass
|
|
225
|
+
return current_class, current_method
|
|
226
|
+
|
|
227
|
+
def _logging(self, message: str, level: int, to_console: Optional[bool] = None) -> None:
|
|
228
|
+
"""Write log entry.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
message: Message to log
|
|
232
|
+
level: Log level
|
|
233
|
+
to_console: If True, log to console instead of IRIS
|
|
234
|
+
"""
|
|
235
|
+
current_class, current_method = self._log()
|
|
236
|
+
if to_console is None:
|
|
237
|
+
to_console = self.log_to_console
|
|
238
|
+
if level == logging.DEBUG:
|
|
239
|
+
self.logger.debug(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
|
|
240
|
+
elif level == logging.INFO:
|
|
241
|
+
self.logger.info(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
|
|
242
|
+
elif level == logging.CRITICAL:
|
|
243
|
+
self.logger.critical(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
|
|
244
|
+
elif level == logging.WARNING:
|
|
245
|
+
self.logger.warning(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
|
|
246
|
+
elif level == logging.ERROR:
|
|
247
|
+
self.logger.error(message, extra={'to_console': to_console, 'class_name': current_class, 'method_name': current_method})
|
|
248
|
+
|
|
249
|
+
def trace(self, message: str, to_console: Optional[bool] = None) -> None:
|
|
250
|
+
"""Write trace log entry.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
message: Message to log
|
|
254
|
+
to_console: If True, log to console instead of IRIS
|
|
255
|
+
"""
|
|
256
|
+
self._logging(message, logging.DEBUG, to_console)
|
|
257
|
+
|
|
258
|
+
def log_info(self, message: str, to_console: Optional[bool] = None) -> None:
|
|
259
|
+
"""Write info log entry.
|
|
260
|
+
|
|
261
|
+
Args:
|
|
262
|
+
message: Message to log
|
|
263
|
+
to_console: If True, log to console instead of IRIS
|
|
264
|
+
"""
|
|
265
|
+
self._logging(message, logging.INFO, to_console)
|
|
266
|
+
|
|
267
|
+
def log_alert(self, message: str, to_console: Optional[bool] = None) -> None:
|
|
268
|
+
"""Write alert log entry.
|
|
269
|
+
|
|
270
|
+
Args:
|
|
271
|
+
message: Message to log
|
|
272
|
+
to_console: If True, log to console instead of IRIS
|
|
273
|
+
"""
|
|
274
|
+
self._logging(message, logging.CRITICAL, to_console)
|
|
275
|
+
|
|
276
|
+
def log_warning(self, message: str, to_console: Optional[bool] = None) -> None:
|
|
277
|
+
"""Write warning log entry.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
message: Message to log
|
|
281
|
+
to_console: If True, log to console instead of IRIS
|
|
282
|
+
"""
|
|
283
|
+
self._logging(message, logging.WARNING, to_console)
|
|
284
|
+
|
|
285
|
+
def log_error(self, message: str, to_console: Optional[bool] = None) -> None:
|
|
286
|
+
"""Write error log entry.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
message: Message to log
|
|
290
|
+
to_console: If True, log to console instead of IRIS
|
|
291
|
+
"""
|
|
292
|
+
self._logging(message, logging.ERROR, to_console)
|
|
293
|
+
|
|
294
|
+
def log_assert(self, message: str) -> None:
|
|
295
|
+
"""Write a log entry of type "assert". Log entries can be viewed in the management portal.
|
|
296
|
+
|
|
297
|
+
Parameters:
|
|
298
|
+
message: a string that is written to the log.
|
|
299
|
+
"""
|
|
300
|
+
iris = _iris.get_iris()
|
|
301
|
+
current_class, current_method = self._log()
|
|
302
|
+
iris.cls("Ens.Util.Log").LogAssert(current_class, current_method, message)
|
|
303
|
+
|
|
304
|
+
def LOGINFO(self, message: str) -> None:
|
|
305
|
+
"""DEPRECATED: Use log_info."""
|
|
306
|
+
return self.log_info(message=message)
|
|
307
|
+
|
|
308
|
+
def LOGALERT(self, message: str) -> None:
|
|
309
|
+
"""DEPRECATED: Use log_alert."""
|
|
310
|
+
return self.log_alert(message)
|
|
311
|
+
|
|
312
|
+
def LOGWARNING(self, message: str) -> None:
|
|
313
|
+
"""DEPRECATED: Use log_warning."""
|
|
314
|
+
return self.log_warning(message)
|
|
315
|
+
|
|
316
|
+
def LOGERROR(self, message: str) -> None:
|
|
317
|
+
"""DEPRECATED: Use log_error."""
|
|
318
|
+
return self.log_error(message)
|
|
319
|
+
|
|
320
|
+
def LOGASSERT(self, message: str) -> None:
|
|
321
|
+
"""DEPRECATED: Use log_assert."""
|
|
322
|
+
return self.log_assert(message)
|
|
323
|
+
|
|
324
|
+
def OnInit(self) -> None:
|
|
325
|
+
"""DEPRECATED: Use on_init."""
|
|
326
|
+
return
|
|
327
|
+
|
|
328
|
+
def OnTearDown(self) -> None:
|
|
329
|
+
"""DEPRECATED: Use on_tear_down."""
|
|
330
|
+
return
|
|
331
|
+
|
|
332
|
+
def OnConnected(self) -> None:
|
|
333
|
+
"""DEPRECATED: Use on_connected."""
|
|
334
|
+
return
|