Skip to content

Commit 7b378b4

Browse files
author
Dennis Labordus
committed
Support websockets to Validator Service.
Signed-off-by: Dennis Labordus <[email protected]>
1 parent 9c4c240 commit 7b378b4

File tree

4 files changed

+97
-28
lines changed

4 files changed

+97
-28
lines changed

src/Logging.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export function Logging<TBase extends LitElementConstructor>(Base: TBase) {
168168
private onIssue(de: IssueEvent): void {
169169
const issues = this.diagnoses.get(de.detail.validatorId);
170170

171-
if (!issues) this.diagnoses.set(de.detail.validatorId, [de.detail]);
171+
if (!issues || de.detail.resetList === true) this.diagnoses.set(de.detail.validatorId, [de.detail]);
172172
else issues?.push(de.detail);
173173

174174
this.latestIssue = de.detail;

src/compas-services/CompasValidatorService.ts

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
import {CompasSettings} from "../compas/CompasSettings.js";
2-
import {handleError, handleResponse, parseXml} from "./foundation.js";
1+
import { CompasSettings } from "../compas/CompasSettings.js";
2+
import {
3+
createLogEvent,
4+
handleError,
5+
handleResponse,
6+
parseXml
7+
} from "./foundation.js";
38

49
export const SVS_NAMESPACE = 'https://www.lfenergy.org/compas/SclValidatorService/v1';
510

@@ -8,23 +13,77 @@ export function CompasSclValidatorService() {
813
return CompasSettings().compasSettings;
914
}
1015

16+
function getWebsocketPort(): string {
17+
if (document.location.port === "") {
18+
return (document.location.protocol == "http:" ? "80" : "443")
19+
}
20+
return document.location.port;
21+
}
22+
23+
function getWebsocketUri(): string {
24+
const sclValidatorServiceUrl = getCompasSettings().sclValidatorServiceUrl;
25+
if (sclValidatorServiceUrl.startsWith("ws://") || sclValidatorServiceUrl.startsWith("wss://")) {
26+
return sclValidatorServiceUrl + (sclValidatorServiceUrl.endsWith("/") ? "" : "/");
27+
}
28+
29+
return (document.location.protocol == "http:" ? "ws://" : "wss://")
30+
+ document.location.hostname + ":" + getWebsocketPort()
31+
+ sclValidatorServiceUrl + (sclValidatorServiceUrl.endsWith("/") ? "" : "/");
32+
}
33+
34+
function createRequest(doc: Document): string {
35+
return `<?xml version="1.0" encoding="UTF-8"?>
36+
<svs:SclValidateRequest xmlns:svs="${SVS_NAMESPACE}">
37+
<svs:SclData><![CDATA[${new XMLSerializer().serializeToString(doc.documentElement)}]]></svs:SclData>
38+
</svs:SclValidateRequest>`;
39+
}
40+
1141
return {
12-
validateSCL(type: string, doc: Document): Promise<Document> {
42+
useWebsocket(): boolean {
43+
const sclValidatorServiceUrl = getCompasSettings().sclValidatorServiceUrl;
44+
return !sclValidatorServiceUrl.startsWith("http");
45+
},
46+
47+
validateSCLUsingRest(type: string, doc: Document): Promise<Document> {
1348
const svsUrl = getCompasSettings().sclValidatorServiceUrl + '/validate/v1/' + type;
1449
return fetch(svsUrl, {
1550
method: 'POST',
1651
headers: {
1752
'Content-Type': 'application/xml'
1853
},
19-
body: `<?xml version="1.0" encoding="UTF-8"?>
20-
<svs:SclValidateRequest xmlns:svs="${SVS_NAMESPACE}">
21-
<svs:SclData><![CDATA[${new XMLSerializer().serializeToString(doc.documentElement)}]]></svs:SclData>
22-
</svs:SclValidateRequest>`
54+
body: createRequest(doc)
2355
}).catch(handleError)
2456
.then(handleResponse)
2557
.then(parseXml);
2658
},
2759

60+
validateSCLUsingWebsockets(type: string, doc: Document, callback: (doc: Document) => void) {
61+
const websocket = new WebSocket(getWebsocketUri() + 'validate-ws/v1/' + type);
62+
63+
websocket.onopen = () => {
64+
websocket.send(createRequest(doc));
65+
};
66+
67+
websocket.onmessage = (evt) => {
68+
parseXml(evt.data)
69+
.then(doc => {
70+
callback(doc);
71+
websocket.close();
72+
})
73+
.catch(reason => {
74+
createLogEvent(reason);
75+
websocket.close();
76+
});
77+
};
78+
79+
websocket.onerror = () => {
80+
createLogEvent(
81+
{ message: 'Websocket Error',
82+
type: 'Error'})
83+
websocket.close();
84+
};
85+
},
86+
2887
listNsdocFiles(): Promise<Document> {
2988
const svsUrl = getCompasSettings().sclValidatorServiceUrl + '/nsdoc/v1';
3089
return fetch(svsUrl).catch(handleError)

src/foundation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ export function newLogEvent(
411411

412412
export interface IssueDetail extends LogDetailBase {
413413
validatorId: string;
414+
resetList?: boolean;
414415
}
415416
export type IssueEvent = CustomEvent<IssueDetail>;
416417
export function newIssueEvent(
Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import {LitElement, property} from "lit-element";
1+
import { LitElement, property } from "lit-element";
22

3-
import {newIssueEvent} from "../foundation.js";
3+
import { newIssueEvent } from "../foundation.js";
44

5-
import {CompasSclValidatorService, SVS_NAMESPACE} from "../compas-services/CompasValidatorService.js";
6-
import {createLogEvent} from "../compas-services/foundation.js";
7-
import {dispatchEventOnOpenScd, getTypeFromDocName} from "../compas/foundation.js";
5+
import { CompasSclValidatorService, SVS_NAMESPACE } from "../compas-services/CompasValidatorService.js";
6+
import { createLogEvent } from "../compas-services/foundation.js";
7+
import { dispatchEventOnOpenScd, getTypeFromDocName } from "../compas/foundation.js";
88

99
export default class ValidateTemplates extends LitElement {
1010
@property({ attribute: false })
@@ -23,22 +23,31 @@ export default class ValidateTemplates extends LitElement {
2323
}
2424

2525
const docType = getTypeFromDocName(this.docName);
26-
await CompasSclValidatorService().validateSCL(docType, this.doc)
27-
.then(document => {
28-
const validationErrors = Array.from(document.querySelectorAll('SclValidateResponse > ValidationErrors') ?? []);
29-
// Check if there are validation errors, if there are we will process them.
30-
if (validationErrors.length > 0) {
31-
validationErrors.forEach(validationError => {
32-
const message = validationError.getElementsByTagNameNS(SVS_NAMESPACE, "Message")!.item(0)!.textContent;
33-
dispatchEventOnOpenScd(
34-
newIssueEvent({
35-
validatorId: this.pluginId,
36-
title: message ?? 'No message'
37-
})
38-
);
26+
const service = CompasSclValidatorService();
27+
if (service.useWebsocket()) {
28+
service.validateSCLUsingWebsockets(docType, this.doc, (doc) => {
29+
this.processValidationResponse(doc);
30+
});
31+
} else {
32+
service.validateSCLUsingRest(docType, this.doc)
33+
.then(response => this.processValidationResponse(response))
34+
.catch(createLogEvent);
35+
}
36+
}
37+
38+
private processValidationResponse(response: Document): void {
39+
const validationErrors = Array.from(response.querySelectorAll('SclValidateResponse > ValidationErrors') ?? []);
40+
// Check if there are validation errors, if there are we will process them.
41+
if (validationErrors.length > 0) {
42+
validationErrors.forEach(validationError => {
43+
const message = validationError.getElementsByTagNameNS(SVS_NAMESPACE, "Message")!.item(0)!.textContent;
44+
dispatchEventOnOpenScd(
45+
newIssueEvent({
46+
validatorId: this.pluginId,
47+
title: message ?? 'No message'
3948
})
40-
}
49+
);
4150
})
42-
.catch(createLogEvent);
51+
}
4352
}
4453
}

0 commit comments

Comments
 (0)