iris-pex-embedded-python 2.3.27b2__py3-none-any.whl → 3.2.1b3__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.
Potentially problematic release.
This version of iris-pex-embedded-python might be problematic. Click here for more details.
- grongier/cls/Grongier/PEX/BusinessOperation.cls +1 -28
- grongier/cls/Grongier/PEX/BusinessProcess.cls +1 -100
- grongier/cls/Grongier/PEX/BusinessService.cls +1 -28
- grongier/cls/Grongier/PEX/Common.cls +1 -194
- grongier/cls/Grongier/PEX/Director.cls +1 -48
- grongier/cls/Grongier/PEX/Duplex/Operation.cls +1 -26
- grongier/cls/Grongier/PEX/Duplex/Process.cls +1 -217
- grongier/cls/Grongier/PEX/Duplex/Service.cls +1 -6
- grongier/cls/Grongier/PEX/InboundAdapter.cls +1 -15
- grongier/cls/Grongier/PEX/Message.cls +1 -116
- grongier/cls/Grongier/PEX/OutboundAdapter.cls +1 -29
- grongier/cls/Grongier/PEX/PickleMessage.cls +1 -46
- grongier/cls/Grongier/PEX/PrivateSession/Duplex.cls +1 -253
- grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls +1 -19
- grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls +1 -19
- grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls +1 -19
- grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls +1 -35
- grongier/cls/Grongier/PEX/Test.cls +1 -53
- grongier/cls/Grongier/PEX/Utils.cls +1 -365
- grongier/cls/Grongier/Service/WSGI.cls +1 -307
- grongier/pex/__init__.py +11 -11
- grongier/pex/__main__.py +1 -1
- grongier/pex/_business_host.py +1 -511
- grongier/pex/_cli.py +2 -150
- grongier/pex/_common.py +1 -347
- grongier/pex/_director.py +1 -286
- grongier/pex/_utils.py +1 -369
- intersystems_iris/_ConnectionInformation.py +22 -20
- intersystems_iris/dbapi/_DBAPI.py +6 -1
- intersystems_iris/dbapi/_ResultSetRow.py +26 -15
- intersystems_iris/dbapi/preparser/_PreParser.py +4 -1
- iop/__init__.py +24 -0
- iop/__main__.py +4 -0
- iop/_business_host.py +675 -0
- iop/_business_operation.py +71 -0
- iop/_business_process.py +220 -0
- {grongier/pex → iop}/_business_service.py +2 -2
- iop/_cli.py +196 -0
- iop/_common.py +352 -0
- iop/_director.py +301 -0
- {grongier/pex → iop}/_inbound_adapter.py +1 -1
- iop/_log_manager.py +81 -0
- {grongier/pex → iop}/_message.py +1 -1
- {grongier/pex → iop}/_outbound_adapter.py +1 -1
- {grongier/pex → iop}/_private_session_duplex.py +3 -2
- {grongier/pex → iop}/_private_session_process.py +2 -2
- iop/_utils.py +458 -0
- iop/cls/IOP/BusinessOperation.cls +35 -0
- iop/cls/IOP/BusinessProcess.cls +124 -0
- iop/cls/IOP/BusinessService.cls +35 -0
- iop/cls/IOP/Common.cls +344 -0
- iop/cls/IOP/Director.cls +62 -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/InboundAdapter.cls +22 -0
- iop/cls/IOP/Message/JSONSchema.cls +125 -0
- iop/cls/IOP/Message.cls +729 -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 +32 -0
- iop/cls/IOP/PrivateSession/Message/Stop.cls +48 -0
- iop/cls/IOP/Service/WSGI.cls +310 -0
- iop/cls/IOP/Test.cls +85 -0
- iop/cls/IOP/Utils.cls +378 -0
- iop/wsgi/handlers.py +104 -0
- iris_pex_embedded_python-3.2.1b3.dist-info/METADATA +90 -0
- iris_pex_embedded_python-3.2.1b3.dist-info/RECORD +139 -0
- {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b3.dist-info}/WHEEL +1 -1
- iris_pex_embedded_python-3.2.1b3.dist-info/entry_points.txt +2 -0
- {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b3.dist-info}/top_level.txt +1 -1
- grongier/pex/_business_operation.py +0 -70
- grongier/pex/_business_process.py +0 -215
- iris/__init__.py +0 -60
- iris/__init__.pyi +0 -236
- iris/iris_ipm.py +0 -40
- iris/iris_ipm.pyi +0 -17
- iris_pex_embedded_python-2.3.27b2.dist-info/METADATA +0 -1384
- iris_pex_embedded_python-2.3.27b2.dist-info/RECORD +0 -113
- iris_pex_embedded_python-2.3.27b2.dist-info/entry_points.txt +0 -2
- {grongier/pex → iop}/_pickle_message.py +0 -0
- {iris_pex_embedded_python-2.3.27b2.dist-info → iris_pex_embedded_python-3.2.1b3.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from typing import Any, List, Optional, Union, Tuple
|
|
3
|
+
from iop._business_host import _BusinessHost
|
|
4
|
+
|
|
5
|
+
class _BusinessOperation(_BusinessHost):
|
|
6
|
+
"""Business operation component that handles outbound communication.
|
|
7
|
+
|
|
8
|
+
Responsible for sending messages to external systems. Can optionally use an
|
|
9
|
+
adapter to handle the outbound messaging protocol.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
DISPATCH: List[Tuple[str, str]] = []
|
|
13
|
+
Adapter: Any = None
|
|
14
|
+
adapter: Any = None
|
|
15
|
+
|
|
16
|
+
def on_message(self, request: Any) -> Any:
|
|
17
|
+
"""Handle incoming messages.
|
|
18
|
+
|
|
19
|
+
Process messages received from other production components and either
|
|
20
|
+
send to external system or forward to another component.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
request: The incoming message
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Response message
|
|
27
|
+
"""
|
|
28
|
+
return self.OnMessage(request)
|
|
29
|
+
|
|
30
|
+
def on_keepalive(self) -> None:
|
|
31
|
+
"""
|
|
32
|
+
Called when the server sends a keepalive message.
|
|
33
|
+
"""
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
|
|
37
|
+
"""For internal use only."""
|
|
38
|
+
self.iris_handle = handle_current
|
|
39
|
+
if type(handle_partner).__module__.find('iris') == 0:
|
|
40
|
+
if handle_partner._IsA("Grongier.PEX.OutboundAdapter") or handle_partner._IsA("IOP.OutboundAdapter"):
|
|
41
|
+
module = importlib.import_module(handle_partner.GetModule())
|
|
42
|
+
handle_partner = getattr(module, handle_partner.GetClassname())()
|
|
43
|
+
self.Adapter = self.adapter = handle_partner
|
|
44
|
+
return
|
|
45
|
+
|
|
46
|
+
def _dispatch_on_init(self, host_object: Any) -> None:
|
|
47
|
+
"""For internal use only."""
|
|
48
|
+
self._create_dispatch()
|
|
49
|
+
self.on_init()
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
@_BusinessHost.input_deserialzer
|
|
53
|
+
@_BusinessHost.output_serialzer
|
|
54
|
+
def _dispatch_on_message(self, request: Any) -> Any:
|
|
55
|
+
"""For internal use only."""
|
|
56
|
+
return self._dispach_message(request)
|
|
57
|
+
|
|
58
|
+
def OnMessage(self, request: Any) -> Any:
|
|
59
|
+
"""DEPRECATED : use on_message
|
|
60
|
+
Called when the business operation receives a message from another production component.
|
|
61
|
+
Typically, the operation will either send the message to the external system or forward it to a business process or another business operation.
|
|
62
|
+
If the operation has an adapter, it uses the Adapter.invoke() method to call the method on the adapter that sends the message to the external system.
|
|
63
|
+
If the operation is forwarding the message to another production component, it uses the SendRequestAsync() or the SendRequestSync() method
|
|
64
|
+
|
|
65
|
+
Parameters:
|
|
66
|
+
request: An instance of either a subclass of Message or of IRISObject containing the incoming message for the business operation.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
The response object
|
|
70
|
+
"""
|
|
71
|
+
return
|
iop/_business_process.py
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
from typing import Any, List, Optional, Union
|
|
2
|
+
from iop._business_host import _BusinessHost
|
|
3
|
+
|
|
4
|
+
class _BusinessProcess(_BusinessHost):
|
|
5
|
+
"""Business process component that contains routing and transformation logic.
|
|
6
|
+
|
|
7
|
+
A business process can receive messages from services, other processes, or operations.
|
|
8
|
+
It can modify messages, transform formats, and route based on content.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
DISPATCH: List[tuple] = []
|
|
12
|
+
PERSISTENT_PROPERTY_LIST: Optional[List[str]] = None
|
|
13
|
+
|
|
14
|
+
def on_message(self, request: Any) -> Any:
|
|
15
|
+
"""Handle incoming messages.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
request: The incoming message
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
Response message
|
|
22
|
+
"""
|
|
23
|
+
return self.on_request(request)
|
|
24
|
+
|
|
25
|
+
def on_request(self, request: Any) -> Any:
|
|
26
|
+
"""Process initial requests sent to this component.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
request: The incoming request message
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
Response message
|
|
33
|
+
"""
|
|
34
|
+
return self.OnRequest(request)
|
|
35
|
+
|
|
36
|
+
def on_response(self, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
|
|
37
|
+
"""Handle responses to messages sent by this component.
|
|
38
|
+
|
|
39
|
+
Args:
|
|
40
|
+
request: The initial request message
|
|
41
|
+
response: The response message
|
|
42
|
+
call_request: The request sent to the target
|
|
43
|
+
call_response: The incoming response
|
|
44
|
+
completion_key: The completion key specified in the outgoing SendAsync() method
|
|
45
|
+
|
|
46
|
+
Returns:
|
|
47
|
+
Response message
|
|
48
|
+
"""
|
|
49
|
+
return self.OnResponse(request, response, call_request, call_response, completion_key)
|
|
50
|
+
|
|
51
|
+
def on_complete(self, request: Any, response: Any) -> Any:
|
|
52
|
+
"""Called after all responses to requests sent by this component have been handled.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
request: The initial request message
|
|
56
|
+
response: The response message
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Response message
|
|
60
|
+
"""
|
|
61
|
+
return self.OnComplete(request, response)
|
|
62
|
+
|
|
63
|
+
@_BusinessHost.input_serialzer_param(0,'response')
|
|
64
|
+
def reply(self, response: Any) -> None:
|
|
65
|
+
"""Send the specified response to the production component that sent the initial request.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
response: The response message
|
|
69
|
+
"""
|
|
70
|
+
return self.iris_handle.dispatchReply(response)
|
|
71
|
+
|
|
72
|
+
@_BusinessHost.input_serialzer_param(1,'request')
|
|
73
|
+
def send_request_async(self, target: str, request: Any, response_required: bool=True, completion_key: Optional[str]=None, description: Optional[str]=None) -> None:
|
|
74
|
+
"""Send the specified message to the target business process or business operation asynchronously.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
target: The name of the business process or operation to receive the request
|
|
78
|
+
request: The message to send to the target
|
|
79
|
+
response_required: Whether a response is required
|
|
80
|
+
completion_key: A string that will be returned with the response if the maximum time is exceeded
|
|
81
|
+
description: An optional description property in the message header
|
|
82
|
+
|
|
83
|
+
Raises:
|
|
84
|
+
TypeError: If request is not of type Message or IRISObject
|
|
85
|
+
"""
|
|
86
|
+
if response_required:
|
|
87
|
+
response_required = 1
|
|
88
|
+
else:
|
|
89
|
+
response_required = 0
|
|
90
|
+
return self.iris_handle.dispatchSendRequestAsync(target, request, response_required, completion_key, description)
|
|
91
|
+
|
|
92
|
+
def set_timer(self, timeout: Union[int, str], completion_key: Optional[str]=None) -> None:
|
|
93
|
+
"""Specify the maximum time the business process will wait for responses.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
timeout: The maximum time to wait for responses
|
|
97
|
+
completion_key: A string that will be returned with the response if the maximum time is exceeded
|
|
98
|
+
"""
|
|
99
|
+
self.iris_handle.dispatchSetTimer(timeout, completion_key)
|
|
100
|
+
return
|
|
101
|
+
|
|
102
|
+
def _set_iris_handles(self, handle_current: Any, handle_partner: Any) -> None:
|
|
103
|
+
"""For internal use only."""
|
|
104
|
+
self.iris_handle = handle_current
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
def _save_persistent_properties(self, host_object: Any) -> None:
|
|
108
|
+
"""For internal use only."""
|
|
109
|
+
if self.PERSISTENT_PROPERTY_LIST is None:
|
|
110
|
+
return
|
|
111
|
+
for prop in self.PERSISTENT_PROPERTY_LIST:
|
|
112
|
+
val = getattr(self, prop, None)
|
|
113
|
+
typ = val.__class__.__name__
|
|
114
|
+
if typ in ["str", "int", "float", "bool", "bytes"]:
|
|
115
|
+
try:
|
|
116
|
+
host_object.setPersistentProperty(prop, val)
|
|
117
|
+
except:
|
|
118
|
+
pass
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
def _restore_persistent_properties(self, host_object: Any) -> None:
|
|
122
|
+
"""For internal use only."""
|
|
123
|
+
if self.PERSISTENT_PROPERTY_LIST is None:
|
|
124
|
+
return
|
|
125
|
+
for prop in self.PERSISTENT_PROPERTY_LIST:
|
|
126
|
+
try:
|
|
127
|
+
val = host_object.getPersistentProperty(prop)
|
|
128
|
+
setattr(self, prop, val)
|
|
129
|
+
except:
|
|
130
|
+
pass
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
def _dispatch_on_connected(self, host_object: Any) -> None:
|
|
134
|
+
"""For internal use only."""
|
|
135
|
+
self.on_connected()
|
|
136
|
+
self._save_persistent_properties(host_object)
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
def _dispatch_on_init(self, host_object: Any) -> None:
|
|
140
|
+
"""For internal use only."""
|
|
141
|
+
self._restore_persistent_properties(host_object)
|
|
142
|
+
self._create_dispatch()
|
|
143
|
+
self.on_init()
|
|
144
|
+
self._save_persistent_properties(host_object)
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
def _dispatch_on_tear_down(self, host_object: Any) -> None:
|
|
148
|
+
"""For internal use only."""
|
|
149
|
+
self._restore_persistent_properties(host_object)
|
|
150
|
+
self.on_tear_down()
|
|
151
|
+
self._save_persistent_properties(host_object)
|
|
152
|
+
return
|
|
153
|
+
|
|
154
|
+
@_BusinessHost.input_deserialzer
|
|
155
|
+
@_BusinessHost.output_serialzer
|
|
156
|
+
def _dispatch_on_request(self, host_object: Any, request: Any) -> Any:
|
|
157
|
+
"""For internal use only."""
|
|
158
|
+
self._restore_persistent_properties(host_object)
|
|
159
|
+
return_object = self._dispach_message(request)
|
|
160
|
+
self._save_persistent_properties(host_object)
|
|
161
|
+
return return_object
|
|
162
|
+
|
|
163
|
+
@_BusinessHost.input_deserialzer
|
|
164
|
+
@_BusinessHost.output_serialzer
|
|
165
|
+
def _dispatch_on_response(self, host_object: Any, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
|
|
166
|
+
"""For internal use only."""
|
|
167
|
+
self._restore_persistent_properties(host_object)
|
|
168
|
+
return_object = self.on_response(request, response, call_request, call_response, completion_key)
|
|
169
|
+
self._save_persistent_properties(host_object)
|
|
170
|
+
return return_object
|
|
171
|
+
|
|
172
|
+
@_BusinessHost.input_deserialzer
|
|
173
|
+
@_BusinessHost.output_serialzer
|
|
174
|
+
def _dispatch_on_complete(self, host_object: Any, request: Any, response: Any) -> Any:
|
|
175
|
+
"""For internal use only."""
|
|
176
|
+
self._restore_persistent_properties(host_object)
|
|
177
|
+
return_object = self.on_complete(request, response)
|
|
178
|
+
self._save_persistent_properties(host_object)
|
|
179
|
+
return return_object
|
|
180
|
+
|
|
181
|
+
def OnRequest(self, request: Any) -> Any:
|
|
182
|
+
"""
|
|
183
|
+
DEPRECATED: Use on_request.
|
|
184
|
+
|
|
185
|
+
Args:
|
|
186
|
+
request: The incoming request message
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
Response message
|
|
190
|
+
"""
|
|
191
|
+
return
|
|
192
|
+
|
|
193
|
+
def OnResponse(self, request: Any, response: Any, call_request: Any, call_response: Any, completion_key: str) -> Any:
|
|
194
|
+
"""
|
|
195
|
+
DEPRECATED: Use on_response.
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
request: The initial request message
|
|
199
|
+
response: The response message
|
|
200
|
+
call_request: The request sent to the target
|
|
201
|
+
call_response: The incoming response
|
|
202
|
+
completion_key: The completion key specified in the outgoing SendAsync() method
|
|
203
|
+
|
|
204
|
+
Returns:
|
|
205
|
+
Response message
|
|
206
|
+
"""
|
|
207
|
+
return response
|
|
208
|
+
|
|
209
|
+
def OnComplete(self, request: Any, response: Any) -> Any:
|
|
210
|
+
"""
|
|
211
|
+
DEPRECATED: Use on_complete.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
request: The initial request message
|
|
215
|
+
response: The response message
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
Response message
|
|
219
|
+
"""
|
|
220
|
+
return response
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import importlib
|
|
2
|
-
from
|
|
2
|
+
from iop._business_host import _BusinessHost
|
|
3
3
|
|
|
4
4
|
class _BusinessService(_BusinessHost):
|
|
5
5
|
""" This class is responsible for receiving the data from external system and sending it to business processes or business operations in the production.
|
|
@@ -30,7 +30,7 @@ class _BusinessService(_BusinessHost):
|
|
|
30
30
|
""" For internal use only. """
|
|
31
31
|
self.iris_handle = handle_current
|
|
32
32
|
if type(handle_partner).__module__.find('iris') == 0:
|
|
33
|
-
if handle_partner._IsA("Grongier.PEX.InboundAdapter"):
|
|
33
|
+
if handle_partner._IsA("Grongier.PEX.InboundAdapter") or handle_partner._IsA("IOP.InboundAdapter"):
|
|
34
34
|
module = importlib.import_module(handle_partner.GetModule())
|
|
35
35
|
handle_partner = getattr(module, handle_partner.GetClassname())()
|
|
36
36
|
self.Adapter = self.adapter = handle_partner
|
iop/_cli.py
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from enum import Enum, auto
|
|
7
|
+
import sys
|
|
8
|
+
from typing import Optional, Callable
|
|
9
|
+
from importlib.metadata import version
|
|
10
|
+
|
|
11
|
+
from iop._director import _Director
|
|
12
|
+
from iop._utils import _Utils
|
|
13
|
+
|
|
14
|
+
class CommandType(Enum):
|
|
15
|
+
DEFAULT = auto()
|
|
16
|
+
LIST = auto()
|
|
17
|
+
START = auto()
|
|
18
|
+
STOP = auto()
|
|
19
|
+
KILL = auto()
|
|
20
|
+
RESTART = auto()
|
|
21
|
+
STATUS = auto()
|
|
22
|
+
TEST = auto()
|
|
23
|
+
VERSION = auto()
|
|
24
|
+
EXPORT = auto()
|
|
25
|
+
MIGRATE = auto()
|
|
26
|
+
LOG = auto()
|
|
27
|
+
INIT = auto()
|
|
28
|
+
HELP = auto()
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class CommandArgs:
|
|
32
|
+
"""Container for parsed command arguments"""
|
|
33
|
+
default: Optional[str] = None
|
|
34
|
+
list: bool = False
|
|
35
|
+
start: Optional[str] = None
|
|
36
|
+
detach: bool = False
|
|
37
|
+
stop: bool = False
|
|
38
|
+
kill: bool = False
|
|
39
|
+
restart: bool = False
|
|
40
|
+
status: bool = False
|
|
41
|
+
migrate: Optional[str] = None
|
|
42
|
+
export: Optional[str] = None
|
|
43
|
+
version: bool = False
|
|
44
|
+
log: Optional[str] = None
|
|
45
|
+
init: Optional[str] = None
|
|
46
|
+
test: Optional[str] = None
|
|
47
|
+
classname: Optional[str] = None
|
|
48
|
+
body: Optional[str] = None
|
|
49
|
+
|
|
50
|
+
class Command:
|
|
51
|
+
def __init__(self, args: CommandArgs):
|
|
52
|
+
self.args = args
|
|
53
|
+
|
|
54
|
+
def execute(self) -> None:
|
|
55
|
+
command_type = self._determine_command_type()
|
|
56
|
+
command_handlers = {
|
|
57
|
+
CommandType.DEFAULT: self._handle_default,
|
|
58
|
+
CommandType.LIST: self._handle_list,
|
|
59
|
+
CommandType.START: self._handle_start,
|
|
60
|
+
CommandType.STOP: self._handle_stop,
|
|
61
|
+
CommandType.KILL: self._handle_kill,
|
|
62
|
+
CommandType.RESTART: self._handle_restart,
|
|
63
|
+
CommandType.STATUS: self._handle_status,
|
|
64
|
+
CommandType.TEST: self._handle_test,
|
|
65
|
+
CommandType.VERSION: self._handle_version,
|
|
66
|
+
CommandType.EXPORT: self._handle_export,
|
|
67
|
+
CommandType.MIGRATE: self._handle_migrate,
|
|
68
|
+
CommandType.LOG: self._handle_log,
|
|
69
|
+
CommandType.INIT: self._handle_init,
|
|
70
|
+
CommandType.HELP: self._handle_help
|
|
71
|
+
}
|
|
72
|
+
handler = command_handlers.get(command_type)
|
|
73
|
+
if handler:
|
|
74
|
+
handler()
|
|
75
|
+
|
|
76
|
+
def _determine_command_type(self) -> CommandType:
|
|
77
|
+
if self.args.default: return CommandType.DEFAULT
|
|
78
|
+
if self.args.list: return CommandType.LIST
|
|
79
|
+
if self.args.start: return CommandType.START
|
|
80
|
+
if self.args.stop: return CommandType.STOP
|
|
81
|
+
if self.args.kill: return CommandType.KILL
|
|
82
|
+
if self.args.restart: return CommandType.RESTART
|
|
83
|
+
if self.args.status: return CommandType.STATUS
|
|
84
|
+
if self.args.test: return CommandType.TEST
|
|
85
|
+
if self.args.version: return CommandType.VERSION
|
|
86
|
+
if self.args.export: return CommandType.EXPORT
|
|
87
|
+
if self.args.migrate: return CommandType.MIGRATE
|
|
88
|
+
if self.args.log: return CommandType.LOG
|
|
89
|
+
if self.args.init: return CommandType.INIT
|
|
90
|
+
return CommandType.HELP
|
|
91
|
+
|
|
92
|
+
def _handle_default(self) -> None:
|
|
93
|
+
if self.args.default == 'not_set':
|
|
94
|
+
print(_Director.get_default_production())
|
|
95
|
+
else:
|
|
96
|
+
_Director.set_default_production(self.args.default)
|
|
97
|
+
|
|
98
|
+
def _handle_list(self) -> None:
|
|
99
|
+
dikt = _Director.list_productions()
|
|
100
|
+
print(json.dumps(dikt, indent=4))
|
|
101
|
+
|
|
102
|
+
def _handle_start(self) -> None:
|
|
103
|
+
production_name = self.args.start if self.args.start != 'not_set' else _Director.get_default_production()
|
|
104
|
+
if self.args.detach:
|
|
105
|
+
_Director.start_production(production_name)
|
|
106
|
+
print(f"Production {production_name} started")
|
|
107
|
+
else:
|
|
108
|
+
_Director.start_production_with_log(production_name)
|
|
109
|
+
|
|
110
|
+
def _handle_stop(self) -> None:
|
|
111
|
+
_Director.stop_production()
|
|
112
|
+
print(f"Production {_Director.get_default_production()} stopped")
|
|
113
|
+
|
|
114
|
+
def _handle_kill(self) -> None:
|
|
115
|
+
_Director.shutdown_production()
|
|
116
|
+
|
|
117
|
+
def _handle_restart(self) -> None:
|
|
118
|
+
_Director.restart_production()
|
|
119
|
+
|
|
120
|
+
def _handle_status(self) -> None:
|
|
121
|
+
print(json.dumps(_Director.status_production(), indent=4))
|
|
122
|
+
|
|
123
|
+
def _handle_test(self) -> None:
|
|
124
|
+
test_name = None if self.args.test == 'not_set' else self.args.test
|
|
125
|
+
response = _Director.test_component(
|
|
126
|
+
test_name,
|
|
127
|
+
classname=self.args.classname if self.args.classname != 'not_set' else None,
|
|
128
|
+
body=self.args.body if self.args.body != 'not_set' else None
|
|
129
|
+
)
|
|
130
|
+
print(response)
|
|
131
|
+
|
|
132
|
+
def _handle_version(self) -> None:
|
|
133
|
+
print(version('iris-pex-embedded-python'))
|
|
134
|
+
|
|
135
|
+
def _handle_export(self) -> None:
|
|
136
|
+
export_name = _Director.get_default_production() if self.args.export == 'not_set' else self.args.export
|
|
137
|
+
print(json.dumps(_Utils.export_production(export_name), indent=4))
|
|
138
|
+
|
|
139
|
+
def _handle_migrate(self) -> None:
|
|
140
|
+
migrate_path = self.args.migrate
|
|
141
|
+
if not os.path.isabs(migrate_path):
|
|
142
|
+
migrate_path = os.path.join(os.getcwd(), migrate_path)
|
|
143
|
+
_Utils.migrate(migrate_path)
|
|
144
|
+
|
|
145
|
+
def _handle_log(self) -> None:
|
|
146
|
+
log_name = _Director.get_default_production() if self.args.log == 'not_set' else self.args.log
|
|
147
|
+
print(_Director.get_production_log(log_name))
|
|
148
|
+
|
|
149
|
+
def _handle_init(self) -> None:
|
|
150
|
+
_Utils.setup(None)
|
|
151
|
+
|
|
152
|
+
def _handle_help(self) -> None:
|
|
153
|
+
create_parser().print_help()
|
|
154
|
+
print(f"\nDefault production: {_Director.get_default_production()}")
|
|
155
|
+
|
|
156
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
157
|
+
"""Create and configure argument parser"""
|
|
158
|
+
main_parser = argparse.ArgumentParser()
|
|
159
|
+
parser = main_parser.add_mutually_exclusive_group()
|
|
160
|
+
|
|
161
|
+
# Main commands
|
|
162
|
+
parser.add_argument('-d', '--default', help='set the default production', nargs='?', const='not_set')
|
|
163
|
+
parser.add_argument('-l', '--list', help='list productions', action='store_true')
|
|
164
|
+
parser.add_argument('-s', '--start', help='start a production', nargs='?', const='not_set')
|
|
165
|
+
parser.add_argument('-S', '--stop', help='stop a production', action='store_true')
|
|
166
|
+
parser.add_argument('-k', '--kill', help='kill a production', action='store_true')
|
|
167
|
+
parser.add_argument('-r', '--restart', help='restart a production', action='store_true')
|
|
168
|
+
parser.add_argument('-x', '--status', help='status a production', action='store_true')
|
|
169
|
+
parser.add_argument('-m', '-M', '--migrate', help='migrate production and classes with settings file')
|
|
170
|
+
parser.add_argument('-e', '--export', help='export a production', nargs='?', const='not_set')
|
|
171
|
+
parser.add_argument('-v', '--version', help='display version', action='store_true')
|
|
172
|
+
parser.add_argument('-L', '--log', help='display log', nargs='?', const='not_set')
|
|
173
|
+
parser.add_argument('-i', '--init', help='init the pex module in iris', nargs='?', const='not_set')
|
|
174
|
+
parser.add_argument('-t', '--test', help='test the pex module in iris', nargs='?', const='not_set')
|
|
175
|
+
|
|
176
|
+
# Command groups
|
|
177
|
+
start = main_parser.add_argument_group('start arguments')
|
|
178
|
+
start.add_argument('-D', '--detach', help='start a production in detach mode', action='store_true')
|
|
179
|
+
|
|
180
|
+
test = main_parser.add_argument_group('test arguments')
|
|
181
|
+
test.add_argument('-C', '--classname', help='test classname', nargs='?', const='not_set')
|
|
182
|
+
test.add_argument('-B', '--body', help='test body', nargs='?', const='not_set')
|
|
183
|
+
|
|
184
|
+
return main_parser
|
|
185
|
+
|
|
186
|
+
def main(argv=None) -> None:
|
|
187
|
+
parser = create_parser()
|
|
188
|
+
args = parser.parse_args(argv)
|
|
189
|
+
cmd_args = CommandArgs(**vars(args))
|
|
190
|
+
|
|
191
|
+
command = Command(cmd_args)
|
|
192
|
+
command.execute()
|
|
193
|
+
sys.exit(0)
|
|
194
|
+
|
|
195
|
+
if __name__ == '__main__':
|
|
196
|
+
main()
|