diff options
5 files changed, 255 insertions, 269 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java index 646a7ecc8b..68adbd5ae3 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java @@ -74,7 +74,9 @@ public class PropertyConvertor { props.stream().filter(p -> p.getOwnerId() == null || p.getOwnerId().equals(component.getUniqueId())).forEach(property -> { ToscaProperty prop = convertProperty(dataTypes, property, false); - properties.put(property.getName(), prop); + if (prop != null) { + properties.put(property.getName(), prop); + } }); if (!properties.isEmpty()) { toscaNodeType.setProperties(properties); @@ -98,13 +100,17 @@ public class PropertyConvertor { } log.trace("try to convert property {} from type {} with default value [{}]", property.getName(), property.getType(), property.getDefaultValue()); prop.setDefaultp(convertToToscaObject(property.getType(), property.getDefaultValue(), innerType, dataTypes)); + + if (prop.getDefaultp() == null) { + return null; + } prop.setType(property.getType()); - prop.setDescription(property.getDescription()); - if (isCapabiltyProperty) { - prop.setStatus(property.getStatus()); - prop.setRequired(property.isRequired()); - } - return prop; + prop.setDescription(property.getDescription()); + if (isCapabiltyProperty) { + prop.setStatus(property.getStatus()); + prop.setRequired(property.isRequired()); + } + return prop; } public Object convertToToscaObject(String propertyType, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java index e6f1ac82fb..a987e0243b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/tosca/PropertyConvertorTest.java @@ -1,71 +1,102 @@ package org.openecomp.sdc.be.tosca; -import java.util.Map; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; -import javax.annotation.Generated; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; import org.junit.Test; -import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; import org.openecomp.sdc.be.tosca.model.ToscaProperty; import fj.data.Either; public class PropertyConvertorTest { + private PropertyDefinition property; + Map<String, DataTypeDefinition> dataTypes; - private PropertyConvertor createTestSubject() { - return new PropertyConvertor(); - } - - - @Test - public void testGetInstance() throws Exception { - PropertyConvertor result; - - // default test - result = PropertyConvertor.getInstance(); - } + @Before + public void setUp(){ + property = new PropertyDefinition(); + property.setName("myProperty"); + property.setType(ToscaPropertyType.INTEGER.getType()); + dataTypes = new HashMap<String, DataTypeDefinition>(); + dataTypes.put(property.getName(), new DataTypeDefinition()); + } - - @Test - public void testConvertProperties() throws Exception { - PropertyConvertor testSubject; - Component component = null; - ToscaNodeType toscaNodeType = null; - Map<String, DataTypeDefinition> dataTypes = null; - Either<ToscaNodeType, ToscaError> result; - // default test - testSubject = createTestSubject(); - result = testSubject.convertProperties(component, toscaNodeType, dataTypes); - } + @Test + public void convertPropertyWhenValueAndDefaultNull() { + assertNull(PropertyConvertor.getInstance().convertProperty(dataTypes, property, false)); + } - - @Test - public void testConvertProperty() throws Exception { - PropertyConvertor testSubject; - Map<String, DataTypeDefinition> dataTypes = null; - PropertyDefinition property = null; - boolean isCapabiltyProperty = false; - ToscaProperty result; + @Test + public void convertPropertyWhenValueNullAndDefaultNotEmpty() { + final String def = "1"; + property.setDefaultValue(def); + ToscaProperty result = PropertyConvertor.getInstance().convertProperty(dataTypes, property, false); + assertNotNull(result); + assertEquals(Integer.valueOf(def).intValue(), result.getDefaultp()); + } - // default test - testSubject = createTestSubject(); - } + @Test + public void convertPropertiesWhenValueAndDefaultNullInOne() { + PropertyDefinition property1 = new PropertyDefinition(); + property1.setName("otherProperty"); + property1.setType(ToscaPropertyType.INTEGER.getType()); + property1.setDefaultValue("2"); + dataTypes.put(property1.getName(), new DataTypeDefinition()); + Resource resource = new Resource(); + List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>(); + properties.add(property); + properties.add(property1); + resource.setProperties(properties); + Either<ToscaNodeType, ToscaError> result = PropertyConvertor.getInstance().convertProperties(resource, new ToscaNodeType(), dataTypes); + assertTrue(result.isLeft()); + assertEquals(1, result.left().value().getProperties().size()); + } - - @Test - public void testConvertToToscaObject() throws Exception { - PropertyConvertor testSubject; - String propertyType = ""; - String value = ""; - String innerType = ""; - Map<String, DataTypeDefinition> dataTypes = null; - Object result; + @Test + public void convertPropertiesWhenValueAndDefaultExist() { + PropertyDefinition property1 = new PropertyDefinition(); + property1.setName("otherProperty"); + property1.setType(ToscaPropertyType.INTEGER.getType()); + property1.setDefaultValue("2"); + property.setDefaultValue("1"); + dataTypes.put(property1.getName(), new DataTypeDefinition()); + Resource resource = new Resource(); + List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>(); + properties.add(property); + properties.add(property1); + resource.setProperties(properties); + Either<ToscaNodeType, ToscaError> result = PropertyConvertor.getInstance().convertProperties(resource, new ToscaNodeType(), dataTypes); + assertTrue(result.isLeft()); + assertEquals(2, result.left().value().getProperties().size()); + } - // default test - testSubject = createTestSubject(); - } + @Test + public void convertPropertiesWhenValueAndDefaultNullInAll() { + PropertyDefinition property1 = new PropertyDefinition(); + property1.setName("otherProperty"); + property1.setType(ToscaPropertyType.INTEGER.getType()); + dataTypes.put(property1.getName(), new DataTypeDefinition()); + Resource resource = new Resource(); + List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>(); + properties.add(property); + properties.add(property1); + resource.setProperties(properties); + Either<ToscaNodeType, ToscaError> result = PropertyConvertor.getInstance().convertProperties(resource, new ToscaNodeType(), dataTypes); + assertTrue(result.isLeft()); + assertNull(result.left().value().getProperties()); + } }
\ No newline at end of file diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java index 2d389f5fe5..f3b842e0cf 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java @@ -35,7 +35,7 @@ public class DataTypePropertyConverter { */ public String getDataTypePropertiesDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) { JsonObject defaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes); - return !defaultValues.isJsonNull() ? gson.toJson(defaultValues) : null; + return !JsonUtils.isJsonNullOrEmpty(defaultValues) ? gson.toJson(defaultValues) : null; } /** diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java index ebb7566611..e15d784c7a 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverterTest.java @@ -1,8 +1,5 @@ package org.openecomp.sdc.be.model.tosca.converters; -import static org.junit.Assert.*; - -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import org.junit.Before; import org.junit.Test; @@ -16,226 +13,175 @@ import java.util.HashMap; import java.util.Map; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import java.util.*; -import org.junit.Assert; +import static org.junit.Assert.assertNull; public class DataTypePropertyConverterTest { - private static final String EMPTY_JSON_STR = "{}"; - public static final String PROPERTY2_DEFAULT = "{\"prop1\":\"def1\",\"prop3\":\"def3\"}"; - private DataTypePropertyConverter testInstance = DataTypePropertyConverter.getInstance(); - private Map<String, DataTypeDefinition> dataTypes; - private DataTypeDefinition noDefaultValue, dataType1, dataType2, dataType3; - private PropertyDefinition prop1, prop2, prop3, noDefaultProp; - - @Before - public void setUp() throws Exception { - dataTypes = new HashMap<>(); - - prop1 = new PropertyDefinition(); - prop1.setDefaultValue("def1"); - prop1.setName("prop1"); - - prop2 = new PropertyDefinition(); - prop2.setType("dataType1"); - prop2.setName("prop2"); - - prop3 = new PropertyDefinition(); - prop3.setDefaultValue("def3"); - prop3.setName("prop3"); - - noDefaultProp = new PropertyDefinition(); - noDefaultProp.setName("noDefaultProp"); - - noDefaultValue = new DataTypeDefinition(); - noDefaultValue.setProperties(Collections.singletonList(noDefaultProp)); - - dataType1 = new DataTypeDefinition(); - dataType1.setProperties(Arrays.asList(prop1, prop3)); - - dataType2 = new DataTypeDefinition(); - dataType2.setDerivedFrom(dataType1); - - dataType3 = new DataTypeDefinition(); - dataType3.setProperties(Collections.singletonList(prop2)); - dataType3.setDerivedFrom(noDefaultValue); - - dataTypes.put("noDefault", noDefaultValue); - dataTypes.put("dataType1", dataType1); - dataTypes.put("dataType2", dataType2); - dataTypes.put("dataType3", dataType3); - } - - @Test - public void testGetPropertyDefaultValuesRec_dataTypeNotExist() throws Exception { - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("someType", dataTypes); - assertEquals(EMPTY_JSON_STR, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec_NoDefaultValue() throws Exception { - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("noDefault", dataTypes); - assertEquals(EMPTY_JSON_STR, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec() throws Exception { - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType1", dataTypes); - assertEquals(PROPERTY2_DEFAULT, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType_derivedDataTypeHasNoDefaults() - throws Exception { - dataType2.setDerivedFrom(noDefaultValue); - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes); - assertEquals(EMPTY_JSON_STR, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType() throws Exception { - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes); - assertEquals(PROPERTY2_DEFAULT, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties_dataTypeOfPropertyHasNoDefault() - throws Exception { - dataType3.getProperties().get(0).setType(noDefaultValue.getName()); - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes); - assertEquals(EMPTY_JSON_STR, defaultValue); - } - - @Test - public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties() throws Exception { - String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes); - assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}", defaultValue);// data - // type - // 3 - // has - // property - // prop2 - // which - // has - // a - // data - // type - // with - // property - // prop1 - // which - // has - // a - // default - // value - } - - @Test - public void testMergeDefaultValues_allDefaultValuesAreOverridden() throws Exception { - JsonObject value = new JsonObject(); - value.addProperty(noDefaultProp.getName(), "override1"); - - JsonObject prop1Val = new JsonObject(); - prop1Val.addProperty(prop1.getName(), "prop1Override"); - - JsonObject prop3Val = new JsonObject(); - prop3Val.addProperty(prop3.getName(), "prop3Override"); - - JsonObject prop2Value = new JsonObject(); - prop2Value.add(prop3.getName(), prop3Val); - prop2Value.add(prop1.getName(), prop1Val); - - value.add(prop2.getName(), prop2Value); - - String valBeforeMerge = value.toString(); - - testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - assertEquals(valBeforeMerge, value.toString()); - } - - @Test - public void testMergeDefaultValues() throws Exception { - JsonObject value = new JsonObject(); - value.addProperty(noDefaultProp.getName(), "override1"); - - JsonObject prop1Val = new JsonObject(); - prop1Val.addProperty(prop1.getName(), "prop1Override"); - - value.add(prop2.getName(), prop1Val); - - testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - - assertEquals("{\"noDefaultProp\":\"override1\",\"prop2\":{\"prop1\":\"prop1Override\",\"prop3\":\"def3\"}}", - value.toString());// expect to merge prop 3 default as it was - // not overridden - } - - @Test - public void testMergeDefaultValues_mergeAll() throws Exception { - JsonObject value = new JsonObject(); - testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - - assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}", value.toString());// expect - // to - // merge - // prop - // 3 - // default - // as - // it - // was - // not - // overridden - } - - @Test - public void testMergeDefaultValues_doNotAddDefaultsForGetInputValues() throws Exception { - - JsonObject getInputValue = new JsonObject(); - getInputValue.addProperty("get_input", "in1"); - - JsonObject value = new JsonObject(); - value.add(prop2.getName(), getInputValue); - - testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - - assertEquals("{\"prop2\":{\"get_input\":\"in1\"}}", value.toString()); - } - - @Test - public void testMergeDefaultValues_doNotAddDefaultsForGetInputInnerValues() throws Exception { - JsonObject getInputValue = new JsonObject(); - getInputValue.addProperty("get_input", "in1"); + private static final String EMPTY_JSON_STR = "{}"; + public static final String PROPERTY2_DEFAULT = "{\"prop1\":\"def1\",\"prop3\":\"def3\"}"; + private DataTypePropertyConverter testInstance = DataTypePropertyConverter.getInstance(); + private Map<String, DataTypeDefinition> dataTypes; + private DataTypeDefinition noDefaultValue, dataType1, dataType2, dataType3; + private PropertyDefinition prop1, prop2, prop3, noDefaultProp; + + @Before + public void setUp() throws Exception { + dataTypes = new HashMap<>(); + + prop1 = new PropertyDefinition(); + prop1.setDefaultValue("def1"); + prop1.setName("prop1"); + + prop2 = new PropertyDefinition(); + prop2.setType("dataType1"); + prop2.setName("prop2"); + + prop3 = new PropertyDefinition(); + prop3.setDefaultValue("def3"); + prop3.setName("prop3"); + + noDefaultProp = new PropertyDefinition(); + noDefaultProp.setName("noDefaultProp"); + + noDefaultValue = new DataTypeDefinition(); + noDefaultValue.setProperties(Collections.singletonList(noDefaultProp)); + + dataType1 = new DataTypeDefinition(); + dataType1.setProperties(Arrays.asList(prop1, prop3)); + + dataType2 = new DataTypeDefinition(); + dataType2.setDerivedFrom(dataType1); + + dataType3 = new DataTypeDefinition(); + dataType3.setProperties(Collections.singletonList(prop2)); + dataType3.setDerivedFrom(noDefaultValue); + + dataTypes.put("noDefault", noDefaultValue); + dataTypes.put("dataType1", dataType1); + dataTypes.put("dataType2", dataType2); + dataTypes.put("dataType3", dataType3); + } + + @Test + public void testGetPropertyDefaultValuesRec_dataTypeNotExist() throws Exception { + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("someType", dataTypes); + assertNull(defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec_NoDefaultValue() throws Exception { + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("noDefault", dataTypes); + assertNull(defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec() throws Exception { + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType1", dataTypes); + assertEquals(PROPERTY2_DEFAULT, defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType_derivedDataTypeHasNoDefaults() throws Exception { + dataType2.setDerivedFrom(noDefaultValue); + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes); + assertNull(defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec_defaultFromDerivedDataType() throws Exception { + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType2", dataTypes); + assertEquals(PROPERTY2_DEFAULT, defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties_dataTypeOfPropertyHasNoDefault() throws Exception { + dataType3.getProperties().get(0).setType(noDefaultValue.getName()); + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes); + assertNull(defaultValue); + } + + @Test + public void testGetPropertyDefaultValuesRec_defaultFromDataTypesOfProperties() throws Exception { + String defaultValue = testInstance.getDataTypePropertiesDefaultValuesRec("dataType3", dataTypes); + assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}", defaultValue);//data type 3 has property prop2 which has a data type with property prop1 which has a default value + } + + @Test + public void testMergeDefaultValues_allDefaultValuesAreOverridden() throws Exception { + JsonObject value = new JsonObject(); + value.addProperty(noDefaultProp.getName(), "override1"); + + JsonObject prop1Val = new JsonObject(); + prop1Val.addProperty(prop1.getName(), "prop1Override"); + + JsonObject prop3Val = new JsonObject(); + prop3Val.addProperty(prop3.getName(), "prop3Override"); + + JsonObject prop2Value = new JsonObject(); + prop2Value.add(prop3.getName(), prop3Val); + prop2Value.add(prop1.getName(), prop1Val); + + value.add(prop2.getName(), prop2Value); + + String valBeforeMerge = value.toString(); + + testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); + assertEquals(valBeforeMerge, value.toString()); + } + + @Test + public void testMergeDefaultValues() throws Exception { + JsonObject value = new JsonObject(); + value.addProperty(noDefaultProp.getName(), "override1"); + + JsonObject prop1Val = new JsonObject(); + prop1Val.addProperty(prop1.getName(), "prop1Override"); + + value.add(prop2.getName(), prop1Val); + + testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); + + assertEquals("{\"noDefaultProp\":\"override1\",\"prop2\":{\"prop1\":\"prop1Override\",\"prop3\":\"def3\"}}", + value.toString());//expect to merge prop 3 default as it was not overridden + } + + @Test + public void testMergeDefaultValues_mergeAll() throws Exception { + JsonObject value = new JsonObject(); + testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - JsonObject prop1Val = new JsonObject(); - prop1Val.add(prop1.getName(), getInputValue); + assertEquals("{\"prop2\":" + PROPERTY2_DEFAULT + "}", + value.toString());//expect to merge prop 3 default as it was not overridden + } - JsonObject value = new JsonObject(); - value.add(prop2.getName(), prop1Val); + @Test + public void testMergeDefaultValues_doNotAddDefaultsForGetInputValues() throws Exception { - testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); + JsonObject getInputValue = new JsonObject(); + getInputValue.addProperty("get_input", "in1"); - assertEquals("{\"prop2\":{\"prop1\":{\"get_input\":\"in1\"},\"prop3\":\"def3\"}}", value.toString()); + JsonObject value = new JsonObject(); + value.add(prop2.getName(), getInputValue); - } + testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - private DataTypePropertyConverter createTestSubject() { - return DataTypePropertyConverter.getInstance(); - } + assertEquals("{\"prop2\":{\"get_input\":\"in1\"}}", value.toString()); + } - - @Test - public void testGetInstance() throws Exception { - DataTypePropertyConverter result; + @Test + public void testMergeDefaultValues_doNotAddDefaultsForGetInputInnerValues() throws Exception { + JsonObject getInputValue = new JsonObject(); + getInputValue.addProperty("get_input", "in1"); - // default test - result = DataTypePropertyConverter.getInstance(); - } + JsonObject prop1Val = new JsonObject(); + prop1Val.add(prop1.getName(), getInputValue); - + JsonObject value = new JsonObject(); + value.add(prop2.getName(), prop1Val); + testInstance.mergeDataTypeDefaultValuesWithPropertyValue(value, "dataType3", dataTypes); - + assertEquals("{\"prop2\":{\"prop1\":{\"get_input\":\"in1\"},\"prop3\":\"def3\"}}", value.toString()); + } } diff --git a/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java b/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java index 367b806104..9022e7246e 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java @@ -54,5 +54,8 @@ public class JsonUtils { public static boolean isEmptyJson(JsonElement json) { return json.isJsonPrimitive() ? false : JsonUtils.isEmptyJson(json.getAsJsonObject()); } - + + public static boolean isJsonNullOrEmpty(JsonObject json) { + return json.isJsonNull() || isEmptyJson(json); + } } |