Skip to content

Commit

Permalink
Fixed uuids at rest api.
Browse files Browse the repository at this point in the history
  • Loading branch information
Acarus committed Sep 21, 2016
1 parent 7488ab7 commit 54975ed
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 100 deletions.
Expand Up @@ -16,6 +16,7 @@

package org.kaaproject.kaa.server.common.core.algorithms;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
Expand All @@ -26,7 +27,7 @@
import org.apache.avro.Schema.Type;
import org.apache.avro.generic.GenericData;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ObjectNode;

import static org.kaaproject.kaa.server.common.core.algorithms.CommonConstants.*;
Expand Down Expand Up @@ -92,20 +93,50 @@ public static void copyJsonProperties(JsonProperties src, JsonProperties dst) {
}
}

public static String injectUuids(String json, Schema schema) throws IOException {
return injectUuids(json.getBytes(), schema);
}

public static void injectUuids(JsonNode json) {
boolean containerWithoutId = json.isContainerNode() && !json.has(UUID_FIELD);
boolean notArray = !json.isArray();
boolean childIsNotArray = !(json.size() == 1 && json.getElements().next() instanceof ArrayNode);
public static String injectUuids(byte[] content, Schema schema) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode root = objectMapper.readTree(content);
injectUuidsFromJsonNodes(root, schema);
return root.toString();
}

if (containerWithoutId && notArray && childIsNotArray) {
((ObjectNode)json).put(UUID_FIELD, (Integer)null);
public static String injectUuids(JsonNode root, Schema schema) {
return injectUuidsFromJsonNodes(root, schema).toString();
}

private static JsonNode injectUuidsFromJsonNodes(JsonNode json, Schema schema) {
if (json == null) {
return json;
}

for (JsonNode node : json) {
if (node.isContainerNode())
injectUuids(node);
switch (schema.getType()) {
case RECORD:
schema.getFields().stream()
.filter(f -> !f.name().equals(UUID_FIELD))
.forEach(f -> injectUuidsFromJsonNodes(json.get(f.name()), f.schema()));

boolean addressable = schema.getFields().stream().filter(f -> f.name().equals(UUID_FIELD)).findFirst().isPresent();
if (addressable) {
((ObjectNode) json).put(UUID_FIELD, (Integer) null);
}
break;
case UNION:
schema.getTypes()
.forEach(s -> injectUuidsFromJsonNodes(json.get(s.getName()), s));
break;
case ARRAY:
schema.getElementType().getTypes()
.forEach(s -> injectUuidsFromJsonNodes(json.get(s.getName()), s));
break;
default:
return json;
}

return json;
}

public static void removeUuids(JsonNode json) {
Expand Down
Expand Up @@ -17,6 +17,7 @@
package org.kaaproject.kaa.server.common.core.algorithms;


import org.apache.avro.Schema;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.Assert;
Expand All @@ -28,17 +29,18 @@
public class AvroUtilsTest {
private JsonNode data;
private JsonNode dataWithUUIDs;
private Schema avroSchema;

@Before
public void setUp() throws IOException {
data = new ObjectMapper().readTree(AvroUtilsTest.class.getClassLoader().getResourceAsStream("uuids/data.json"));
dataWithUUIDs = new ObjectMapper().readTree(AvroUtilsTest.class.getClassLoader().getResourceAsStream("uuids/data_with_uuids.json"));
avroSchema = new Schema.Parser().parse(AvroUtilsTest.class.getClassLoader().getResourceAsStream("uuids/schema.json"));
}

@Test
public void testInjectUuids() throws IOException {
AvroUtils.injectUuids(data);
String jsonWithUUIds = data.toString();
String jsonWithUUIds = AvroUtils.injectUuids(data, avroSchema);
Assert.assertTrue("Generated json is not equal json with UUIDs", jsonWithUUIds.equals(dataWithUUIDs.toString()));
}

Expand Down
21 changes: 1 addition & 20 deletions common/core/src/test/resources/uuids/data.json
@@ -1,22 +1,3 @@
{
"AddressList": {
"array": [
{
"label": "Kaa website",
"url": "http://www.kaaproject.org"
},
{
"label": "Kaa GitHub repository",
"url": "https://github.com/kaaproject/kaa"
},
{
"label": "Kaa docs",
"url": "http://docs.kaaproject.org/display/KAA/Kaa+IoT+Platform+Home"
},
{
"label": "Kaa configuration design reference",
"url": "http://docs.kaaproject.org/display/KAA/Configuration"
}
]
}
"label": "a"
}
25 changes: 1 addition & 24 deletions common/core/src/test/resources/uuids/data_with_uuids.json
@@ -1,27 +1,4 @@
{
"AddressList": {
"array": [
{
"label": "Kaa website",
"url": "http://www.kaaproject.org",
"__uuid":null
},
{
"label": "Kaa GitHub repository",
"url": "https://github.com/kaaproject/kaa",
"__uuid":null
},
{
"label": "Kaa docs",
"url": "http://docs.kaaproject.org/display/KAA/Kaa+IoT+Platform+Home",
"__uuid":null
},
{
"label": "Kaa configuration design reference",
"url": "http://docs.kaaproject.org/display/KAA/Configuration",
"__uuid":null
}
]
},
"label": "a",
"__uuid":null
}
8 changes: 8 additions & 0 deletions common/core/src/test/resources/uuids/schema.json
@@ -0,0 +1,8 @@
{
"type":"record",
"name": "someFields",
"fields":[
{"name":"label", "type":"string"},
{"name":"__uuid", "type":"string"}
]
}
Expand Up @@ -47,6 +47,7 @@
import org.kaaproject.kaa.common.dto.UpdateStatus;
import org.kaaproject.kaa.common.dto.VersionDto;
import org.kaaproject.kaa.common.dto.ctl.CTLSchemaDto;
import org.kaaproject.kaa.server.common.core.algorithms.AvroUtils;
import org.kaaproject.kaa.server.common.core.algorithms.generation.DefaultRecordGenerationAlgorithm;
import org.kaaproject.kaa.server.common.core.algorithms.generation.DefaultRecordGenerationAlgorithmImpl;
import org.kaaproject.kaa.server.common.core.algorithms.schema.SchemaCreationException;
Expand Down Expand Up @@ -271,24 +272,27 @@ private void validateUuids(ConfigurationDto currentConfiguration, ConfigurationD
try {
EndpointGroup endpointGroup = endpointGroupDao.findById(currentConfiguration.getEndpointGroupId());
GenericAvroConverter<GenericRecord> avroConverter;
Schema avroSchema;
KaaData body = null;
if (endpointGroup != null) {
if (endpointGroup.getWeight() == 0) {
LOG.debug("Create default UUID validator with base schema: {}", configurationSchema.getBaseSchema());
BaseSchema baseSchema = new BaseSchema(configurationSchema.getBaseSchema());
uuidValidator = new DefaultUuidValidator(baseSchema, new BaseDataFactory());
avroConverter = new GenericAvroConverter<GenericRecord>(baseSchema.getRawSchema());
avroSchema = new Schema.Parser().parse(baseSchema.getRawSchema());
} else {
LOG.debug("Create default UUID validator with override schema: {}", configurationSchema.getOverrideSchema());
OverrideSchema overrideSchema = new OverrideSchema(configurationSchema.getOverrideSchema());
uuidValidator = new DefaultUuidValidator(overrideSchema, new OverrideDataFactory());
avroConverter = new GenericAvroConverter<GenericRecord>(overrideSchema.getRawSchema());
avroSchema = new Schema.Parser().parse(overrideSchema.getRawSchema());
}
GenericRecord previousRecord = null;
if (previousConfiguration != null) {
previousRecord = avroConverter.decodeJson(previousConfiguration.getBody());
}
GenericRecord currentRecord = avroConverter.decodeJson(currentConfiguration.getBody());
GenericRecord currentRecord = avroConverter.decodeJson(AvroUtils.injectUuids(currentConfiguration.getBody(), avroSchema));
body = uuidValidator.validateUuidFields(currentRecord, previousRecord);
}
if (body != null) {
Expand Down
Expand Up @@ -18,10 +18,6 @@

import org.apache.avro.Schema;
import org.apache.avro.generic.GenericRecord;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.hibernate.StaleObjectStateException;
import org.kaaproject.avro.ui.converter.FormAvroConverter;
import org.kaaproject.avro.ui.shared.RecordField;
Expand Down Expand Up @@ -49,6 +45,7 @@
import org.kaaproject.kaa.server.admin.shared.services.GroupService;
import org.kaaproject.kaa.server.admin.shared.services.KaaAdminServiceException;
import org.kaaproject.kaa.server.admin.shared.services.ServiceErrorCode;
import org.kaaproject.kaa.server.common.core.algorithms.AvroUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand Down Expand Up @@ -341,17 +338,12 @@ public ConfigurationRecordFormDto deactivateConfigurationRecordForm(String confi
public RecordField getConfigurationRecordDataFromFile(String schema, String fileItemName) throws KaaAdminServiceException {
checkAuthority(KaaAuthorityDto.TENANT_DEVELOPER, KaaAuthorityDto.TENANT_USER);
try {
byte[] body = getFileContent(fileItemName);

Schema avroSchema = new Schema.Parser().parse(schema);
JsonNode json = new ObjectMapper().readTree(body);
json = injectUuids(json, avroSchema);
body = json.toString().getBytes();

byte[] body = getFileContent(fileItemName);
body = AvroUtils.injectUuids(body, avroSchema).getBytes();
GenericAvroConverter<GenericRecord> converter = new GenericAvroConverter<>(schema);
GenericRecord record = converter.decodeJson(body);
RecordField recordData = FormAvroConverter.createRecordFieldFromGenericRecord(record);
return recordData;
return FormAvroConverter.createRecordFieldFromGenericRecord(record);
} catch (Exception e) {
throw Utils.handleException(e);
}
Expand Down Expand Up @@ -555,35 +547,4 @@ private List<SchemaInfoDto> toConfigurationSchemaInfos(List<VersionDto> schemas,
}
return schemaInfos;
}

private JsonNode injectUuids(JsonNode json, Schema schema) {
if (json == null) return json;
String UUID_FIELD = "__uuid";

switch (schema.getType()) {
case RECORD:
schema.getFields().stream()
.filter(f -> !f.name().equals(UUID_FIELD))
.forEach(f -> injectUuids(json.get(f.name()), f.schema()));

boolean addressable = schema.getFields().stream().filter(f -> f.name().equals(UUID_FIELD)).findFirst().isPresent();
if (addressable) {
((ObjectNode) json).put(UUID_FIELD, (Integer) null);
}
break;
case UNION:
schema.getTypes()
.forEach(s -> injectUuids(json.get(s.getName()), s));
break;
case ARRAY:
schema.getElementType().getTypes()
.forEach(s -> injectUuids(json.get(s.getName()), s));
break;
default:
return json;
}

return json;
}

}

0 comments on commit 54975ed

Please sign in to comment.