Skip to content

Commit e4bc078

Browse files
author
loscales
committed
dev v2
1 parent 23f3669 commit e4bc078

8 files changed

Lines changed: 1258 additions & 29 deletions

File tree

src/dc/openapi/common/Generator.cls

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,7 @@ Method IterateOnResponses(callBackMethod As %String) As %Status [ Private ]
8282
Quit sc
8383
}
8484

85-
Method GenerateRequestClass(
86-
path As %String,
87-
pathItem As %DynamicObject,
88-
method As %String,
89-
operation As %DynamicObject) As %Status
85+
Method GenerateRequestClass(path As %String, pathItem As %DynamicObject, method As %String, operation As %DynamicObject) As %Status
9086
{
9187
Set sc = $$$OK
9288

@@ -209,10 +205,7 @@ Method GenerateRequestClass(
209205
Quit sc
210206
}
211207

212-
ClassMethod CheckAndGenerateOperationId(
213-
method As %String,
214-
operation As %DynamicObject,
215-
path As %String) As %Status
208+
ClassMethod CheckAndGenerateOperationId(method As %String, operation As %DynamicObject, path As %String) As %Status
216209
{
217210
If operation.operationId = "" { ; In order to ease the code generation, we generate an operationId
218211

@@ -229,9 +222,7 @@ ClassMethod CheckAndGenerateOperationId(
229222
Quit $$$OK
230223
}
231224

232-
ClassMethod GetOperationParameters(
233-
pathItem As %DynamicObject,
234-
operation As %DynamicObject) As %DynamicArray
225+
ClassMethod GetOperationParameters(pathItem As %DynamicObject, operation As %DynamicObject) As %DynamicArray
235226
{
236227
#dim parameters As %DynamicArray = []
237228

@@ -294,9 +285,7 @@ ClassMethod RequestBodyHelper(contentDefinition As %DynamicObject) As %DynamicOb
294285
Quit bodyDef
295286
}
296287

297-
ClassMethod isBodyProperty(
298-
propertyName As %String,
299-
operation As %DynamicObject) As %Boolean
288+
ClassMethod isBodyProperty(propertyName As %String, operation As %DynamicObject) As %Boolean
300289
{
301290
If '$ISOBJECT(operation.requestBody)||'$IsObject(operation.requestBody.content) Quit $$$NO
302291

@@ -305,9 +294,7 @@ ClassMethod isBodyProperty(
305294
Quit helperObj.%IsDefined(propertyName)
306295
}
307296

308-
ClassMethod GetContentTypeListForProperty(
309-
propertyName,
310-
operation As %DynamicObject) As %String
297+
ClassMethod GetContentTypeListForProperty(propertyName, operation As %DynamicObject) As %String
311298
{
312299
If '$ISOBJECT(operation.requestBody)||'$IsObject(operation.requestBody.content) Quit ""
313300

@@ -324,11 +311,7 @@ ClassMethod GetContentTypeListForProperty(
324311
Quit $Extract(list, 2, *)
325312
}
326313

327-
ClassMethod GetXmlParameters(
328-
spec As %DynamicObject,
329-
schema As %DynamicObject,
330-
Output xmlName,
331-
Output xmlItemName)
314+
ClassMethod GetXmlParameters(spec As %DynamicObject, schema As %DynamicObject, Output xmlName, Output xmlItemName)
332315
{
333316
Set (xmlName, xmlItemName) = ""
334317

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
Class dc.openapi.common.PreProcessing Extends %RegisteredObject
2+
{
3+
4+
Property OAS As %DynamicObject;
5+
6+
Property ExternalRefs As dc.openapi.common.SwaggerExternalRefs;
7+
8+
Property errors As %DynamicObject;
9+
10+
ClassMethod Test() As %Status
11+
{
12+
Set tSc = $$$OK
13+
14+
Set oas = {}.%FromJSONFile("/home/irisowner/irisdev/temp-dev-specs/v1.json")
15+
Set ssi = {}.%FromJSONFile("/home/irisowner/irisdev/temp-dev-specs/ssi_types.json")
16+
Set err = {}.%FromJSONFile("/home/irisowner/irisdev/temp-dev-specs/error_response.json")
17+
18+
Set pp = ##class(dc.openapi.common.PreProcessing).%New()
19+
Set pp.OAS = oas
20+
Set pp.ExternalRefs = ##class(dc.openapi.common.SwaggerExternalRefs).%New()
21+
Do pp.ExternalRefs.AddItem(ssi, "../common/ssi_types.yaml")
22+
;Do pp.ExternalRefs.AddItem(err, "../common/error_response.yaml")
23+
24+
;w pp.ExternalRefs.GetDocument("../common/ssi_types.yaml", .found)
25+
26+
Set tSc = pp.PreProcess()
27+
Quit tSc
28+
}
29+
30+
Method PreProcess() As %Status
31+
{
32+
Set tSc = $$$OK
33+
34+
Set tSc = ..Validate()
35+
36+
Return tSc
37+
}
38+
39+
Method Validate() As %Status
40+
{
41+
Set tSc = $$$OK
42+
Set document = ..OAS ; specification to process ...
43+
44+
Set getInternal = $$$YES, getExternal = $$$YES
45+
Set references = ##class(dc.openapi.common.RefScanner).GetListOfRefs(document, getInternal, getExternal)
46+
47+
Set ptr = 0
48+
While $ListNext(references, ptr, ref) {
49+
Set isDefined = ..ReferenceIsDefined(document, ref)
50+
If 'isDefined {
51+
Write !,"Reference not defined: ", ref
52+
}
53+
}
54+
55+
; Check if the external references are defined
56+
Set key = ""
57+
For {
58+
Set item = ..ExternalRefs.Items.GetNext(.key)
59+
Quit:key=""
60+
w !,"item : ", key
61+
Set document = item.Document
62+
Set references = ##class(dc.openapi.common.RefScanner).GetListOfRefs(document, getInternal, getExternal)
63+
Set ptr = 0
64+
While $ListNext(references, ptr, ref) {
65+
Set isDefined = ..ReferenceIsDefined(document, ref)
66+
If 'isDefined {
67+
Write !,"External reference not defined: ", ref, !
68+
}
69+
}
70+
}
71+
72+
Quit $$$OK
73+
}
74+
75+
Method ReferenceIsDefined(document As %DynamicObject, ref As %String) As %Boolean
76+
{
77+
If $Extract(ref) = "#" {
78+
; It's an internal reference
79+
Return ##class(dc.openapi.common.RefScanner).ReferenceIsDefined(document, ref)
80+
}
81+
82+
; It's an external reference
83+
; Check if the external reference is already in the list
84+
Set key = $Piece(ref, "#", 1)
85+
Set document = ..ExternalRefs.GetDocument(key, .found)
86+
If 'found Return $$$NO
87+
88+
Return ##class(dc.openapi.common.RefScanner).ReferenceIsDefined(document, ref)
89+
}
90+
91+
}

src/dc/openapi/common/ExternalRefScanner.cls renamed to src/dc/openapi/common/RefScanner.cls

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Class dc.openapi.common.ExternalRefScanner Extends %RegisteredObject
1+
Class dc.openapi.common.RefScanner Extends %RegisteredObject
22
{
33

44
Parameter SEPARATOR = ".";
@@ -15,20 +15,25 @@ ClassMethod Test()
1515
ClassMethod GetListOfRefs(oas As %DynamicObject, internal As %Boolean = {$$$YES}, external As %Boolean = {$$$NO}) As %List
1616
{
1717
Set list = "", k = ""
18-
Set status = ..CollectOASReferences(oas, .out)
18+
Do ..CollectOASReferences(oas, .out)
1919

2020
For {
2121
Set k = $Order(out(k), 1, line)
2222
Quit:k=""
2323

2424
If $Extract(line, *-3, *) '= "$ref" Continue
25-
25+
2626
Set reference = ..GetValue(oas, line)
27+
2728
If internal {
28-
Set:$Extract(reference)="#" $List(list, *+1) = reference
29+
If $Extract(reference)="#" && '$Data(unique(" "_reference)) {
30+
Set $List(list, *+1) = reference, unique(" "_reference) = ""
31+
}
2932
}
3033
If external {
31-
Set:$Extract(reference)'="#" $List(list, *+1) = reference
34+
If $Extract(reference)'="#" && '$Data(unique(" "_reference)) {
35+
Set $List(list, *+1) =reference, unique(" "_reference) = ""
36+
}
3237
}
3338
}
3439

@@ -47,6 +52,34 @@ ClassMethod GetValue(oas As %DynamicObject, ref As %String) As %String
4752
Return value
4853
}
4954

55+
ClassMethod ReferenceIsDefined(oas As %DynamicObject, ref As %String) As %Boolean
56+
{
57+
If '$IsObject(oas) {
58+
Return $$$NO
59+
}
60+
61+
Set subPart = $Piece(ref, "#/", 2)
62+
If subPart = "" {
63+
; The reference is the received object itself
64+
Return $$$YES
65+
}
66+
67+
Set isDefined = $$$YES
68+
69+
Set list = $ListFromString(subPart, "/"), ptr = 0, value = oas
70+
While $ListNext(list, ptr, key) {
71+
If value.%IsDefined(key) {
72+
Set value = value.%Get(key)
73+
}
74+
Else {
75+
Set isDefined = $$$NO
76+
Quit
77+
}
78+
}
79+
80+
Return isDefined
81+
}
82+
5083
ClassMethod CollectOASReferences(oas As %DynamicObject, ByRef out As %Binary, prefix As %String = "") As %Status
5184
{
5285
#dim iterator As %Iterator.AbstractIterator
@@ -58,7 +91,6 @@ ClassMethod CollectOASReferences(oas As %DynamicObject, ByRef out As %Binary, pr
5891
Set key = $Increment(out)
5992
Set out(key) = ref
6093

61-
Write !, ref
6294
If $IsObject(item) {
6395
Do ..CollectOASReferences(item, .out, ref_..#SEPARATOR)
6496
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Class dc.openapi.common.SwaggerExternalRef Extends %RegisteredObject
2+
{
3+
4+
Property Key As %String;
5+
6+
Property IsAFullSpecification As %Boolean [ InitialExpression = {$$$NO} ];
7+
8+
Property Document As %DynamicObject;
9+
10+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
Class dc.openapi.common.SwaggerExternalRefs Extends %RegisteredObject
2+
{
3+
4+
Property Items As array Of dc.openapi.common.SwaggerExternalRef;
5+
6+
Method AddItem(document As %DynamicObject, key As %String, isAFullSpecification As %Boolean = "") As %Status
7+
{
8+
Set item = ##class(dc.openapi.common.SwaggerExternalRef).%New()
9+
Set item.Document = document
10+
Set item.Key = key
11+
12+
If isAFullSpecification = "" { ; try to guess if the document is a full specification
13+
If document.%IsDefined("openapi") {
14+
Set item.IsAFullSpecification = $$$YES
15+
} Else {
16+
Set item.IsAFullSpecification = $$$NO
17+
}
18+
} Else {
19+
Set item.IsAFullSpecification = isAFullSpecification
20+
}
21+
22+
Return ..Items.SetAt(item, key)
23+
}
24+
25+
Method GetItem(key As %String) As dc.openapi.common.SwaggerExternalRef
26+
{
27+
Return ..Items.GetAt(key)
28+
}
29+
30+
Method GetDocument(key As %String, Output found As %Boolean) As %DynamicObject
31+
{
32+
Set found = $$$NO, item = ..Items.GetAt(key)
33+
If '$IsObject(item) Return ""
34+
Set found = $$$YES
35+
Return item.Document
36+
}
37+
38+
}

temp-dev-specs/error_response.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"description": "Default return values follow Problem Details for HTTP APIs as specified in [RFC7807](https://tools.ietf.org/html/rfc7807).\n\nCurrently, return values contain the following members of a problem details object:\n- \"title\" (string) - A short, human-readable summary of the problem type.\n- \"status\" (number) - The HTTP status code generated by the origin server for this occurrence of the problem.\n- \"detail\" (string) - A human-readable explanation specific to this occurrence of the problem.\n",
3+
"content": {
4+
"application/problem+json": {
5+
"schema": {
6+
"type": "object",
7+
"required": [
8+
"title",
9+
"status",
10+
"detail"
11+
],
12+
"properties": {
13+
"title": {
14+
"type": "string",
15+
"description": "A short, human-readable summary of the problem type."
16+
},
17+
"status": {
18+
"type": "number",
19+
"description": "HTTP statuscode"
20+
},
21+
"detail": {
22+
"type": "string",
23+
"description": "A human-readable explanation specific to this occurrence of the problem."
24+
}
25+
}
26+
}
27+
}
28+
}
29+
}

0 commit comments

Comments
 (0)