-
Notifications
You must be signed in to change notification settings - Fork 148
/
Copy pathbgrfc_server.py
191 lines (147 loc) · 5.51 KB
/
bgrfc_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# SPDX-FileCopyrightText: 2013 SAP SE Srdjan Boskovic <srdjan.boskovic@sap.com>
#
# SPDX-License-Identifier: Apache-2.0
import sys
from backends import BACKEND
from pyrfc import RCStatus, Server, UnitCallType, UnitState
from tlog import TLog
backend_dest = sys.argv[1]
tlog = TLog()
# clear the log
tlog.remove()
def stfc_write_to_tcpic(request_context, RESTART_QNAME="", TCPICDAT=[]):
try:
context = request_context["server_context"]
tid = context["unit_identifier"]["id"] if "unit_identifier" in context else None
print(
"server function: stfc_write_to_tcpic",
"tid:",
tid,
"call:",
UnitCallType.synchronous.value,
context,
)
# if context["call_type"] != UnitCallType.synchronous:
# # Obtain the database connection that was opened for the
# # current TID context.tid in the onCheckTID handler.
# Implement functionality of function module MY_FUNCTION_MODULE, if any.
# print(f"RESTART_QNAME: {RESTART_QNAME}")
print("TCPICDAT:", TCPICDAT)
# try:
# unit = client.initialize_unit()
# print("unit:", unit)
# client.fill_and_submit_unit(
# unit,
# [("STFC_WRITE_TO_TCPIC", {"TCPICDAT": TCPICDAT})],
# queue_names=["RFCSDK_QUEUE_IN"],
# attributes={"lock": 1},
# )
# except Exception as ex:
# print(ex)
if context["call_type"] != UnitCallType.synchronous: # SIM102
# Store the data received in funcHandle as well as any results
# computed in the business functionality of the FM (if any)
# via the DB connection obtained above.
# Optionally, if you want to make status tracking and forensic analysis
# in case of an error easier, you can update the TID`s status to EXECUTED
# in this step.
if tid is not None:
tlog.write(tid, UnitState.executed, "stfc_write_to_tcpic")
return RCStatus.OK
except Exception as ex:
print("Error in stfc_write_to_tcpic", ex)
return RCStatus.RFC_EXTERNAL_FAILURE
def on_auth_check(func_name=False, request_context=None):
if request_context is None:
request_context = {}
print(f"authorization check for '{func_name}'")
# print("request_context", request_context)
return RCStatus.OK
def onCheckFunction(
rfcHandle,
unit_identifier,
):
# section 5.5.1 pg 76 of SAP NWRFC SDK Programming Guide 7.50
if tlog is None:
# TLog not available
return RCStatus.RFC_EXTERNAL_FAILURE
tid = unit_identifier["id"]
tlog_record = tlog[tid]
if tlog_record is None:
# Create TID record
tlog_record = tlog.write(tid, UnitState.created)
print(
"bgRFC:onCheck",
f"handle {rfcHandle} tid {tid} status {tlog_record['status']}",
)
if tlog_record["status"] in [UnitState.created.name, UnitState.rolled_back.name]:
return RCStatus.OK
else:
return RCStatus.RFC_EXECUTED
def onCommitFunction(rfcHandle, unit_identifier):
# section 5.5.3 pg 79 of SAP NWRFC SDK Programming Guide 7.50
print("bgRFC:onCommit handle", rfcHandle, "unit", unit_identifier)
if tlog is None:
# TLog not available
return RCStatus.RFC_EXTERNAL_FAILURE
tid = unit_identifier["id"]
tlog.write(tid, UnitState.committed)
return RCStatus.OK
def onConfirmFunction(rfcHandle, unit_identifier):
# section 5.5.4 pg 80 of SAP NWRFC SDK Programming Guide 7.50
print("bgRFC:onConfirm handle", rfcHandle, "unit", unit_identifier)
if tlog is None:
# TLog not available
return RCStatus.RFC_EXTERNAL_FAILURE
tid = unit_identifier["id"]
tlog.write(tid, UnitState.confirmed)
# or remove tid records from db
# tlog.remove(tid)
return RCStatus.OK
def onRollbackFunction(rfcHandle, unit_identifier):
# section 5.5.3 pg 80 of SAP NWRFC SDK Programming Guide 7.50
print("bgRFC:onRollback handle", rfcHandle, "unit", unit_identifier)
if tlog is None:
# TLog not available
return RCStatus.RFC_EXTERNAL_FAILURE
tid = unit_identifier["id"]
tlog.write(tid, UnitState.rolled_back)
return RCStatus.RFC_OK
def onGetStateFunction(rfcHandle, unit_identifier):
# section 5.6.3 pg 84 of SAP NWRFC SDK Programming Guide 7.50
print("bgRFC:onGetState handle", rfcHandle, "unit", unit_identifier)
if tlog is None:
# TLog not available
return RCStatus.RFC_EXTERNAL_FAILURE
tid = unit_identifier["id"]
tlog_record = tlog[tid]
if tlog_record is None:
return RCStatus.RFC_NOT_FOUND
return RCStatus(tlog_record["status"])
# create server
server = Server(*BACKEND[backend_dest])
print(server.get_server_attributes())
try:
# expose python function stfc_write_to_tcpic as ABAP function STFC_WRITE_TO_TCPIC,
# to be called by ABAP system
server.add_function("STFC_WRITE_TO_TCPIC", stfc_write_to_tcpic)
# register bgRFC handlers
server.bgrfc_init(
backend_dest,
{
"check": onCheckFunction,
"commit": onCommitFunction,
"rollback": onRollbackFunction,
"confirm": onConfirmFunction,
"getState": onGetStateFunction,
},
)
# start server
server.start()
input("Press Enter key to stop server...\n")
# stop server and database
server.stop()
finally:
# clean-up the server
server.close()
tlog.dump()