aboutsummaryrefslogtreecommitdiffstats
path: root/models-pdp/src
diff options
context:
space:
mode:
Diffstat (limited to 'models-pdp/src')
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java59
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java23
-rw-r--r--models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpSubGroup.java36
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/ModelsTest.java6
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupTest.java74
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupsTest.java93
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpMessageTest.java3
-rw-r--r--models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpSubGroupTest.java127
8 files changed, 399 insertions, 22 deletions
diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java
index 8805ae9ba..53bf3c1c6 100644
--- a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java
+++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroup.java
@@ -21,13 +21,17 @@
package org.onap.policy.models.pdp.concepts;
+import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-
+import java.util.Set;
import lombok.Data;
import lombok.NoArgsConstructor;
-
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.models.base.PfNameVersion;
import org.onap.policy.models.base.PfUtils;
import org.onap.policy.models.pdp.enums.PdpState;
@@ -78,4 +82,55 @@ public class PdpGroup implements PfNameVersion, Comparable<PdpGroup> {
public int compareTo(final PdpGroup other) {
return compareNameVersion(this, other);
}
+
+ /**
+ * Validates that appropriate fields are populated for an incoming call to the PAP
+ * REST API.
+ *
+ * @return the validation result
+ */
+ public ValidationResult validatePapRest() {
+ BeanValidationResult result = new BeanValidationResult("group", this);
+
+ /*
+ * Don't care about version or state, because we override them. Ok if description
+ * is null.
+ */
+
+ result.validateNotNull("name", name);
+ result.validateNotNullList("pdpSubgroups", pdpSubgroups, PdpSubGroup::validatePapRest);
+
+ checkDuplicateSubgroups(result);
+
+ return result;
+ }
+
+ /**
+ * Checks for duplicate subgroups.
+ *
+ * @param result where to place validation results
+ */
+ private void checkDuplicateSubgroups(BeanValidationResult result) {
+ if (pdpSubgroups == null) {
+ return;
+ }
+
+ Set<String> set = new HashSet<>();
+
+ for (PdpSubGroup subgrp : pdpSubgroups) {
+ if (subgrp == null) {
+ continue;
+ }
+
+ String pdpType = subgrp.getPdpType();
+ if (pdpType == null) {
+ continue;
+ }
+
+ if (!set.add(pdpType)) {
+ result.addResult(new ObjectValidationResult("subgroups", pdpType, ValidationStatus.INVALID,
+ "duplicate subgroup"));
+ }
+ }
+ }
}
diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java
index 32e0b1a29..a7e05dd6b 100644
--- a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java
+++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpGroups.java
@@ -24,14 +24,14 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
/**
- * Request deploy or update a set of groups via the PDP Group deployment
- * REST API.
+ * Request deploy or update a set of groups via the PDP Group deployment REST API.
*/
@Getter
@Setter
@@ -41,14 +41,29 @@ public class PdpGroups {
/**
* Get the contents of this class as a list of PDP group maps.
+ *
* @return the PDP groups in a list of maps
*/
public List<Map<String, PdpGroup>> toMapList() {
final Map<String, PdpGroup> pdpGroupMap = new LinkedHashMap<>();
for (PdpGroup pdpGroup : groups) {
- pdpGroupMap.put(pdpGroup.getName() + ':' + pdpGroup.getVersion() , pdpGroup);
+ pdpGroupMap.put(pdpGroup.getName() + ':' + pdpGroup.getVersion(), pdpGroup);
}
return Collections.singletonList(pdpGroupMap);
}
+
+ /**
+ * Validates that appropriate fields are populated for an incoming call to the PAP
+ * REST API.
+ *
+ * @return the validation result
+ */
+ public ValidationResult validatePapRest() {
+ BeanValidationResult result = new BeanValidationResult("groups", this);
+
+ result.validateNotNullList("groups", groups, PdpGroup::validatePapRest);
+
+ return result;
+ }
}
diff --git a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpSubGroup.java b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpSubGroup.java
index 405408946..2618a5017 100644
--- a/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpSubGroup.java
+++ b/models-pdp/src/main/java/org/onap/policy/models/pdp/concepts/PdpSubGroup.java
@@ -24,16 +24,19 @@ package org.onap.policy.models.pdp.concepts;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-
import lombok.Data;
import lombok.NonNull;
-
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.models.base.PfUtils;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
/**
- * Class to represent a group of all PDP's of the same pdp type running for a particular domain.
+ * Class to represent a group of all PDP's of the same pdp type running for a particular
+ * domain.
*
* @author Ram Krishna Verma (ram.krishna.verma@est.tech)
*/
@@ -68,4 +71,31 @@ public class PdpSubGroup {
this.properties = (source.properties == null ? null : new LinkedHashMap<>(source.properties));
this.pdpInstances = PfUtils.mapList(source.pdpInstances, Pdp::new);
}
+
+ /**
+ * Validates that appropriate fields are populated for an incoming call to the PAP
+ * REST API.
+ *
+ * @return the validation result
+ */
+ public ValidationResult validatePapRest() {
+ BeanValidationResult result = new BeanValidationResult("group", this);
+
+ result.validateNotNull("pdpType", pdpType);
+ result.validateNotNullList("supportedPolicyTypes", supportedPolicyTypes,
+ ToscaPolicyTypeIdentifier::validatePapRest);
+ result.validateNotNullList("policies", policies, ToscaPolicyIdentifier::validatePapRest);
+
+ if (supportedPolicyTypes != null && supportedPolicyTypes.isEmpty()) {
+ result.addResult(new ObjectValidationResult("supportedPolicyTypes", supportedPolicyTypes,
+ ValidationStatus.INVALID, "empty list"));
+ }
+
+ if (desiredInstanceCount <= 0) {
+ result.addResult(new ObjectValidationResult("desiredInstanceCount", desiredInstanceCount,
+ ValidationStatus.INVALID, "non-positive"));
+ }
+
+ return result;
+ }
}
diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/ModelsTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/ModelsTest.java
index 541e00b02..7a6c03c71 100644
--- a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/ModelsTest.java
+++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/ModelsTest.java
@@ -21,12 +21,12 @@
package org.onap.policy.models.pdp.concepts;
+import com.openpojo.reflection.filters.FilterClassName;
import com.openpojo.reflection.filters.FilterPackageInfo;
import com.openpojo.validation.Validator;
import com.openpojo.validation.ValidatorBuilder;
import com.openpojo.validation.test.impl.GetterTester;
import com.openpojo.validation.test.impl.SetterTester;
-
import org.junit.Test;
import org.onap.policy.common.utils.validation.ToStringTester;
@@ -41,7 +41,7 @@ public class ModelsTest {
@Test
public void testPdpModels() {
final Validator validator = ValidatorBuilder.create().with(new ToStringTester()).with(new SetterTester())
- .with(new GetterTester()).build();
- validator.validate(POJO_PACKAGE, new FilterPackageInfo());
+ .with(new GetterTester()).build();
+ validator.validate(POJO_PACKAGE, new FilterPackageInfo(), new FilterClassName(PdpMessage.class.getName()));
}
}
diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupTest.java
index 77666b228..3082bb228 100644
--- a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupTest.java
+++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupTest.java
@@ -23,20 +23,30 @@ package org.onap.policy.models.pdp.concepts;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.models.pdp.enums.PdpState;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
/**
- * Test the copy constructor, as {@link ModelsTest} tests the other methods.
+ * Test methods not tested by {@link ModelsTest}.
*/
public class PdpGroupTest {
+ private static final String NAME = "my-name";
+ private static final String PDP_TYPE1 = "type-1";
+ private static final String PDP_TYPE2 = "type-2";
+ private static final String PDP_TYPE3 = "type-3";
@Test
public void testCopyConstructor() {
@@ -50,7 +60,7 @@ public class PdpGroupTest {
// verify with all values
orig.setDescription("my-descript");
- orig.setName("my-name");
+ orig.setName(NAME);
orig.setVersion("1.2.3");
orig.setDescription("my-description");
orig.setPdpGroupState(PdpState.SAFE);
@@ -108,4 +118,64 @@ public class PdpGroupTest {
assertEquals(1, mapList.size());
assertEquals(1, mapList.get(0).size());
}
+
+ @Test
+ public void testValidatePapRest() {
+ PdpGroup group = new PdpGroup();
+ group.setName(NAME);
+
+ PdpSubGroup subgroup1 = new PdpSubGroup();
+ subgroup1.setDesiredInstanceCount(1);
+ subgroup1.setPdpType(PDP_TYPE1);
+ subgroup1.setSupportedPolicyTypes(Arrays.asList(new ToscaPolicyTypeIdentifier("a-type-name", "3.2.1")));
+ subgroup1.setPolicies(Collections.emptyList());
+
+ PdpSubGroup subgroup2 = new PdpSubGroup(subgroup1);
+ subgroup2.setPdpType(PDP_TYPE2);
+
+ PdpSubGroup subgroup3 = new PdpSubGroup(subgroup1);
+ subgroup3.setPdpType(PDP_TYPE3);
+
+ group.setPdpSubgroups(Arrays.asList(subgroup1, subgroup2, subgroup3));
+
+ // valid
+ ValidationResult result = group.validatePapRest();
+ assertNotNull(result);
+ assertTrue(result.isValid());
+ assertNull(result.getResult());
+
+ // null name
+ PdpGroup group2 = new PdpGroup(group);
+ group2.setName(null);
+ assertInvalid(group2);
+
+ // null subgroup list
+ group2 = new PdpGroup(group);
+ group2.setPdpSubgroups(null);
+ assertInvalid(group2);
+
+ // null subgroup
+ group2 = new PdpGroup(group);
+ group2.setPdpSubgroups(Arrays.asList(subgroup1, null));
+ assertInvalid(group2);
+
+ // invalid subgroup
+ group2 = new PdpGroup(group);
+ PdpSubGroup subgroupX = new PdpSubGroup(subgroup1);
+ subgroupX.setPdpType(null);
+ group2.setPdpSubgroups(Arrays.asList(subgroupX));
+ assertInvalid(group2);
+
+ // duplicate PDP type
+ group2 = new PdpGroup(group);
+ group2.setPdpSubgroups(Arrays.asList(subgroup1, subgroup2, subgroup1));
+ assertInvalid(group2);
+ }
+
+ private void assertInvalid(PdpGroup group) {
+ ValidationResult result = group.validatePapRest();
+ assertNotNull(result);
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+ }
}
diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupsTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupsTest.java
new file mode 100644
index 000000000..22e178da2
--- /dev/null
+++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpGroupsTest.java
@@ -0,0 +1,93 @@
+/*
+ * ============LICENSE_START=======================================================
+ * ONAP Policy Models
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.models.pdp.concepts;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationResult;
+
+public class PdpGroupsTest {
+
+ @Test
+ public void testValidatePapRest_toMapList() {
+ PdpGroup group1 = new PdpGroup();
+ group1.setName("group-1");
+ group1.setPdpSubgroups(Collections.emptyList());
+
+ PdpGroup group2 = new PdpGroup();
+ group2.setName("group-2");
+ group2.setPdpSubgroups(Collections.emptyList());
+
+ PdpGroups groups = new PdpGroups();
+ groups.setGroups(Arrays.asList(group1, group2));
+
+ // valid
+ ValidationResult result = groups.validatePapRest();
+ assertNotNull(result);
+ assertTrue(result.isValid());
+ assertNull(result.getResult());
+
+ // check toMapList()
+ List<Map<String, PdpGroup>> lst = groups.toMapList();
+ assertEquals(1, lst.size());
+
+ Map<String, PdpGroup> map = lst.get(0);
+ assertEquals(2, map.size());
+
+ Iterator<PdpGroup> iter = map.values().iterator();
+ assertSame(group1, iter.next());
+ assertSame(group2, iter.next());
+
+ // null group list
+ groups = new PdpGroups();
+ groups.setGroups(null);
+ assertInvalid(groups);
+
+ // null group
+ groups = new PdpGroups();
+ groups.setGroups(Arrays.asList(group1, null));
+ assertInvalid(groups);
+
+ // invalid group
+ PdpGroup groupX = new PdpGroup(group1);
+ groupX.setName(null);
+ groups.setGroups(Arrays.asList(group1, groupX));
+ assertInvalid(groups);
+ }
+
+ private void assertInvalid(PdpGroups groups) {
+ ValidationResult result = groups.validatePapRest();
+ assertNotNull(result);
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+ }
+}
diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpMessageTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpMessageTest.java
index bc90f649b..10f31312c 100644
--- a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpMessageTest.java
+++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpMessageTest.java
@@ -29,9 +29,6 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.onap.policy.models.pdp.enums.PdpMessageType;
-/**
- * Tests methods not already tested by {@link TestModels}.
- */
public class PdpMessageTest {
private static final String PDP_NAME = "pdpA";
private static final String PDP_GROUP = "groupA";
diff --git a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpSubGroupTest.java b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpSubGroupTest.java
index 4284f71c4..7a7babecc 100644
--- a/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpSubGroupTest.java
+++ b/models-pdp/src/test/java/org/onap/policy/models/pdp/concepts/PdpSubGroupTest.java
@@ -23,19 +23,28 @@ package org.onap.policy.models.pdp.concepts;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;
-
import org.junit.Test;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
/**
- * Test the copy constructor, as {@link ModelsTest} tests the other methods.
+ * Test methods not tested by {@link ModelsTest}.
*/
public class PdpSubGroupTest {
+ private static final Coder coder = new StandardCoder();
@Test
public void testCopyConstructor() {
@@ -44,10 +53,9 @@ public class PdpSubGroupTest {
final PdpSubGroup orig = new PdpSubGroup();
// verify with null values
- assertEquals(
- "PdpSubGroup(pdpType=null, supportedPolicyTypes=[], policies=[], "
+ assertEquals("PdpSubGroup(pdpType=null, supportedPolicyTypes=[], policies=[], "
+ "currentInstanceCount=0, desiredInstanceCount=0, properties=null, pdpInstances=[])",
- new PdpSubGroup(orig).toString());
+ new PdpSubGroup(orig).toString());
// verify with all values
orig.setCurrentInstanceCount(10);
@@ -80,4 +88,113 @@ public class PdpSubGroupTest {
assertEquals(orig.toString(), new PdpSubGroup(orig).toString());
}
+
+ @Test
+ public void testValidatePapRest() throws Exception {
+ PdpSubGroup subgrp = new PdpSubGroup();
+
+ subgrp.setDesiredInstanceCount(1);
+ subgrp.setPdpType("pdp-type");
+ subgrp.setSupportedPolicyTypes(Arrays.asList(makeIdent("type-X", "3.0.0", ToscaPolicyTypeIdentifier.class)));
+ subgrp.setPolicies(Arrays.asList(makeIdent("policy-X", "4.0.0", ToscaPolicyIdentifier.class)));
+
+ // valid
+ ValidationResult result = subgrp.validatePapRest();
+ assertNotNull(result);
+ assertTrue(result.isValid());
+ assertNull(result.getResult());
+
+ // zero count
+ PdpSubGroup sub2 = new PdpSubGroup(subgrp);
+ sub2.setDesiredInstanceCount(0);
+ assertInvalid(sub2);
+
+ // negative count
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.setDesiredInstanceCount(-1);
+ assertInvalid(sub2);
+
+ // null pdp type
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.setPdpType(null);
+ assertInvalid(sub2);
+
+ // null policy types
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.setSupportedPolicyTypes(null);
+ assertInvalid(sub2);
+
+ // empty policy types
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.setSupportedPolicyTypes(Collections.emptyList());
+ assertInvalid(sub2);
+
+ // null policy type item
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.getSupportedPolicyTypes().set(0, null);
+ assertInvalid(sub2);
+
+ // invalid policy type item
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.getSupportedPolicyTypes().set(0, makeIdent(null, "3.0.0", ToscaPolicyTypeIdentifier.class));
+ assertInvalid(sub2);
+
+ // null policies
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.setPolicies(null);
+ assertInvalid(sub2);
+
+ // null policy item
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.getPolicies().set(0, null);
+ assertInvalid(sub2);
+
+ // invalid policy item
+ sub2 = new PdpSubGroup(subgrp);
+ sub2.getPolicies().set(0, makeIdent(null, "3.0.0", ToscaPolicyIdentifier.class));
+ assertInvalid(sub2);
+ }
+
+ private void assertInvalid(PdpSubGroup sub2) {
+ ValidationResult result = sub2.validatePapRest();
+ assertNotNull(result);
+ assertFalse(result.isValid());
+ assertNotNull(result.getResult());
+ }
+
+ /**
+ * Makes an identifier. Uses JSON which does no error checking.
+ *
+ * @param name name to put into the identifier
+ * @param version version to put into the identifier
+ * @param clazz type of identifier to create
+ * @return a new identifier
+ * @throws CoderException if the JSON cannot be decoded
+ */
+ public <T> T makeIdent(String name, String version, Class<T> clazz) throws CoderException {
+ StringBuilder bldr = new StringBuilder();
+ bldr.append("{");
+
+ if (name != null) {
+ bldr.append("'name':'");
+ bldr.append(name);
+ bldr.append("'");
+ }
+
+ if (version != null) {
+ if (name != null) {
+ bldr.append(',');
+ }
+
+ bldr.append("'version':'");
+ bldr.append(version);
+ bldr.append("'");
+ }
+
+ bldr.append("}");
+
+ String json = bldr.toString().replace('\'', '"');
+
+ return coder.decode(json, clazz);
+ }
}