iris-pex-embedded-python 2.3.28b3__py3-none-any.whl → 3.0.0__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 -112
- 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 +1 -152
- grongier/pex/_common.py +1 -347
- grongier/pex/_director.py +1 -286
- grongier/pex/_utils.py +1 -369
- iop/__init__.py +24 -0
- iop/__main__.py +4 -0
- iop/_business_host.py +511 -0
- {grongier/pex → iop}/_business_operation.py +1 -1
- {grongier/pex → iop}/_business_process.py +1 -1
- {grongier/pex → iop}/_business_service.py +1 -1
- iop/_cli.py +152 -0
- iop/_common.py +349 -0
- iop/_director.py +286 -0
- {grongier/pex → iop}/_inbound_adapter.py +1 -1
- {grongier/pex → iop}/_outbound_adapter.py +1 -1
- {grongier/pex → iop}/_private_session_duplex.py +1 -1
- {grongier/pex → iop}/_private_session_process.py +2 -2
- iop/_utils.py +374 -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 +203 -0
- iop/cls/IOP/Director.cls +57 -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.cls +128 -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 +62 -0
- iop/cls/IOP/Utils.cls +374 -0
- iop/wsgi/handlers.py +104 -0
- {iris_pex_embedded_python-2.3.28b3.dist-info → iris_pex_embedded_python-3.0.0.dist-info}/METADATA +28 -28
- {iris_pex_embedded_python-2.3.28b3.dist-info → iris_pex_embedded_python-3.0.0.dist-info}/RECORD +70 -42
- {iris_pex_embedded_python-2.3.28b3.dist-info → iris_pex_embedded_python-3.0.0.dist-info}/WHEEL +1 -1
- iris_pex_embedded_python-3.0.0.dist-info/entry_points.txt +2 -0
- {iris_pex_embedded_python-2.3.28b3.dist-info → iris_pex_embedded_python-3.0.0.dist-info}/top_level.txt +1 -0
- iris_pex_embedded_python-2.3.28b3.dist-info/entry_points.txt +0 -2
- {grongier/pex → iop}/_message.py +0 -0
- {grongier/pex → iop}/_pickle_message.py +0 -0
- {iris_pex_embedded_python-2.3.28b3.dist-info → iris_pex_embedded_python-3.0.0.dist-info}/LICENSE +0 -0
|
@@ -4,371 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Include Ensemble
|
|
6
6
|
|
|
7
|
-
Class Grongier.PEX.Utils Extends
|
|
7
|
+
Class Grongier.PEX.Utils Extends IOP.Utils
|
|
8
8
|
{
|
|
9
9
|
|
|
10
|
-
ClassMethod dispatchRegisterComponent(
|
|
11
|
-
pModule As %String,
|
|
12
|
-
pRemoteClassname As %String,
|
|
13
|
-
pCLASSPATHS As %String = "",
|
|
14
|
-
pOverwrite As %Boolean = 0,
|
|
15
|
-
pProxyClassname As %String = "") As %Status
|
|
16
|
-
{
|
|
17
|
-
set tSc = $$$OK
|
|
18
|
-
$$$ThrowOnError(##class(Grongier.PEX.Utils).RegisterComponent(pModule, pRemoteClassname, pCLASSPATHS, pOverwrite , pProxyClassname))
|
|
19
|
-
return tSc
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/// "bo","Duplex","/irisdev/app/src/python/demo/duplex/",1,"Duplex.Duplex"
|
|
23
|
-
ClassMethod RegisterComponent(
|
|
24
|
-
pModule As %String,
|
|
25
|
-
pRemoteClassname As %String,
|
|
26
|
-
pCLASSPATHS As %String = "",
|
|
27
|
-
pOverwrite As %Boolean = 0,
|
|
28
|
-
pProxyClassname As %String = "") As %Status
|
|
29
|
-
{
|
|
30
|
-
#dim tSC As %Status = $$$OK
|
|
31
|
-
#dim ex As %Exception.AbstractException
|
|
32
|
-
#dim tLanguage,tExtraClasspaths,tDelimiter,tOnePath As %String = ""
|
|
33
|
-
#dim tClassDetails,tRemoteSettings As %String = ""
|
|
34
|
-
#dim tClasspaths As %ListOfDataTypes
|
|
35
|
-
|
|
36
|
-
Quit:(""=pRemoteClassname) $$$ERROR($$$EnsErrGeneral,"Remote Classname must be specified in order to register a Production EXtensions component")
|
|
37
|
-
Quit:(""=pModule) $$$ERROR($$$EnsErrGeneral,"Must specify the module of the remote code.")
|
|
38
|
-
|
|
39
|
-
Try {
|
|
40
|
-
|
|
41
|
-
$$$ThrowOnError(..GetRemoteClassInfo(pRemoteClassname,pModule,pCLASSPATHS,.tClassDetails,.tRemoteSettings))
|
|
42
|
-
|
|
43
|
-
Set tConnectionSettings("Classpaths") = pCLASSPATHS
|
|
44
|
-
Set tConnectionSettings("Module") = pModule
|
|
45
|
-
Set tConnectionSettings("Classname") = pRemoteClassname
|
|
46
|
-
Set:(""=pProxyClassname) pProxyClassname = "User."_pRemoteClassname
|
|
47
|
-
|
|
48
|
-
$$$ThrowOnError(..GenerateProxyClass(pProxyClassname,.tConnectionSettings,tClassDetails,tRemoteSettings,pOverwrite))
|
|
49
|
-
|
|
50
|
-
} Catch ex {
|
|
51
|
-
set msg = $System.Status.GetOneStatusText(ex.AsStatus(),1)
|
|
52
|
-
set tSC = $$$ERROR($$$EnsErrGeneral,msg)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
Quit tSC
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
ClassMethod DeleteComponentProxy(pClassname As %String = "") As %Status
|
|
59
|
-
{
|
|
60
|
-
#dim tSC As %Status = $$$OK
|
|
61
|
-
#dim ex As %Exception.AbstractException
|
|
62
|
-
#dim tIsPEX As %Boolean = 0
|
|
63
|
-
#dim tClass As %Dictionary.CompiledClass
|
|
64
|
-
|
|
65
|
-
Quit:(""=pClassname) $$$ERROR($$$EnsErrGeneral,"Remote class name must be specified.")
|
|
66
|
-
|
|
67
|
-
Try {
|
|
68
|
-
|
|
69
|
-
If '##class(%Dictionary.ClassDefinition).%ExistsId(pClassname) {
|
|
70
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("No proxy class defined for remote class '%1'.",pClassname))
|
|
71
|
-
Quit
|
|
72
|
-
}
|
|
73
|
-
If $classmethod(pClassname,"%Extends","Grongier.PEX.Common") {
|
|
74
|
-
Set tClass = ##class(%Dictionary.CompiledClass).%OpenId(pClassname,,.tSC)
|
|
75
|
-
Quit:$$$ISERR(tSC)
|
|
76
|
-
If '$IsObject(tClass) {
|
|
77
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Proxy class for remote class '%1' could not be opened.",pClassname))
|
|
78
|
-
Quit
|
|
79
|
-
}
|
|
80
|
-
Set tIsPEX = ("Grongier.PEX.Utils" = tClass.GeneratedBy)
|
|
81
|
-
}
|
|
82
|
-
If tIsPEX {
|
|
83
|
-
Set tSC = ##class(%Dictionary.ClassDefinition).%DeleteId(pClassname)
|
|
84
|
-
If $$$ISERR(tSC) {
|
|
85
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Unable to delete proxy class for remote class '%1' : '%2'.",pClassname,$System.Status.GetErrorText(tSC)))
|
|
86
|
-
Quit
|
|
87
|
-
}
|
|
88
|
-
} Else {
|
|
89
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Cannot delete class '%1' because it is not a PEX proxy class.",pClassname))
|
|
90
|
-
Quit
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
} Catch ex {
|
|
94
|
-
Set tSC = ex.AsStatus()
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
Quit tSC
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// ..GetRemoteClassInfo(pRemoteClassname,pModule,pCLASSPATHS,.tClassDetails,.tRemoteSettings)
|
|
101
|
-
|
|
102
|
-
ClassMethod GetRemoteClassInfo(
|
|
103
|
-
pRemoteClassname As %String,
|
|
104
|
-
pModule As %String,
|
|
105
|
-
pClasspaths As %String,
|
|
106
|
-
ByRef pClassDetails,
|
|
107
|
-
ByRef pRemoteSettings) As %Status [ Internal, Private ]
|
|
108
|
-
{
|
|
109
|
-
#dim tSC As %Status = $$$OK
|
|
110
|
-
#dim ex As %Exception.AbstractException
|
|
111
|
-
#dim tGateway As %External.Gateway
|
|
112
|
-
#dim tGatewayProxy As %Net.Remote.Object
|
|
113
|
-
|
|
114
|
-
Try {
|
|
115
|
-
if pClasspaths '="" {
|
|
116
|
-
set sys = ##class(%SYS.Python).Import("sys")
|
|
117
|
-
set delimiter = $s($system.Version.GetOS()="Windows":";",1:":")
|
|
118
|
-
set extraClasspaths = $tr(pClasspaths,delimiter,"|")
|
|
119
|
-
for i=1:1:$l(extraClasspaths,"|") {
|
|
120
|
-
set onePath = $p(extraClasspaths,"|",i)
|
|
121
|
-
set onePath = ##class(%File).NormalizeDirectory(onePath)
|
|
122
|
-
if onePath?1"$$IRISHOME"1P.E set onePath = $e($system.Util.InstallDirectory(),1,*-1)_$e(onePath,11,*)
|
|
123
|
-
if onePath'="" do sys.path.append(onePath)
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
;
|
|
127
|
-
|
|
128
|
-
set importlib = ##class(%SYS.Python).Import("importlib")
|
|
129
|
-
set builtins = ##class(%SYS.Python).Import("builtins")
|
|
130
|
-
set module = importlib."import_module"(pModule)
|
|
131
|
-
set class = builtins.getattr(module, pRemoteClassname)
|
|
132
|
-
set tClass = class."__new__"(class)
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
If $IsObject(tClass) {
|
|
136
|
-
#; List of information about the class as a whole - $lb(SuperClass, Description, InfoURL, IconURL, Adapter)
|
|
137
|
-
Set pClassDetails = tClass."_get_info"()
|
|
138
|
-
#; List of information about the various properties of the class
|
|
139
|
-
#; List of lists of form $lb(propName,dataType,defaultVal,required,category,description)
|
|
140
|
-
Set pRemoteSettings = tClass."_get_properties"()
|
|
141
|
-
} Else {
|
|
142
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Error opening gateway proxy for class '%1'"),pRemoteClassname)
|
|
143
|
-
}
|
|
144
|
-
} Catch ex {
|
|
145
|
-
set msg = $System.Status.GetOneStatusText(ex.AsStatus(),1)
|
|
146
|
-
set tSC = $$$ERROR($$$EnsErrGeneral,msg)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
Quit tSC
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/// Set tConnectionSettings("Classpaths") = pCLASSPATHS
|
|
153
|
-
/// Set tConnectionSettings("Module") = pModule
|
|
154
|
-
/// Set tConnectionSettings("Classname") = pRemoteClassname
|
|
155
|
-
/// Set:(""=pProxyClassname) pProxyClassname = pRemoteClassname
|
|
156
|
-
///
|
|
157
|
-
/// Set tSC = ..GenerateProxyClass(pProxyClassname,.tConnectionSettings,tClassDetails,tRemoteSettings,pOverwrite)
|
|
158
|
-
/// "bo","Duplex","/irisdev/app/src/python/demo/duplex/",1,"Duplex.Duplex"
|
|
159
|
-
ClassMethod GenerateProxyClass(
|
|
160
|
-
pClassname As %String,
|
|
161
|
-
ByRef pConnectionSettings,
|
|
162
|
-
pClassDetails As %String = "",
|
|
163
|
-
pRemoteSettings As %String = "",
|
|
164
|
-
pOverwrite As %Boolean = 0) As %Status [ Internal, Private ]
|
|
165
|
-
{
|
|
166
|
-
#dim tSC As %Status = $$$OK
|
|
167
|
-
#dim ex As %Exception.AbstractException
|
|
168
|
-
|
|
169
|
-
Quit:(""=pClassname) $$$ERROR($$$EnsErrGeneral,"Class name must be specified in order to generate a proxy class for this Production EXtensions component")
|
|
170
|
-
|
|
171
|
-
Try {
|
|
172
|
-
|
|
173
|
-
If ##class(%Dictionary.ClassDefinition).%ExistsId(pClassname) {
|
|
174
|
-
If 'pOverwrite {
|
|
175
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Proxy class '%1' already exists.",pClassname))
|
|
176
|
-
Quit
|
|
177
|
-
} Else {
|
|
178
|
-
#dim tIsPEX As %Boolean = 0
|
|
179
|
-
If $classmethod(pClassname,"%Extends","Grongier.PEX.Common") {
|
|
180
|
-
#dim tClass As %Dictionary.CompiledClass = ##class(%Dictionary.CompiledClass).%OpenId(pClassname)
|
|
181
|
-
If '$IsObject(tClass) {
|
|
182
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,"Class not found")
|
|
183
|
-
Quit
|
|
184
|
-
}
|
|
185
|
-
Set tIsPEX = ("Grongier.PEX.Utils" = tClass.GeneratedBy)
|
|
186
|
-
}
|
|
187
|
-
If tIsPEX {
|
|
188
|
-
Set tSC = ##class(%Dictionary.ClassDefinition).%DeleteId(pClassname)
|
|
189
|
-
If $$$ISERR(tSC) {
|
|
190
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Unable to delete existing proxy class '%1' : '%2'.",pClassname,$System.Status.GetErrorText(tSC)))
|
|
191
|
-
Quit
|
|
192
|
-
}
|
|
193
|
-
} Else {
|
|
194
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,$$$FormatText("Cannot overwrite class '%1' because it is not a PEX proxy class.",pClassname))
|
|
195
|
-
Quit
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
#; create subclass of the ObjectScript Business Host
|
|
201
|
-
#dim tCOSClass As %Dictionary.ClassDefinition
|
|
202
|
-
Set tCOSClass = ##class(%Dictionary.ClassDefinition).%New()
|
|
203
|
-
Set tCOSClass.Name = pClassname
|
|
204
|
-
|
|
205
|
-
#dim tSuperClass As %String = pClassDetails."__getitem__"(0)
|
|
206
|
-
If (""=tSuperClass) {
|
|
207
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,"No PEX superclass found.")
|
|
208
|
-
Quit
|
|
209
|
-
}
|
|
210
|
-
If '$Case($P(tSuperClass,".",*),"DuplexProcess":1,"DuplexService":1,"DuplexOperation":1,"InboundAdapter":1,"OutboundAdapter":1,"BusinessService":1,"BusinessProcess":1,"BusinessOperation":1,:0) {
|
|
211
|
-
Set tSC = $$$ERROR($$$EnsErrGeneral,"Invalid superclass")
|
|
212
|
-
Quit
|
|
213
|
-
}
|
|
214
|
-
Set tSuperClass = "Grongier.PEX."_$P(tSuperClass,".",*)
|
|
215
|
-
|
|
216
|
-
Set tCOSClass.Super = tSuperClass
|
|
217
|
-
Set tCOSClass.GeneratedBy = $CLASSNAME()
|
|
218
|
-
Set tCOSClass.ClassVersion = $$$CLASSDEFINITIONVERSION
|
|
219
|
-
#dim tDescription As %String = pClassDetails."__getitem__"(1)
|
|
220
|
-
If (""'=tDescription) {
|
|
221
|
-
Set tCOSClass.Description = $Replace(tDescription,$C(10),$C(13,10))
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
#; Do not display any of the connection settings
|
|
225
|
-
#dim tSETTINGSParamValue As %String = "%classname:Python $type,%module:Python $type,%settings:Python $type,%classpaths:Python $type"
|
|
226
|
-
|
|
227
|
-
#dim tPropClassname As %Dictionary.PropertyDefinition = ##class(%Dictionary.PropertyDefinition).%New()
|
|
228
|
-
Set tPropClassname.Name = "%classname"
|
|
229
|
-
Set tPropClassname.Type = "%String"
|
|
230
|
-
Set tPropClassname.InitialExpression = $$$quote(pConnectionSettings("Classname"))
|
|
231
|
-
Set tPropClassname.Internal = 1
|
|
232
|
-
Set tSC = tCOSClass.Properties.Insert(tPropClassname)
|
|
233
|
-
Quit:$$$ISERR(tSC)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
#dim tPropClasspaths As %Dictionary.PropertyDefinition = ##class(%Dictionary.PropertyDefinition).%New()
|
|
237
|
-
Set tPropClasspaths.Name = "%classpaths"
|
|
238
|
-
Set tPropClasspaths.Type = "%String"
|
|
239
|
-
Set tSC = tPropClasspaths.Parameters.SetAt("","MAXLEN")
|
|
240
|
-
Quit:$$$ISERR(tSC)
|
|
241
|
-
Set tPropClasspaths.InitialExpression = $$$quote(pConnectionSettings("Classpaths"))
|
|
242
|
-
Set tPropClasspaths.Description = "One or more Classpaths (separated by '|' character) needed in addition to the ones configured in the Remote Gateway"
|
|
243
|
-
Set tSC = tCOSClass.Properties.Insert(tPropClasspaths)
|
|
244
|
-
Quit:$$$ISERR(tSC)
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
#dim tPropLanguage As %Dictionary.PropertyDefinition = ##class(%Dictionary.PropertyDefinition).%New()
|
|
248
|
-
Set tPropLanguage.Name = "%module"
|
|
249
|
-
Set tPropLanguage.Type = "%String"
|
|
250
|
-
Set tPropLanguage.Internal = 1
|
|
251
|
-
Set tPropLanguage.InitialExpression = $$$quote(pConnectionSettings("Module"))
|
|
252
|
-
Set tSC = tCOSClass.Properties.Insert(tPropLanguage)
|
|
253
|
-
Quit:$$$ISERR(tSC)
|
|
254
|
-
|
|
255
|
-
If $Case(tSuperClass,"Grongier.PEX.BusinessService":1,"Grongier.PEX.BusinessOperation":1,"Grongier.PEX.DuplexService":1,"Grongier.PEX.DuplexOperation":1,:0) {
|
|
256
|
-
set builtins = ##class(%SYS.Python).Import("builtins")
|
|
257
|
-
If (builtins.len(pClassDetails)>4) { //Adaptor
|
|
258
|
-
|
|
259
|
-
#dim tAdapterClass = pClassDetails."__getitem__"(4)
|
|
260
|
-
#; May want to issue a warning in the UI if the Adapter class does not exist
|
|
261
|
-
#; but we don't check here because it does compile and may just be that the user is registering the Service/Operation before the Adapter
|
|
262
|
-
#dim tADAPTERParam As %Dictionary.ParameterDefinition = ##class(%Dictionary.ParameterDefinition).%New()
|
|
263
|
-
Set tADAPTERParam.Name = "ADAPTER"
|
|
264
|
-
Set tADAPTERParam.Default = tAdapterClass
|
|
265
|
-
Set tSC = tCOSClass.Parameters.Insert(tADAPTERParam)
|
|
266
|
-
Quit:$$$ISERR(tSC)
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
set type = ""
|
|
271
|
-
set:($Case(tSuperClass,"Grongier.PEX.InboundAdapter":1,"Grongier.PEX.OutboundAdapter":1,:0)) type = "Adapter"
|
|
272
|
-
set tSETTINGSParamValue = $REPLACE(tSETTINGSParamValue,"$type",type)
|
|
273
|
-
|
|
274
|
-
#dim tSETTINGSParam As %Dictionary.ParameterDefinition = ##class(%Dictionary.ParameterDefinition).%New()
|
|
275
|
-
Set tSETTINGSParam.Name = "SETTINGS"
|
|
276
|
-
Set tSETTINGSParam.Default = tSETTINGSParamValue
|
|
277
|
-
Set tSC = tCOSClass.Parameters.Insert(tSETTINGSParam)
|
|
278
|
-
Quit:$$$ISERR(tSC)
|
|
279
|
-
|
|
280
|
-
Set tSC = tCOSClass.%Save()
|
|
281
|
-
Quit:$$$ISERR(tSC)
|
|
282
|
-
|
|
283
|
-
Set tSC = $System.OBJ.Compile(pClassname,"-d")
|
|
284
|
-
|
|
285
|
-
} Catch ex {
|
|
286
|
-
Set tSC = ex.AsStatus()
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
Quit tSC
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
ClassMethod CreateProduction(
|
|
293
|
-
package As %String = "test",
|
|
294
|
-
name As %String = "AutoCreatedProduction",
|
|
295
|
-
xdata As %CharacterStream) As %Status
|
|
296
|
-
{
|
|
297
|
-
#Dim produtionClassName As %String = package _ "." _ name
|
|
298
|
-
If ('$ZName(produtionClassName, 4))
|
|
299
|
-
{
|
|
300
|
-
Return $System.Status.Error(5001, "Invalid Production package or name.")
|
|
301
|
-
}
|
|
302
|
-
#Dim productionDefinition As %Dictionary.ClassDefinition
|
|
303
|
-
// Check if the production already exists
|
|
304
|
-
If (##class(%Dictionary.ClassDefinition).%ExistsId(produtionClassName))
|
|
305
|
-
{
|
|
306
|
-
// Open the production
|
|
307
|
-
set productionDefinition = ##class(%Dictionary.ClassDefinition).%OpenId(produtionClassName)
|
|
308
|
-
}
|
|
309
|
-
Else
|
|
310
|
-
{
|
|
311
|
-
// Create the production definition
|
|
312
|
-
set productionDefinition = ##Class(%Dictionary.ClassDefinition).%New()
|
|
313
|
-
}
|
|
314
|
-
//
|
|
315
|
-
Set productionDefinition.Name = produtionClassName
|
|
316
|
-
Set productionDefinition.Super = "Ens.Production"
|
|
317
|
-
Set productionDefinition.ClassVersion = 25
|
|
318
|
-
//
|
|
319
|
-
// Check if the XData Definition already exists
|
|
320
|
-
If (##Class(%Dictionary.XDataDefinition).%ExistsId(produtionClassName_"||ProductionDefinition"))
|
|
321
|
-
{
|
|
322
|
-
// delete the XData Definition
|
|
323
|
-
$$$ThrowOnError(##Class(%Dictionary.XDataDefinition).%DeleteId(produtionClassName_"||ProductionDefinition"))
|
|
324
|
-
}
|
|
325
|
-
#Dim xdataDefinition As %Dictionary.XDataDefinition = ##Class(%Dictionary.XDataDefinition).%New()
|
|
326
|
-
//
|
|
327
|
-
Set xdataDefinition.Name = "ProductionDefinition"
|
|
328
|
-
//
|
|
329
|
-
Do xdataDefinition.Data.CopyFrom(xdata)
|
|
330
|
-
//
|
|
331
|
-
// Insert XData Definition into Production Definition
|
|
332
|
-
Do productionDefinition.XDatas.Insert(xdataDefinition)
|
|
333
|
-
//
|
|
334
|
-
#Dim statusCode As %Status = productionDefinition.%Save()
|
|
335
|
-
//
|
|
336
|
-
If ($System.Status.IsError(statusCode))
|
|
337
|
-
{
|
|
338
|
-
Return statusCode
|
|
339
|
-
}
|
|
340
|
-
// Compile the production class
|
|
341
|
-
return $System.OBJ.Compile(produtionClassName,"k-d")
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
/// Export a production to an XML string
|
|
345
|
-
ClassMethod ExportProduction(pProductionName As %String) As %String
|
|
346
|
-
{
|
|
347
|
-
Set sc = $$$OK
|
|
348
|
-
set xdata = ""
|
|
349
|
-
// Check if the XData Definition exists
|
|
350
|
-
If (##Class(%Dictionary.XDataDefinition).%ExistsId(pProductionName_"||ProductionDefinition"))
|
|
351
|
-
{
|
|
352
|
-
// Open the XData Definition
|
|
353
|
-
Set xdataDefinition = ##Class(%Dictionary.XDataDefinition).%OpenId(pProductionName_"||ProductionDefinition")
|
|
354
|
-
Set xdata = xdataDefinition.Data
|
|
355
|
-
}
|
|
356
|
-
Else
|
|
357
|
-
{
|
|
358
|
-
$$$ThrowOnError($System.Status.Error(5001, "Production does not exist."))
|
|
359
|
-
}
|
|
360
|
-
Return xdata
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
ClassMethod dispatchTestComponent(
|
|
364
|
-
pTargetName As %String,
|
|
365
|
-
pInput As Ens.Request) As Ens.Response
|
|
366
|
-
{
|
|
367
|
-
#dim tService as EnsLib.Testing.Service
|
|
368
|
-
set tOutput = ""
|
|
369
|
-
$$$ThrowOnError(##class(Ens.Director).CreateBusinessService("EnsLib.Testing.Service", .tService))
|
|
370
|
-
$$$ThrowOnError(tService.SendTestRequest(pTargetName, pInput, .tOutput, .sessionID , 1))
|
|
371
|
-
Quit tOutput
|
|
372
|
-
}
|
|
373
|
-
|
|
374
10
|
}
|
|
@@ -1,310 +1,4 @@
|
|
|
1
|
-
Class Grongier.Service.WSGI Extends
|
|
1
|
+
Class Grongier.Service.WSGI Extends IOP.Service.WSGI [ ServerOnly = 1 ]
|
|
2
2
|
{
|
|
3
3
|
|
|
4
|
-
Parameter CLASSPATHS;
|
|
5
|
-
|
|
6
|
-
Parameter MODULENAME;
|
|
7
|
-
|
|
8
|
-
Parameter APPNAME;
|
|
9
|
-
|
|
10
|
-
Parameter DEVMODE = 1;
|
|
11
|
-
|
|
12
|
-
/// This method matches the request and method and calls the dispatcher
|
|
13
|
-
ClassMethod Page(skipheader As %Boolean = 0) As %Status [ ProcedureBlock = 1 ]
|
|
14
|
-
{
|
|
15
|
-
#dim tSC As %Status = $$$OK
|
|
16
|
-
#dim e As %Exception.AbstractException
|
|
17
|
-
|
|
18
|
-
#dim tAuthorized,tRedirected As %Boolean
|
|
19
|
-
#dim tRedirectRoutine,tURL As %String = ""
|
|
20
|
-
#dim %response As %CSP.Response
|
|
21
|
-
|
|
22
|
-
Try {
|
|
23
|
-
|
|
24
|
-
#; Ensure that we honor the requested charset
|
|
25
|
-
Set %response.CharSet=..#CHARSET
|
|
26
|
-
|
|
27
|
-
#; Ensure that we honor the requested CONTENTTYPE
|
|
28
|
-
If ..#CONTENTTYPE'="" Set %response.ContentType=..#CONTENTTYPE
|
|
29
|
-
|
|
30
|
-
#; Ensure that we honor the requested HTTP_ACCEPT_LANGUAGE
|
|
31
|
-
Set %response.Domain = ..#DOMAIN
|
|
32
|
-
Do %response.MatchLanguage()
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
#; Record if device re-direction is already active
|
|
37
|
-
Set tRedirected=##class(%Library.Device).ReDirectIO()
|
|
38
|
-
|
|
39
|
-
#; Record the redirect routine
|
|
40
|
-
Set tRedirectRoutine=$System.Device.GetMnemonicRoutine()
|
|
41
|
-
|
|
42
|
-
#; Now switch to using THIS routine for device redirection
|
|
43
|
-
Use $io::("^%SYS.cspServer2")
|
|
44
|
-
|
|
45
|
-
#; Switch device redirection on (may already be on but thats ok)
|
|
46
|
-
Do ##class(%Library.Device).ReDirectIO(1)
|
|
47
|
-
|
|
48
|
-
#; Ensure that the application is defined (security check)
|
|
49
|
-
If $$$GetSecurityApplicationsDispatchClass(%request.AppData)="" {
|
|
50
|
-
|
|
51
|
-
#; Report not authorized
|
|
52
|
-
Set tSC=..Http403()
|
|
53
|
-
|
|
54
|
-
#; Done
|
|
55
|
-
Quit
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
#; GgiEnvs are not defined in the CSP shell
|
|
59
|
-
Set tURL=$Get(%request.CgiEnvs("CSPLIB"))
|
|
60
|
-
If tURL="" Set tURL=%request.URL
|
|
61
|
-
|
|
62
|
-
#; Do an access check
|
|
63
|
-
Set tSC=..AccessCheck(.tAuthorized)
|
|
64
|
-
If $$$ISERR(tSC) Quit
|
|
65
|
-
|
|
66
|
-
If tAuthorized=0 {
|
|
67
|
-
|
|
68
|
-
#; Don't want the session token
|
|
69
|
-
Set %response.OutputSessionToken=0
|
|
70
|
-
|
|
71
|
-
#; Set the Http Status
|
|
72
|
-
Set %response.Status=..#HTTP403FORBIDDEN
|
|
73
|
-
|
|
74
|
-
#; Done
|
|
75
|
-
Quit
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
#; Extract the match url from the application name
|
|
79
|
-
Set tMatchUrl = "/"_$Extract(tURL,$Length(%request.Application)+1,*)
|
|
80
|
-
|
|
81
|
-
#; Dispatch the request
|
|
82
|
-
Set tSC=..DispatchRequest(tMatchUrl,%request.Method)
|
|
83
|
-
|
|
84
|
-
} Catch (e) {
|
|
85
|
-
Set tSC=e.AsStatus()
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
If $$$ISERR(tSC) {
|
|
89
|
-
|
|
90
|
-
#; Don't want the session token
|
|
91
|
-
Set %response.OutputSessionToken=0
|
|
92
|
-
|
|
93
|
-
Do ..Http500(##class(%Exception.StatusException).CreateFromStatus(tSC))
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
#; Ensure that at least something is written out as the body
|
|
97
|
-
#; This will trigger the device redirect capture and force headers to be written
|
|
98
|
-
#; (if not already done)
|
|
99
|
-
Write ""
|
|
100
|
-
|
|
101
|
-
#; Reset redirect device if necessary
|
|
102
|
-
If tRedirected {
|
|
103
|
-
|
|
104
|
-
#; Use the original redirected routine
|
|
105
|
-
Use $io::("^"_tRedirectRoutine)
|
|
106
|
-
|
|
107
|
-
#; Switch device redirection on
|
|
108
|
-
Do ##class(%Library.Device).ReDirectIO(1)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if ..#DEVMODE {
|
|
112
|
-
#; Close the device to ensure next request starts with a new process
|
|
113
|
-
Close 0
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
Quit $$$OK
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
ClassMethod OnPreDispatch(
|
|
120
|
-
pUrl As %String,
|
|
121
|
-
pMethod As %String,
|
|
122
|
-
ByRef pContinue As %Boolean) As %Status
|
|
123
|
-
{
|
|
124
|
-
Set path = ..#CLASSPATHS
|
|
125
|
-
Set appName = ..#APPNAME
|
|
126
|
-
Set module = ..#MODULENAME
|
|
127
|
-
Set devmode = ..#DEVMODE
|
|
128
|
-
Set pContinue = 1
|
|
129
|
-
Do ..DispatchREST(pUrl, path, appName, module, devmode)
|
|
130
|
-
Quit $$$OK
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
ClassMethod DispatchREST(
|
|
134
|
-
PathInfo As %String,
|
|
135
|
-
appPath As %String,
|
|
136
|
-
appName As %String,
|
|
137
|
-
module As %String,
|
|
138
|
-
devmode As %Boolean = 1) As %Status
|
|
139
|
-
{
|
|
140
|
-
Set builtins = ##CLASS(%SYS.Python).Builtins()
|
|
141
|
-
Set interface = ##CLASS(%SYS.Python).Import("grongier.pex.wsgi.handlers")
|
|
142
|
-
Set rawformdata = ""
|
|
143
|
-
Set environ = builtins.dict()
|
|
144
|
-
Set key = %request.NextCgiEnv("")
|
|
145
|
-
|
|
146
|
-
// Let's check if the WSGI application has been loaded or not for this session.
|
|
147
|
-
|
|
148
|
-
If (($DATA(%session.Data("application")) && $ISOBJECT(%session.Data("application"))) && 'devmode) {
|
|
149
|
-
Set application = %session.Data("Application")
|
|
150
|
-
}
|
|
151
|
-
Else{
|
|
152
|
-
|
|
153
|
-
Set application = ..GetPythonClass(appName, module, appPath)
|
|
154
|
-
If application = "" {
|
|
155
|
-
throw ##class(%Exception.General).%New("Error loading WSGI application: "_module_"."_appName_" from "_appPath)
|
|
156
|
-
}
|
|
157
|
-
Else {
|
|
158
|
-
Set %session.Data("Application") = application
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Editing some CGI variables that may be incorrect in %request
|
|
163
|
-
// Also filling in environ with as many CGI variables as possible from %request
|
|
164
|
-
// WSGI states that all CGI variables are valid and should be included if possible
|
|
165
|
-
While (key'="") {
|
|
166
|
-
Set value = %request.GetCgiEnv(key)
|
|
167
|
-
If key = "PATH_INFO" {
|
|
168
|
-
Set app=$$getapp^%SYS.cspServer(%request.URL,.path,.match,.updatedurl)
|
|
169
|
-
Set value = $EXTRACT(updatedurl,$LENGTH(path),*)
|
|
170
|
-
}
|
|
171
|
-
If key = "SCRIPT_NAME" {
|
|
172
|
-
//%request will sometimes have Script_name include Path_info
|
|
173
|
-
Set value = $PIECE(%request.Application, "/",1,*-1)
|
|
174
|
-
}
|
|
175
|
-
Do environ."__setitem__"(key,value)
|
|
176
|
-
Set key = %request.NextCgiEnv(key)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
//Have to set up a correct wsgi.input stream from %request
|
|
180
|
-
Set stream = %request.Content
|
|
181
|
-
|
|
182
|
-
Set contentType = %request.ContentType
|
|
183
|
-
Set contentLength = 0
|
|
184
|
-
|
|
185
|
-
If contentType = "application/x-www-form-urlencoded" {
|
|
186
|
-
Set formdict = builtins.dict()
|
|
187
|
-
Set key = $ORDER(%request.Data(""))
|
|
188
|
-
While (key'="") {
|
|
189
|
-
Set value = $GET(%request.Data(key,1))
|
|
190
|
-
Do formdict."__setitem__"(key,value)
|
|
191
|
-
Set key = $ORDER(%request.Data(key))
|
|
192
|
-
}
|
|
193
|
-
Do environ."__setitem__"("formdata", formdict)
|
|
194
|
-
}
|
|
195
|
-
ElseIf contentType = "multipart/form-data" {
|
|
196
|
-
Set boundary = $PIECE(%request.GetCgiEnv("CONTENT_TYPE"), "=",2)
|
|
197
|
-
Set stream = ##CLASS(%CSP.BinaryStream).%New()
|
|
198
|
-
|
|
199
|
-
Do stream.Write($CHAR(13,10))
|
|
200
|
-
|
|
201
|
-
//Get the Form Data values
|
|
202
|
-
|
|
203
|
-
Set key = $ORDER(%request.Data(""))
|
|
204
|
-
While (key'="") {
|
|
205
|
-
Do stream.Write("--")
|
|
206
|
-
Do stream.Write(boundary)
|
|
207
|
-
Do stream.Write($CHAR(13,10))
|
|
208
|
-
Set value = $GET(%request.Data(key,1))
|
|
209
|
-
Do stream.Write("Content-Disposition: form-data; name=")
|
|
210
|
-
Do stream.Write(""""_key_"""")
|
|
211
|
-
Do stream.Write($CHAR(13,10,13,10))
|
|
212
|
-
Do stream.Write(value)
|
|
213
|
-
Do stream.Write($CHAR(13,10))
|
|
214
|
-
Set key = $ORDER(%request.Data(key))
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
//Now get the possible MIME data streams
|
|
218
|
-
Set key = %request.NextMimeData("")
|
|
219
|
-
While key'="" {
|
|
220
|
-
Set numMimeStreams = %request.CountMimeData(key)
|
|
221
|
-
Set index = %request.NextMimeDataIndex(key, "")
|
|
222
|
-
Do stream.Write("--")
|
|
223
|
-
Do stream.Write(boundary)
|
|
224
|
-
Do stream.Write($CHAR(13,10))
|
|
225
|
-
If numMimeStreams > 1 {
|
|
226
|
-
//I need to create a boundary for a nested multipart content type
|
|
227
|
-
Set internalboundary = "--"
|
|
228
|
-
For i = 1 : 1 : 7 {
|
|
229
|
-
Set internalboundary = internalboundary _ $RANDOM(10)
|
|
230
|
-
}
|
|
231
|
-
While index '= "" {
|
|
232
|
-
Set mimestream = %request.GetMimeData(key, index)
|
|
233
|
-
Set headers = mimestream.Headers
|
|
234
|
-
Do stream.Write("--")
|
|
235
|
-
Do stream.Write(internalboundary)
|
|
236
|
-
Do stream.Write($CHAR(13,10))
|
|
237
|
-
Do stream.Write(headers)
|
|
238
|
-
Do stream.Write($CHAR(13,10,13,10))
|
|
239
|
-
Set sc = stream.CopyFrom(mimestream)
|
|
240
|
-
//TODO error handling
|
|
241
|
-
Do stream.Write($CHAR(13,10))
|
|
242
|
-
Set index = %request.NextMimeDataIndex(key, index)
|
|
243
|
-
}
|
|
244
|
-
Do stream.Write("--")
|
|
245
|
-
Do stream.Write(internalboundary)
|
|
246
|
-
Do stream.Write("--")
|
|
247
|
-
}
|
|
248
|
-
Else {
|
|
249
|
-
Set mimestream = %request.GetMimeData(key, index)
|
|
250
|
-
Set headers = mimestream.Headers
|
|
251
|
-
Do stream.Write(headers)
|
|
252
|
-
Do stream.Write($CHAR(13,10,13,10))
|
|
253
|
-
Set sc = stream.CopyFrom(mimestream)
|
|
254
|
-
//TODO error handling
|
|
255
|
-
Do stream.Write($CHAR(13,10))
|
|
256
|
-
}
|
|
257
|
-
Set key = %request.NextMimeData(key)
|
|
258
|
-
}
|
|
259
|
-
Do stream.Write("--")
|
|
260
|
-
Do stream.Write(boundary)
|
|
261
|
-
Do stream.Write("--")
|
|
262
|
-
Do stream.Rewind()
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
Try {
|
|
267
|
-
Do interface."make_request"(environ, stream, application, appPath)
|
|
268
|
-
}
|
|
269
|
-
Catch exception {
|
|
270
|
-
throw exception
|
|
271
|
-
}
|
|
272
|
-
Quit $$$OK
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
ClassMethod GetPythonClass(
|
|
276
|
-
pClassname As %String,
|
|
277
|
-
pModule As %String,
|
|
278
|
-
pClasspath As %String) As %SYS.Python
|
|
279
|
-
{
|
|
280
|
-
Try {
|
|
281
|
-
If pClasspath '="" {
|
|
282
|
-
set sys = ##class(%SYS.Python).Import("sys")
|
|
283
|
-
|
|
284
|
-
for i=0:1:(sys.path."__len__"()-1) {
|
|
285
|
-
Try {
|
|
286
|
-
if sys.path."__getitem__"(i) = pClasspath {
|
|
287
|
-
do sys.path."__delitem__"(i)
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
Catch ex {
|
|
291
|
-
// do nothing
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
do sys.path.insert(0, pClasspath)
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
Set importlib = ##class(%SYS.Python).Import("importlib")
|
|
299
|
-
Set builtins = ##class(%SYS.Python).Import("builtins")
|
|
300
|
-
Set module = importlib."import_module"(pModule)
|
|
301
|
-
Set class = builtins.getattr(module, pClassname)
|
|
302
|
-
}
|
|
303
|
-
Catch ex {
|
|
304
|
-
throw ##class(%Exception.General).%New("Error loading WSGI application: "_pModule_"."_pClassname_" from "_pClasspath)
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
Quit class
|
|
308
|
-
}
|
|
309
|
-
|
|
310
4
|
}
|