diff options
author | 2018-10-04 07:06:41 +0100 | |
---|---|---|
committer | 2018-10-04 16:44:57 +0100 | |
commit | b213e23edf68d36b4c0984d94d38d444f96949e2 (patch) | |
tree | bd7b60df8e8220abe93094fbbe373bc9c19791d0 /plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap | |
parent | 16a8f59fed2e53b1bbedaf65a33165bb4d3225f8 (diff) |
Fix creation of sub Avro items
When an Avro object is created, nested sub avro objects
are not created automatically. This change allows
invocation of a method to create sub objects of Avro
objects.
Issue-ID: POLICY-954
Change-Id: Ie510867f2631ba6a8c6f5452c08aef5db67e8997
Signed-off-by: liamfallon <liam.fallon@ericsson.com>
Diffstat (limited to 'plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap')
-rw-r--r-- | plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap/policy/apex/plugins/context/schema/avro/AvroSchemaHelper.java | 88 |
1 files changed, 87 insertions, 1 deletions
diff --git a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap/policy/apex/plugins/context/schema/avro/AvroSchemaHelper.java b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap/policy/apex/plugins/context/schema/avro/AvroSchemaHelper.java index 015d9ea30..723aefdc5 100644 --- a/plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap/policy/apex/plugins/context/schema/avro/AvroSchemaHelper.java +++ b/plugins/plugins-context/plugins-context-schema/plugins-context-schema-avro/src/main/java/org/onap/policy/apex/plugins/context/schema/avro/AvroSchemaHelper.java @@ -25,8 +25,12 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import java.io.ByteArrayOutputStream; +import java.util.LinkedHashSet; +import java.util.Set; import org.apache.avro.Schema; +import org.apache.avro.Schema.Field; +import org.apache.avro.Schema.Type; import org.apache.avro.generic.GenericDatumReader; import org.apache.avro.generic.GenericDatumWriter; import org.apache.avro.generic.GenericRecord; @@ -37,6 +41,7 @@ import org.apache.avro.io.JsonDecoder; import org.apache.avro.io.JsonEncoder; import org.onap.policy.apex.context.ContextRuntimeException; import org.onap.policy.apex.context.impl.schema.AbstractSchemaHelper; +import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey; import org.onap.policy.apex.model.basicmodel.concepts.AxKey; import org.onap.policy.apex.model.contextmodel.concepts.AxContextSchema; import org.slf4j.ext.XLogger; @@ -101,7 +106,7 @@ public class AvroSchemaHelper extends AbstractSchemaHelper { // Create a new instance using the Avro object mapper final Object newInstance = avroObjectMapper.createNewInstance(avroSchema); - // If no new instance is created, use default schema handler behavior + // If no new instance is created, use default schema handler behaviour if (newInstance != null) { return newInstance; } else { @@ -130,6 +135,87 @@ public class AvroSchemaHelper extends AbstractSchemaHelper { } @Override + public Object createNewSubInstance(final String subInstanceType) { + final Set<String> foundTypes = new LinkedHashSet<>(); + + Object subInstance = createNewSubInstance(avroSchema, subInstanceType, foundTypes); + + if (subInstance != null) { + return subInstance; + } else { + final String returnString = getUserKey().getId() + ": the schema \"" + avroSchema.getName() + + "\" does not have a subtype of type \"" + subInstanceType + "\""; + LOGGER.warn(returnString); + throw new ContextRuntimeException(returnString); + } + } + + /** + * Create an instance of a sub type of this type. + * + * @param schema the Avro schema of the the type + * @param subInstanceType the sub type + * @param foundTypes types we have already found + * @return the sub type schema or null if it is not created + */ + private Object createNewSubInstance(Schema schema, String subInstanceType, final Set<String> foundTypes) { + // Try Array element types + if (Type.ARRAY == schema.getType()) { + Object newInstance = instantiateSubInstance(subInstanceType, schema.getElementType(), foundTypes); + if (newInstance != null) { + return newInstance; + } + } + + if (Type.MAP == schema.getType()) { + Object newInstance = instantiateSubInstance(subInstanceType, schema.getValueType(), foundTypes); + if (newInstance != null) { + return newInstance; + } + } + + if (Type.RECORD == schema.getType()) { + for (Field field : schema.getFields()) { + Object newInstance = instantiateSubInstance(subInstanceType, field.schema(), foundTypes); + if (newInstance != null) { + return newInstance; + } + } + } + + return null; + } + + /** + * Instantiate a sub instance of a type. + * + * @param subInstanceType the type of the sub instance to create + * @param subSchema the sub schema we have received + * @param foundTypes types we have already found + * @return an instance of the type or null if it is the incorrect type + */ + private Object instantiateSubInstance(final String subInstanceType, final Schema subSchema, + final Set<String> foundTypes) { + if (subSchema == null) { + return null; + } + + // Check for recursive use of field names in records, if we have already checked a field name + // skip it this time. + if (foundTypes.contains(subSchema.getName())) { + return null; + } + + foundTypes.add(subSchema.getName()); + + if (subSchema.getName().equals(subInstanceType)) { + return new AvroObjectMapperFactory().get(AxArtifactKey.getNullKey(), subSchema) + .createNewInstance(subSchema); + } + return createNewSubInstance(subSchema, subInstanceType, foundTypes); + } + + @Override public Object unmarshal(final Object object) { // If an object is already in the correct format, just carry on if (passThroughObject(object)) { |