Skip to content

Commit 5fbc121

Browse files
committed
fix(addon): cancelClient interface and unit tests fixed
1 parent 9fcddde commit 5fbc121

File tree

9 files changed

+86
-77
lines changed

9 files changed

+86
-77
lines changed

doc/api.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ loadCryptoLibrary(cryptoLibraryPath: string)
5050
Usage: [usage/addon](usage.md#cancelclient)
5151

5252
```ts
53-
cancelClient(client: Client, callback?: Function): void | Promise<any>;
53+
cancelClient(client: Client, callback?: Function): void | Promise<void>;
5454
```
5555

5656
### languageIsoToSap

src/cpp/Client.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,7 @@ Napi::Value Client::Release(const Napi::CallbackInfo& info) {
626626

627627
return info.Env().Undefined();
628628
}
629+
629630
void cancelConnection(RFC_RC* rc,
630631
RFC_CONNECTION_HANDLE connectionHandle,
631632
RFC_ERROR_INFO* errorInfo) {

src/cpp/Server.cc

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -621,13 +621,40 @@ RFC_RC SAP_API genericRequestHandler(RFC_CONNECTION_HANDLE conn_handle,
621621

622622
if (requestBaton->jsHandlerError.length() > 0) {
623623
// return the error message to ABAP
624+
// ref Table 5-A at pg. 48 of SAP NW RFC SDK Programming Guide
624625
strncpyU(errorInfo->message, setString(requestBaton->jsHandlerError), 512);
625626
return RFC_EXTERNAL_FAILURE;
626627
}
627628

628629
return RFC_OK;
629630
}
630631

632+
// to-do
633+
// RFC_RC SAP_API authorizationHandler(RFC_CONNECTION_HANDLE rfcHandle,
634+
// RFC_SECURITY_ATTRIBUTES* secAttributes,
635+
// RFC_ERROR_INFO* errorInfo) {
636+
// // Here you can check any combination of function name, system ID, //
637+
// client,
638+
// // calling ABAP report and username, as well as the backend’s SNC
639+
// credentials. if (!strcmpU(secAttributes->user, cU("ADMIN"))) {
640+
// // User ADMIN is allowed to call function modules FUNCTION_1,
641+
// // ... FUNCTION_3.
642+
// if (!strcmpU(secAttributes->functionName, cU("FUNCTION_1")) ||
643+
// !strcmpU(secAttributes->functionName, cU("FUNCTION_2")) ||
644+
// !strcmpU(secAttributes->functionName, cU("FUNCTION_3")))
645+
// return RFC_OK;
646+
// else if (!strcmpU(secAttributes->user, cU("BUSINESS_USER"))) {
647+
// // User BUSINESS_USER is allowed to call function modules // BAPI_A,
648+
// and
649+
// // BAPI_B.
650+
// if (!strcmpU(secAttributes->functionName, cU("BAPI_A")) ||
651+
// !strcmpU(secAttributes->functionName, cU("BAPI_A")))
652+
// return RFC_OK;
653+
// // All other cases are denied.
654+
// return RFC_AUTHORIZATION_FAILURE;
655+
// }
656+
// }
657+
631658
class StartAsync : public Napi::AsyncWorker {
632659
public:
633660
StartAsync(Napi::Function& callback, Server* server)
@@ -840,9 +867,9 @@ Napi::Value Server::AddFunction(const Napi::CallbackInfo& info) {
840867

841868
if (abapFunctionName.Utf8Value().length() == 0 ||
842869
abapFunctionName.Utf8Value().length() > 30) {
843-
Napi::TypeError::New(
844-
info.Env(),
845-
"Server addFunction() accepts max. 30 characters long ABAP RFM name")
870+
Napi::TypeError::New(info.Env(),
871+
"Server addFunction() accepts max. 30 characters "
872+
"long ABAP RFM name")
846873
.ThrowAsJavaScriptException();
847874
return info.Env().Undefined();
848875
}

src/cpp/addon.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,6 @@ Napi::Value SetLogFilePath(const Napi::CallbackInfo& info) {
116116
_log.set_log_file_path(info[0].As<Napi::String>().Utf8Value());
117117
return info.Env().Undefined();
118118
}
119-
120119
Napi::Object RegisterModule(Napi::Env env, Napi::Object exports) {
121120
if (node_rfc::__env == nullptr) {
122121
node_rfc::__env = env;

src/ts/index.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,13 @@ function terminate(workerData: unknown) {
6969
export function cancelClient(
7070
client: Client,
7171
callback?: Function
72-
): void | Promise<unknown> {
72+
): void | Promise<void> {
7373
if (callback !== undefined && typeof callback !== "function") {
7474
throw new TypeError(
7575
`cancelClient 2nd argument, if provided, must be a Function. Received: ${typeof callback}`
7676
);
7777
}
78-
const old_handle = client.connectionHandle;
79-
const workerData = { connectionHandle: old_handle };
80-
if (typeof callback === "function") {
81-
return terminate(workerData)
82-
.then((res) => {
83-
sapnwrfcEvents.emit("sapnwrfc:clientCancel", {
84-
id: client.id,
85-
connectionHandle: old_handle,
86-
});
87-
callback(undefined, res);
88-
})
89-
.catch((err) => {
90-
callback(err);
91-
});
92-
} else {
93-
return terminate(workerData);
94-
}
78+
return client.cancel(callback);
9579
}
9680

9781
export function languageIsoToSap(langIso: string): string {

src/ts/sapnwrfc-client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ export class Client {
432432

433433
cancel(callback?: Function): void | Promise<void> {
434434
Client.checkCallbackArg("cancel", callback);
435+
435436
if (typeof callback === "function") {
436437
try {
437438
this.__client.cancel(callback);

test/cancel/addon.cancelClient.promise.spec.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { direct_client, cancelClient } from "../utils/setup";
66

7-
describe.skip("Connection terminate by addon", () => {
7+
describe("Connection terminate by addon", () => {
88
const DURATION = 3;
99
const CANCEL = 1;
1010
const RfcCanceledError = {
@@ -16,27 +16,28 @@ describe.skip("Connection terminate by addon", () => {
1616
message: "Connection was canceled.",
1717
};
1818

19-
test("Non-managed, addon.cancelClient() promise", async () => {
20-
const client = direct_client();
21-
expect.assertions(2);
22-
await client.open();
23-
// call function
24-
const handle = client.connectionHandle;
25-
try {
26-
await client.call("RFC_PING_AND_WAIT", { SECONDS: DURATION });
27-
} catch (err) {
28-
expect(err).toMatchObject(RfcCanceledError);
29-
}
19+
test(
20+
"Non-managed, addon.cancelClient() promise",
21+
async () => {
22+
try {
23+
expect.assertions(1);
24+
const client = direct_client();
3025

31-
// cancel
32-
setTimeout(() => {
33-
async () => {
34-
const res = await (cancelClient(client) as Promise<unknown>);
35-
expect(res).toMatchObject({
36-
connectionHandle: handle,
37-
result: "cancelled",
26+
await client.open();
27+
28+
// cancel after 1 sec
29+
setTimeout(() => {
30+
<void>cancelClient(client);
31+
}, CANCEL * 1000);
32+
33+
// 3 seconds long call
34+
await client.call("RFC_PING_AND_WAIT", {
35+
SECONDS: DURATION,
3836
});
39-
};
40-
}, CANCEL * 1000);
41-
});
37+
} catch (err: unknown) {
38+
return expect(err).toMatchObject(RfcCanceledError);
39+
}
40+
},
41+
DURATION * 1000
42+
);
4243
});

test/cancel/addon.cancelClient.spec.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { direct_client, cancelClient } from "../utils/setup";
66

7-
describe.skip("Connection terminate by addon", () => {
7+
describe("Connection terminate by addon", () => {
88
const DURATION = 3;
99
const CANCEL = 1;
1010
const RfcCanceledError = {
@@ -16,33 +16,29 @@ describe.skip("Connection terminate by addon", () => {
1616
message: "Connection was canceled.",
1717
};
1818

19-
test("Non-managed, addon.cancelClient() callback", function (done) {
20-
const client = direct_client();
21-
expect.assertions(3);
22-
void client.open(() => {
23-
// call function
24-
const handle = client.connectionHandle;
25-
client.invoke(
26-
"RFC_PING_AND_WAIT",
27-
{
28-
SECONDS: DURATION,
29-
},
30-
function (err) {
31-
expect(err).toMatchObject(RfcCanceledError);
32-
done();
33-
}
34-
);
35-
// cancel
36-
37-
setTimeout(() => {
38-
void cancelClient(client, (err, res) => {
39-
expect(err).toBeUndefined();
40-
expect(res).toMatchObject({
41-
connectionHandle: handle,
42-
result: "cancelled",
43-
});
44-
});
45-
}, CANCEL * 1000);
46-
});
47-
});
19+
test(
20+
"Non-managed, addon.cancelClient() callback",
21+
function (done) {
22+
const client = direct_client();
23+
expect.assertions(1);
24+
void client.open(() => {
25+
// 3 seconds long call
26+
client.invoke(
27+
"RFC_PING_AND_WAIT",
28+
{
29+
SECONDS: DURATION,
30+
},
31+
function (err: unknown) {
32+
expect(err).toMatchObject(RfcCanceledError);
33+
done();
34+
}
35+
);
36+
// cancel after 1 sec
37+
setTimeout(() => {
38+
<void>cancelClient(client);
39+
}, CANCEL * 1000);
40+
});
41+
},
42+
DURATION * 1000
43+
);
4844
});

test/cancel/timeout.client.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ describe("Connection terminate timeout", () => {
1616
message: "Connection was canceled.",
1717
};
1818

19-
test.only("Client options timeout", function (done) {
19+
test("Client options timeout", function (done) {
2020
const client = new Client({ dest: "MME" }, { timeout: TIMEOUT });
2121
expect.assertions(3);
2222
void client.open(() => {
@@ -37,5 +37,5 @@ describe("Connection terminate timeout", () => {
3737
}
3838
);
3939
});
40-
});
40+
}, 10000);
4141
});

0 commit comments

Comments
 (0)