aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaMont, William (wl2432) <wl2432@att.com>2019-08-06 11:15:21 -0400
committerLaMont, William (wl2432) <wl2432@att.com>2019-08-06 11:17:17 -0400
commit8d4ca0d78d2b34a07473d8a9293173c798d0a1f8 (patch)
tree19e23fc63cf8a4d98c30acb6e1c6141eaa785715
parent127b1c09eb66ff7f9273e1e79d283e94bd731b14 (diff)
update to swagger generation for WAPIml loading
Issue-ID: AAI-2562 Change-Id: I50db09d5b450ad805e365c1365d0c5b3c4cef5be Signed-off-by: LaMont, William (wl2432) <wl2432@att.com>
-rw-r--r--aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/GetOperation.java2
-rw-r--r--aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/PatchOperation.java23
-rw-r--r--aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/XSDElement.java18
-rw-r--r--aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/YAMLfromOXM.java99
-rw-r--r--aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/GetOperationTest.java4
-rw-r--r--aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/NodesYAMLfromOXMTest.java173
-rw-r--r--aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/PatchOperationTest.java2
-rw-r--r--aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/YAMLfromOXMTest.java157
8 files changed, 105 insertions, 373 deletions
diff --git a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/GetOperation.java b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/GetOperation.java
index f2f0d63..b942e1b 100644
--- a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/GetOperation.java
+++ b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/GetOperation.java
@@ -101,7 +101,7 @@ public class GetOperation {
pathSb.append(" \"200\":\n");
pathSb.append(" description: successful operation\n");
pathSb.append(" schema:\n");
- pathSb.append(" $ref: \"#/getDefinitions/" + xmlRootElementName + "\"\n");
+ pathSb.append(" $ref: \"#/definitions/" + xmlRootElementName + "\"\n");
pathSb.append(" \"default\":\n");
pathSb.append(" " + GenerateXsd.getResponsesUrl());
if ( StringUtils.isNotEmpty(pathParams) || StringUtils.isNotEmpty(queryParams)) {
diff --git a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/PatchOperation.java b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/PatchOperation.java
index 27882b7..5ab3678 100644
--- a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/PatchOperation.java
+++ b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/PatchOperation.java
@@ -30,16 +30,21 @@ public class PatchOperation {
private String tag;
private String path;
private String pathParams;
+ private String prefixForPatch;
- public PatchOperation(String useOpId, String xmlRootElementName, String tag, String path, String pathParams) {
- super();
- this.useOpId = useOpId;
- this.xmlRootElementName = xmlRootElementName;
- this.tag = tag;
- this.path = path;
- this.pathParams = pathParams;
+ public PatchOperation(String useOpId, String xmlRootElementName, String tag, String path, String pathParams) {
+ super();
+ this.useOpId = useOpId;
+ this.xmlRootElementName = xmlRootElementName;
+ this.tag = tag;
+ this.path = path;
+ this.pathParams = pathParams;
+ this.prefixForPatch = "";
+ }
+ public void setPrefixForPatchRef(String prefixForPatchRef) {
+ this.prefixForPatch = prefixForPatchRef;
}
-
+
public String toString() {
StringTokenizer st;
st = new StringTokenizer(path, "/");
@@ -107,7 +112,7 @@ public class PatchOperation {
pathSb.append(" description: " + xmlRootElementName + " object that needs to be updated."+relationshipExamplesSb.toString()+"\n");
pathSb.append(" required: true\n");
pathSb.append(" schema:\n");
- pathSb.append(" $ref: \"#/patchDefinitions/" + xmlRootElementName + "\"\n");
+ pathSb.append(" $ref: \"#/definitions/" + prefixForPatch + xmlRootElementName + "\"\n");
return pathSb.toString();
}
}
diff --git a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/XSDElement.java b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/XSDElement.java
index 3ee9495..0e5c2fa 100644
--- a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/XSDElement.java
+++ b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/XSDElement.java
@@ -146,6 +146,11 @@ public class XSDElement implements Element {
}
}
}
+ if ( pathDescriptionProperty != null ) {
+ //suppress non-printable characters in a description
+ String replaceDescription = pathDescriptionProperty.replaceAll("[^\\p{ASCII}]", "");
+ return replaceDescription;
+ }
return pathDescriptionProperty;
}
public Vector<String> getIndexedProps() {
@@ -249,10 +254,18 @@ public class XSDElement implements Element {
}
return sbParameter.toString();
}
-
+
public String getPathParamYAML(String elementDescription) {
+ return getPathParamYAML(elementDescription, null);
+ }
+
+ public String getPathParamYAML(String elementDescription, String overrideName) {
+ // updated to allow caller to provide parameter name to use in API
StringBuffer sbParameter = new StringBuffer();
- sbParameter.append((" - name: " + this.getAttribute("name") + "\n"));
+ if ( overrideName == null ) {
+ overrideName = this.getAttribute("name");
+ }
+ sbParameter.append((" - name: " + overrideName + "\n"));
sbParameter.append((" in: path\n"));
if ( elementDescription != null && elementDescription.length() > 0 )
sbParameter.append((" description: " + elementDescription + "\n"));
@@ -723,3 +736,4 @@ public class XSDElement implements Element {
}
+
diff --git a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/YAMLfromOXM.java b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/YAMLfromOXM.java
index ee5fa36..32ae998 100644
--- a/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/YAMLfromOXM.java
+++ b/aai-schema-gen/src/main/java/org/onap/aai/schemagen/genxsd/YAMLfromOXM.java
@@ -55,6 +55,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
private static final String yaml_dir = (((System.getProperty("user.dir") != null)
&& (!System.getProperty("user.dir").contains(normalStartDir))) ? autoGenRoot : root)
+ "/aai_swagger_yaml";
+ private final String patchDefinePrefix = "zzzz-patch-";
private StringBuilder inventoryDefSb = null;
private String basePath;
@@ -194,37 +195,6 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
sb.append(entry.getValue());
}
-
- sb.append("patchDefinitions:\n");
- for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
- if (namespaceFilter != null && (!namespaceFilter.contains(entry.getKey()))) {
- continue;
- }
- String jb = entry.getValue().replaceAll("/definitions/", "/patchDefinitions/");
- int ndx = jb.indexOf("relationship-list:");
- if (ndx > 0) {
- jb = jb.substring(0, ndx);
- jb = jb.replaceAll(" +$", "");
- }
- int ndx1 = jb.indexOf("resource-version:");
- logger.debug("Key: " + entry.getKey() + " index: " + ndx1);
- logger.debug("Value: " + jb);
- if (ndx1 > 0) {
- jb = jb.substring(0, ndx1);
- jb = jb.replaceAll(" +$", "");
- }
- logger.debug("Value-after: " + jb);
- sb.append(jb);
- }
-
- sb.append("getDefinitions:\n");
- for (Map.Entry<String, String> entry : sortedJavaTypeDefinitions.entrySet()) {
- if (namespaceFilter != null && (!namespaceFilter.contains(entry.getKey()))) {
- continue;
- }
- String jb = entry.getValue().replaceAll("/definitions/", "/getDefinitions/");
- sb.append(jb);
- }
return sb.toString();
}
@@ -248,6 +218,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
String xmlRootElementName = getXMLRootElementName(javaTypeElement);
StringBuilder definitionsLocalSb = new StringBuilder(256);
+ StringBuilder definitionsLocalPatchSb = new StringBuilder(256);
String useTag = null;
String useOpId = null;
@@ -303,10 +274,14 @@ public class YAMLfromOXM extends OxmFileProcessor {
NodeList xmlElementNodes = parentElement.getElementsByTagName("xml-element");
StringBuffer sbParameters = new StringBuffer();
+ StringBuffer sbPathParameters = new StringBuffer(); // separate naming path parameters from name of parameter in the schema
StringBuffer sbRequired = new StringBuffer();
+
int requiredCnt = 0;
int propertyCnt = 0;
StringBuffer sbProperties = new StringBuffer();
+ int patchPropertyCnt = 0; // manage payload properties separately for patch
+ StringBuffer sbPropertiesPatch = new StringBuffer();
if (appliedPaths.containsKey(path)) {
return null;
@@ -321,6 +296,8 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
Vector<String> addTypeV = null;
+ String modifiedName;
+ String replaceDescription;
for (int i = 0; i < xmlElementNodes.getLength(); ++i) {
XSDElement xmlElementElement = new XSDElement((Element) xmlElementNodes.item(i));
if (!xmlElementElement.getParentNode().isSameNode(parentElement)) {
@@ -330,13 +307,24 @@ public class YAMLfromOXM extends OxmFileProcessor {
if (getItemName == null) {
addTypeV = xmlElementElement.getAddTypes(v.toString());
}
+ // use alternate name for parameter if already in the path string
+ modifiedName = "/{" + xmlElementElement.getAttribute("name") + "}";
+ if ( path.contains(modifiedName)) {
+ modifiedName = path.substring(path.lastIndexOf('/')+1) + "." + xmlElementElement.getAttribute("name");
+ } else {
+ modifiedName = xmlElementElement.getAttribute("name");
+ }
if ("true".equals(xmlElementElement.getAttribute("xml-key"))) {
- path += "/{" + xmlElementElement.getAttribute("name") + "}";
+ path += "/{" + modifiedName + "}";
}
logger.debug("path: " + path);
logger.debug("xmlElementElement.getAttribute(required):"
+ xmlElementElement.getAttribute("required"));
+ if ("true".equals(xmlElementElement.getAttribute("xml-key"))) {
+ sbParameters.append(xmlElementElement.getPathParamYAML(elementDescription));
+ sbPathParameters.append(xmlElementElement.getPathParamYAML(elementDescription, modifiedName));
+ }
if (("true").equals(xmlElementElement.getAttribute("required"))) {
if (requiredCnt == 0) {
sbRequired.append(" required:\n");
@@ -351,10 +339,6 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
}
}
-
- if ("true".equals(xmlElementElement.getAttribute("xml-key"))) {
- sbParameters.append(xmlElementElement.getPathParamYAML(elementDescription));
- }
if (indexedProps != null
&& indexedProps.contains(xmlElementElement.getAttribute("name"))) {
containerProps.add(xmlElementElement.getQueryParamYAML());
@@ -362,11 +346,15 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
if (xmlElementElement.isStandardType()) {
sbProperties.append(xmlElementElement.getTypePropertyYAML());
+ if ( !"resource-version".equals(xmlElementElement.getAttribute("name"))) {
+ sbPropertiesPatch.append(xmlElementElement.getTypePropertyYAML());
+ ++patchPropertyCnt;
+ }
++propertyCnt;
}
StringBuffer newPathParams = new StringBuffer(
- (pathParams == null ? "" : pathParams.toString()) + sbParameters.toString());
+ (pathParams == null ? "" : pathParams.toString()) + sbPathParameters.toString());
String useName;
for (int k = 0; addTypeV != null && k < addTypeV.size(); ++k) {
String addType = addTypeV.elementAt(k);
@@ -394,6 +382,11 @@ public class YAMLfromOXM extends OxmFileProcessor {
sbProperties.append(" type: object\n");
sbProperties.append(" $ref: \"#/definitions/"
+ itemName + "\"\n");
+ sbPropertiesPatch.append(" " + getXmlRootElementName(addType) + ":\n");
+ sbPropertiesPatch.append(" type: object\n");
+ sbPropertiesPatch.append(" $ref: \"#/definitions/"
+ + itemName + "\"\n");
+ ++patchPropertyCnt;
} else {
if ( "relationship".equals(itemName) ) {
System.out.println(v + "-relationship added as array for getItemName null");
@@ -423,6 +416,9 @@ public class YAMLfromOXM extends OxmFileProcessor {
if ( "relationship".equals(useName)) {
sbProperties.append(" type: object\n");
sbProperties.append(" $ref: \"#/definitions/relationship\"\n");
+ sbPropertiesPatch.append(" type: object\n");
+ sbPropertiesPatch.append(" $ref: \"#/definitions/relationship\"\n");
+ ++patchPropertyCnt;
} else {
sbProperties.append(" type: array\n items: \n");
sbProperties.append(" $ref: \"#/definitions/"
@@ -456,7 +452,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
if (pathParams == null) {
pathParams = new StringBuffer();
}
- pathParams.append(sbParameters);
+ pathParams.append(sbPathParameters);
}
GetOperation get = new GetOperation(useOpId, xmlRootElementName, tag, path,
pathParams == null ? "" : pathParams.toString());
@@ -469,6 +465,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
// add PATCH
PatchOperation patch = new PatchOperation(useOpId, xmlRootElementName, tag, path,
pathParams == null ? "" : pathParams.toString());
+ patch.setPrefixForPatchRef(patchDefinePrefix);
pathSb.append(patch.toString());
// add DELETE
DeleteOperation del = new DeleteOperation(useOpId, xmlRootElementName, tag, path,
@@ -597,10 +594,25 @@ public class YAMLfromOXM extends OxmFileProcessor {
if (pathDescriptionProperty != null) {
definitionsSb.append(" " + pathDescriptionProperty + "\n");
- definitionsLocalSb.append(" " + pathDescriptionProperty + "\n");
+ definitionsLocalSb.append(" " + pathDescriptionProperty + "\n");
+ }
+ if (StringUtils.isNotEmpty(validEdges) ) {
+ definitionsSb.append(validEdges);
+ definitionsLocalSb.append(validEdges);
}
- definitionsSb.append(validEdges);
- definitionsLocalSb.append(validEdges);
+ }
+ if ( patchPropertyCnt > 0 ) {
+ definitionsLocalPatchSb.append(" " + patchDefinePrefix + xmlRootElementName + ":\n");
+ if (StringUtils.isNotEmpty(pathDescriptionProperty) || StringUtils.isNotEmpty(validEdges)) {
+ definitionsLocalPatchSb.append(" description: |\n");
+ }
+ if (pathDescriptionProperty != null) {
+ definitionsLocalPatchSb.append(" " + pathDescriptionProperty + "\n");
+ }
+ if (StringUtils.isNotEmpty(validEdges) ) {
+ definitionsLocalPatchSb.append(validEdges);
+ }
+ definitionsLocalPatchSb.append(" properties:\n");
}
if (requiredCnt > 0) {
@@ -615,6 +627,7 @@ public class YAMLfromOXM extends OxmFileProcessor {
definitionsLocalSb.append(" properties:\n");
}
definitionsLocalSb.append(sbProperties);
+ definitionsLocalPatchSb.append(sbPropertiesPatch);
}
try {
namespaceFilter.add(xmlRootElementName);
@@ -627,6 +640,9 @@ public class YAMLfromOXM extends OxmFileProcessor {
definitionsLocalSb.toString());
} else {
javaTypeDefinitions.put(xmlRootElementName, definitionsLocalSb.toString());
+ if ( !"relationship-list".equals(xmlRootElementName)) {
+ javaTypeDefinitions.put(patchDefinePrefix + xmlRootElementName, definitionsLocalPatchSb.toString());
+ }
}
} catch (Exception e) {
e.printStackTrace();
@@ -691,3 +707,4 @@ public class YAMLfromOXM extends OxmFileProcessor {
}
}
+
diff --git a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/GetOperationTest.java b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/GetOperationTest.java
index 6a82cff..1540a30 100644
--- a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/GetOperationTest.java
+++ b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/GetOperationTest.java
@@ -47,9 +47,9 @@ public class GetOperationTest {
@Parameters
public static Collection<String []> testConditions() {
String inputs [][] = {
- {"NetworkGenericVnfsGenericVnf","generic-vnf","Network","/network/generic-vnfs/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"," /network/generic-vnfs/generic-vnf/{vnf-id}:\n get:\n tags:\n - Network\n summary: returns generic-vnf\n description: returns generic-vnf\n operationId: getNetworkGenericVnfsGenericVnf\n produces:\n - application/json\n - application/xml\n responses:\n \"200\":\n description: successful operation\n schema:\n $ref: \"#/getDefinitions/generic-vnf\"\n \"default\":\n null parameters:\n - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"},
+ {"NetworkGenericVnfsGenericVnf","generic-vnf","Network","/network/generic-vnfs/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"," /network/generic-vnfs/generic-vnf/{vnf-id}:\n get:\n tags:\n - Network\n summary: returns generic-vnf\n description: returns generic-vnf\n operationId: getNetworkGenericVnfsGenericVnf\n produces:\n - application/json\n - application/xml\n responses:\n \"200\":\n description: successful operation\n schema:\n $ref: \"#/definitions/generic-vnf\"\n \"default\":\n null parameters:\n - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"},
{"GenericVnf","generic-vnf","","/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__",""},
- {"CloudInfrastructurePserversPserverPInterfaces","p-interfaces","CloudInfrastructure","/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces"," - name: hostname\n in: path\n description: Value from executing hostname on the compute node.\n required: true\n type: string\n example: __HOSTNAME__"," /cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces:\n get:\n tags:\n - CloudInfrastructure\n summary: returns p-interfaces\n description: returns p-interfaces\n operationId: getCloudInfrastructurePserversPserverPInterfaces\n produces:\n - application/json\n - application/xml\n responses:\n \"200\":\n description: successful operation\n schema:\n $ref: \"#/getDefinitions/p-interfaces\"\n \"default\":\n null parameters:\n - name: hostname\n in: path\n description: Value from executing hostname on the compute node.\n required: true\n type: string\n example: __HOSTNAME__ - name: interface-name\n in: query\n description:\n required: false\n type: string - name: prov-status\n in: query\n description:\n required: false\n type: string"},
+ {"CloudInfrastructurePserversPserverPInterfaces","p-interfaces","CloudInfrastructure","/cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces"," - name: hostname\n in: path\n description: Value from executing hostname on the compute node.\n required: true\n type: string\n example: __HOSTNAME__"," /cloud-infrastructure/pservers/pserver/{hostname}/p-interfaces:\n get:\n tags:\n - CloudInfrastructure\n summary: returns p-interfaces\n description: returns p-interfaces\n operationId: getCloudInfrastructurePserversPserverPInterfaces\n produces:\n - application/json\n - application/xml\n responses:\n \"200\":\n description: successful operation\n schema:\n $ref: \"#/definitions/p-interfaces\"\n \"default\":\n null parameters:\n - name: hostname\n in: path\n description: Value from executing hostname on the compute node.\n required: true\n type: string\n example: __HOSTNAME__ - name: interface-name\n in: query\n description:\n required: false\n type: string - name: prov-status\n in: query\n description:\n required: false\n type: string"},
// {"","ctag-pool","","","",""},
// {"","pserver","","","",""},
// {"","oam-network","","","",""},
diff --git a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/NodesYAMLfromOXMTest.java b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/NodesYAMLfromOXMTest.java
index eb2ce81..70262ba 100644
--- a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/NodesYAMLfromOXMTest.java
+++ b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/NodesYAMLfromOXMTest.java
@@ -243,8 +243,6 @@ public class NodesYAMLfromOXMTest {
StringBuilder sb = new StringBuilder(32368);
sb.append(YAMLheader());
sb.append(YAMLops());
-// sb.append(YAMLdefs());
-// sb.append(YAMLpatchDefs());
sb.append(YAMLgetDefs());
return sb.toString();
}
@@ -383,176 +381,7 @@ public class NodesYAMLfromOXMTest {
sb.append(" type: string\n");
return sb.toString();
}
- public String YAMLdefs() {
- StringBuilder sb = new StringBuilder(8092);
- sb.append("definitions:\n");
- sb.append(" business:\n");
- sb.append(" description: |\n");
- sb.append(" Namespace for business related constructs\n");
- sb.append(" properties:\n");
- sb.append(" customers:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/definitions/customer\"\n");
- sb.append(" customer:\n");
- sb.append(" description: |\n");
- sb.append(" customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - FROM service-subscription (CHILD of customer, service-subscription BelongsTo customer, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this CUSTOMER node is deleted, this FROM node is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - global-customer-id\n");
- sb.append(" - subscriber-name\n");
- sb.append(" - subscriber-type\n");
- sb.append(" properties:\n");
- sb.append(" global-customer-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: Global customer id used across to uniquely identify customer.\n");
- sb.append(" subscriber-name:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber name, an alternate way to retrieve a customer.\n");
- sb.append(" subscriber-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber type, a way to provide VID with only the INFRA customers.\n");
- sb.append(" resource-version:\n");
- sb.append(" type: string\n");
- sb.append(" description: Used for optimistic concurrency. Must be empty on create, valid on update and delete.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/definitions/service-subscription\"\n");
- sb.append(" customers:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" properties:\n");
- sb.append(" customer:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/definitions/customer\"\n");
- sb.append(" inventory:\n");
- sb.append(" properties:\n");
- sb.append(" business:\n");
- sb.append(" type: object\n");
- sb.append(" $ref: \"#/definitions/business\"\n");
- sb.append(" nodes:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" properties:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" inventory-item-data:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" type: array" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" items:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" $ref: \"#/definitions/inventory-item-data\"" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" service-subscription:\n");
- sb.append(" description: |\n");
- sb.append(" Object that group service instances.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - TO customer (PARENT of service-subscription, service-subscription BelongsTo customer, MANY2ONE)(4)\n");
- sb.append(" - TO tenant( service-subscription Uses tenant, MANY2MANY)\n");
- sb.append(" - FROM service-instance (CHILD of service-subscription, service-instance BelongsTo service-subscription, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this SERVICE-SUBSCRIPTION node is deleted, this FROM node is DELETED also\n");
- sb.append(" -(4) IF this TO node is deleted, this SERVICE-SUBSCRIPTION is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - service-type\n");
- sb.append(" properties:\n");
- sb.append(" service-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Value defined by orchestration to identify this service.\n");
- sb.append(" temp-ub-sub-account-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: This property will be deleted from A&AI in the near future. Only stop gap solution.\n");
- sb.append(" resource-version:\n");
- sb.append(" type: string\n");
- sb.append(" description: Used for optimistic concurrency. Must be empty on create, valid on update and delete.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of objects that group service instances.\n");
- sb.append(" properties:\n");
- sb.append(" service-subscription:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/definitions/service-subscription\"\n");
- return sb.toString();
- }
- public String YAMLpatchDefs() {
- StringBuilder sb = new StringBuilder(8092);
- sb.append("patchDefinitions:\n");
- sb.append(" business:\n");
- sb.append(" description: |\n");
- sb.append(" Namespace for business related constructs\n");
- sb.append(" properties:\n");
- sb.append(" customers:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/patchDefinitions/customer\"\n");
- sb.append(" customer:\n");
- sb.append(" description: |\n");
- sb.append(" customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - FROM service-subscription (CHILD of customer, service-subscription BelongsTo customer, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this CUSTOMER node is deleted, this FROM node is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - global-customer-id\n");
- sb.append(" - subscriber-name\n");
- sb.append(" - subscriber-type\n");
- sb.append(" properties:\n");
- sb.append(" global-customer-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: Global customer id used across to uniquely identify customer.\n");
- sb.append(" subscriber-name:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber name, an alternate way to retrieve a customer.\n");
- sb.append(" subscriber-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber type, a way to provide VID with only the INFRA customers.\n");
- sb.append(" customers:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" properties:\n");
- sb.append(" customer:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/patchDefinitions/customer\"\n");
- sb.append(" inventory:\n");
- sb.append(" properties:\n");
- sb.append(" business:\n");
- sb.append(" type: object\n");
- sb.append(" $ref: \"#/patchDefinitions/business\"\n");
- sb.append(" nodes:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" properties:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" inventory-item-data:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" type: array" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" items:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" $ref: \"#/patchDefinitions/inventory-item-data\"" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" service-subscription:\n");
- sb.append(" description: |\n");
- sb.append(" Object that group service instances.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - TO customer (CHILD of customer, service-subscription BelongsTo customer, MANY2ONE)(4)\n");
- sb.append(" - TO tenant( service-subscription Uses tenant, MANY2MANY)\n");
- sb.append(" - FROM service-instance (CHILD of service-subscription, service-instance BelongsTo service-subscription, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this SERVICE-SUBSCRIPTION node is deleted, this FROM node is DELETED also\n");
- sb.append(" -(4) IF this TO node is deleted, this SERVICE-SUBSCRIPTION is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - service-type\n");
- sb.append(" properties:\n");
- sb.append(" service-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Value defined by orchestration to identify this service.\n");
- sb.append(" temp-ub-sub-account-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: This property will be deleted from A&AI in the near future. Only stop gap solution.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of objects that group service instances.\n");
- sb.append(" properties:\n");
- sb.append(" service-subscription:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/patchDefinitions/service-subscription\"\n");
- return sb.toString();
- }
+
public String YAMLgetDefs() {
StringBuilder sb = new StringBuilder(8092);
sb.append("definitions:\n");
diff --git a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/PatchOperationTest.java b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/PatchOperationTest.java
index 65cca9c..e686fbc 100644
--- a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/PatchOperationTest.java
+++ b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/PatchOperationTest.java
@@ -43,7 +43,7 @@ public class PatchOperationTest {
@Parameters
public static Collection<String []> testConditions() {
String inputs [][] = {
- {"NetworkGenericVnfsGenericVnf","generic-vnf","Network","/network/generic-vnfs/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"," patch:\n tags:\n - Network\n summary: update an existing generic-vnf\n description: |\n Update an existing generic-vnf\n #\n Note: Endpoints that are not devoted to object relationships support both PUT and PATCH operations.\n The PUT operation will entirely replace an existing object.\n The PATCH operation sends a \"description of changes\" for an existing object. The entire set of changes must be applied. An error result means no change occurs.\n #\n Other differences between PUT and PATCH are:\n #\n - For PATCH, you can send any of the values shown in sample REQUEST body. There are no required values.\n - For PATCH, resource-id which is a required REQUEST body element for PUT, must not be sent.\n - PATCH cannot be used to update relationship elements; there are dedicated PUT operations for this.\n operationId: UpdateNetworkGenericVnfsGenericVnf\n consumes:\n - application/json\n produces:\n - application/json\n responses:\n \"default\":\n null parameters:\n - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__ - name: body\n in: body\n description: generic-vnf object that needs to be updated.\n required: true\n schema:\n $ref: \"#/patchDefinitions/generic-vnf\"\n"},
+ {"NetworkGenericVnfsGenericVnf","generic-vnf","Network","/network/generic-vnfs/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__"," patch:\n tags:\n - Network\n summary: update an existing generic-vnf\n description: |\n Update an existing generic-vnf\n #\n Note: Endpoints that are not devoted to object relationships support both PUT and PATCH operations.\n The PUT operation will entirely replace an existing object.\n The PATCH operation sends a \"description of changes\" for an existing object. The entire set of changes must be applied. An error result means no change occurs.\n #\n Other differences between PUT and PATCH are:\n #\n - For PATCH, you can send any of the values shown in sample REQUEST body. There are no required values.\n - For PATCH, resource-id which is a required REQUEST body element for PUT, must not be sent.\n - PATCH cannot be used to update relationship elements; there are dedicated PUT operations for this.\n operationId: UpdateNetworkGenericVnfsGenericVnf\n consumes:\n - application/json\n produces:\n - application/json\n responses:\n \"default\":\n null parameters:\n - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__ - name: body\n in: body\n description: generic-vnf object that needs to be updated.\n required: true\n schema:\n $ref: \"#/definitions/generic-vnf\"\n"},
// if ( StringUtils.isEmpty(tag) )
{"GenericVnf","generic-vnf","","/generic-vnf/{vnf-id}"," - name: vnf-id\n in: path\n description: Unique id of VNF. This is unique across the graph.\n required: true\n type: string\n example: __VNF-ID__",""},
// Test: if ( !path.endsWith("/relationship") && !path.endsWith("}") )
diff --git a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/YAMLfromOXMTest.java b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/YAMLfromOXMTest.java
index 7f746ec..aa03cd2 100644
--- a/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/YAMLfromOXMTest.java
+++ b/aai-schema-gen/src/test/java/org/onap/aai/schemagen/genxsd/YAMLfromOXMTest.java
@@ -246,7 +246,7 @@ public class YAMLfromOXMTest {
} catch(Exception e) {
e.printStackTrace();
}
- assertThat("Definitions:\n"+definitions,definitions, is(YAMLdefs()+YAMLpatchDefs()+YAMLgetDefs()));
+ assertThat("Definitions:\n"+definitions,definitions, is(YAMLdefs()+YAMLdefsAddPatch()));
}
@Test
@@ -304,8 +304,7 @@ public class YAMLfromOXMTest {
sb.append(YAMLheader());
sb.append(YAMLops());
sb.append(YAMLdefs());
- sb.append(YAMLpatchDefs());
- sb.append(YAMLgetDefs());
+ sb.append(YAMLdefsAddPatch());
return sb.toString();
}
public String YAMLheader() {
@@ -357,7 +356,7 @@ public class YAMLfromOXMTest {
sb.append(" \"200\":\n");
sb.append(" description: successful operation\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/getDefinitions/service-subscription\"\n");
+ sb.append(" $ref: \"#/definitions/service-subscription\"\n");
sb.append(" \"default\":\n");
sb.append(" null parameters:\n");
sb.append(" - name: global-customer-id\n");
@@ -449,7 +448,7 @@ public class YAMLfromOXMTest {
sb.append(" description: service-subscription object that needs to be updated.\n");
sb.append(" required: true\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/patchDefinitions/service-subscription\"\n");
+ sb.append(" $ref: \"#/definitions/zzzz-patch-service-subscription\"\n");
sb.append(" delete:\n");
sb.append(" tags:\n");
sb.append(" - Business\n");
@@ -496,7 +495,7 @@ public class YAMLfromOXMTest {
sb.append(" \"200\":\n");
sb.append(" description: successful operation\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/getDefinitions/service-subscriptions\"\n");
+ sb.append(" $ref: \"#/definitions/service-subscriptions\"\n");
sb.append(" \"default\":\n");
sb.append(" null parameters:\n");
sb.append(" - name: global-customer-id\n");
@@ -524,7 +523,7 @@ public class YAMLfromOXMTest {
sb.append(" \"200\":\n");
sb.append(" description: successful operation\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/getDefinitions/customer\"\n");
+ sb.append(" $ref: \"#/definitions/customer\"\n");
sb.append(" \"default\":\n");
sb.append(" null parameters:\n");
sb.append(" - name: global-customer-id\n");
@@ -598,7 +597,7 @@ public class YAMLfromOXMTest {
sb.append(" description: customer object that needs to be updated.\n");
sb.append(" required: true\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/patchDefinitions/customer\"\n");
+ sb.append(" $ref: \"#/definitions/zzzz-patch-customer\"\n");
sb.append(" delete:\n");
sb.append(" tags:\n");
sb.append(" - Business\n");
@@ -639,7 +638,7 @@ public class YAMLfromOXMTest {
sb.append(" \"200\":\n");
sb.append(" description: successful operation\n");
sb.append(" schema:\n");
- sb.append(" $ref: \"#/getDefinitions/customers\"\n");
+ sb.append(" $ref: \"#/definitions/customers\"\n");
sb.append(" \"default\":\n");
sb.append(" null parameters:\n");
sb.append(" - name: global-customer-id\n");
@@ -749,28 +748,15 @@ public class YAMLfromOXMTest {
sb.append(" $ref: \"#/definitions/service-subscription\"\n");
return sb.toString();
}
- public String YAMLpatchDefs() {
+ public String YAMLdefsAddPatch() {
StringBuilder sb = new StringBuilder(8092);
- sb.append("patchDefinitions:\n");
- sb.append(" business:\n");
- sb.append(" description: |\n");
- sb.append(" Namespace for business related constructs\n");
- sb.append(" properties:\n");
- sb.append(" customers:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/patchDefinitions/customer\"\n");
- sb.append(" customer:\n");
+ sb.append(" zzzz-patch-customer:\n");
sb.append(" description: |\n");
sb.append(" customer identifiers to provide linkage back to BSS information.\n");
sb.append(" ###### Related Nodes\n");
sb.append(" - FROM service-subscription (CHILD of customer, service-subscription BelongsTo customer, MANY2ONE)(1)\n");
sb.append("\n");
sb.append(" -(1) IF this CUSTOMER node is deleted, this FROM node is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - global-customer-id\n");
- sb.append(" - subscriber-name\n");
- sb.append(" - subscriber-type\n");
sb.append(" properties:\n");
sb.append(" global-customer-id:\n");
sb.append(" type: string\n");
@@ -781,26 +767,7 @@ public class YAMLfromOXMTest {
sb.append(" subscriber-type:\n");
sb.append(" type: string\n");
sb.append(" description: Subscriber type, a way to provide VID with only the INFRA customers.\n");
- sb.append(" customers:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" properties:\n");
- sb.append(" customer:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/patchDefinitions/customer\"\n");
- sb.append(" inventory:\n");
- sb.append(" properties:\n");
- sb.append(" business:\n");
- sb.append(" type: object\n");
- sb.append(" $ref: \"#/patchDefinitions/business\"\n");
- sb.append(" nodes:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" properties:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" inventory-item-data:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" type: array" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" items:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" $ref: \"#/patchDefinitions/inventory-item-data\"" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" service-subscription:\n");
+ sb.append(" zzzz-patch-service-subscription:\n");
sb.append(" description: |\n");
sb.append(" Object that group service instances.\n");
sb.append(" ###### Related Nodes\n");
@@ -810,8 +777,6 @@ public class YAMLfromOXMTest {
sb.append("\n");
sb.append(" -(1) IF this SERVICE-SUBSCRIPTION node is deleted, this FROM node is DELETED also\n");
sb.append(" -(4) IF this TO node is deleted, this SERVICE-SUBSCRIPTION is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - service-type\n");
sb.append(" properties:\n");
sb.append(" service-type:\n");
sb.append(" type: string\n");
@@ -819,104 +784,6 @@ public class YAMLfromOXMTest {
sb.append(" temp-ub-sub-account-id:\n");
sb.append(" type: string\n");
sb.append(" description: This property will be deleted from A&AI in the near future. Only stop gap solution.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of objects that group service instances.\n");
- sb.append(" properties:\n");
- sb.append(" service-subscription:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/patchDefinitions/service-subscription\"\n");
- return sb.toString();
- }
- public String YAMLgetDefs() {
- StringBuilder sb = new StringBuilder(8092);
- sb.append("getDefinitions:\n");
- sb.append(" business:\n");
- sb.append(" description: |\n");
- sb.append(" Namespace for business related constructs\n");
- sb.append(" properties:\n");
- sb.append(" customers:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/getDefinitions/customer\"\n");
- sb.append(" customer:\n");
- sb.append(" description: |\n");
- sb.append(" customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - FROM service-subscription (CHILD of customer, service-subscription BelongsTo customer, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this CUSTOMER node is deleted, this FROM node is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - global-customer-id\n");
- sb.append(" - subscriber-name\n");
- sb.append(" - subscriber-type\n");
- sb.append(" properties:\n");
- sb.append(" global-customer-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: Global customer id used across to uniquely identify customer.\n");
- sb.append(" subscriber-name:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber name, an alternate way to retrieve a customer.\n");
- sb.append(" subscriber-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Subscriber type, a way to provide VID with only the INFRA customers.\n");
- sb.append(" resource-version:\n");
- sb.append(" type: string\n");
- sb.append(" description: Used for optimistic concurrency. Must be empty on create, valid on update and delete.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" type: array\n");
- sb.append(" items:\n");
- sb.append(" $ref: \"#/getDefinitions/service-subscription\"\n");
- sb.append(" customers:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of customer identifiers to provide linkage back to BSS information.\n");
- sb.append(" properties:\n");
- sb.append(" customer:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/getDefinitions/customer\"\n");
- sb.append(" inventory:\n");
- sb.append(" properties:\n");
- sb.append(" business:\n");
- sb.append(" type: object\n");
- sb.append(" $ref: \"#/getDefinitions/business\"\n");
- sb.append(" nodes:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" properties:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" inventory-item-data:" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" type: array" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" items:" + OxmFileProcessor.LINE_SEPARATOR );
- sb.append(" $ref: \"#/getDefinitions/inventory-item-data\"" + OxmFileProcessor.LINE_SEPARATOR);
- sb.append(" service-subscription:\n");
- sb.append(" description: |\n");
- sb.append(" Object that group service instances.\n");
- sb.append(" ###### Related Nodes\n");
- sb.append(" - TO customer (PARENT of service-subscription, service-subscription BelongsTo customer, MANY2ONE)(4)\n");
- sb.append(" - TO tenant( service-subscription Uses tenant, MANY2MANY)\n");
- sb.append(" - FROM service-instance (CHILD of service-subscription, service-instance BelongsTo service-subscription, MANY2ONE)(1)\n");
- sb.append("\n");
- sb.append(" -(1) IF this SERVICE-SUBSCRIPTION node is deleted, this FROM node is DELETED also\n");
- sb.append(" -(4) IF this TO node is deleted, this SERVICE-SUBSCRIPTION is DELETED also\n");
- sb.append(" required:\n");
- sb.append(" - service-type\n");
- sb.append(" properties:\n");
- sb.append(" service-type:\n");
- sb.append(" type: string\n");
- sb.append(" description: Value defined by orchestration to identify this service.\n");
- sb.append(" temp-ub-sub-account-id:\n");
- sb.append(" type: string\n");
- sb.append(" description: This property will be deleted from A&AI in the near future. Only stop gap solution.\n");
- sb.append(" resource-version:\n");
- sb.append(" type: string\n");
- sb.append(" description: Used for optimistic concurrency. Must be empty on create, valid on update and delete.\n");
- sb.append(" service-subscriptions:\n");
- sb.append(" description: |\n");
- sb.append(" Collection of objects that group service instances.\n");
- sb.append(" properties:\n");
- sb.append(" service-subscription:\n");
- sb.append(" type: array\n");
- sb.append(" items: \n");
- sb.append(" $ref: \"#/getDefinitions/service-subscription\"\n");
return sb.toString();
}
@@ -926,7 +793,7 @@ public class YAMLfromOXMTest {
sb.append(" properties:\n");
sb.append(" relationship:\n");
sb.append(" type: object\n");
- sb.append(" $ref: \"#/getDefinitions/relationship\"\n");
+ sb.append(" $ref: \"#/definitions/relationship\"\n");
return sb.toString();
}