Skip to content

Commit

Permalink
added defensive code to validate json
Browse files Browse the repository at this point in the history
  • Loading branch information
smartrics committed May 31, 2024
1 parent eedd523 commit 24f230a
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
import org.apache.nifi.util.TestRunners;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import smartrics.iotics.nifi.processors.objects.MyTwinModel;

import java.io.IOException;
Expand All @@ -36,6 +38,8 @@

public class IoticsJSONToTwinIT {

private static final Gson GSON = new Gson();

private static final String CONTENT = """
{
"properties": [
Expand All @@ -52,6 +56,74 @@ public class IoticsJSONToTwinIT {
]
}
""";
private static final String INVALID_JSON = """
{ "properties": [ {
"key": "http://data.iotics.com/nifi/isOperational",
"value": "true",
"type": "Literal",
"dataType": "boolean"
}, }""";
private static final String NULL_VALUE_PROP_JSON = """
{ "properties": [ {
"key": "http://data.iotics.com/nifi/isOperational",
"value": null,
"type": "Literal",
"dataType": "boolean"
} }""";

private static final String MISSING_VALUE_PROP_JSON = """
{ "properties": [ {
"key": "http://data.iotics.com/nifi/isOperational",
"type": "Literal",
"dataType": "boolean"
} }""";

private static final String EMPTY_KEY_PROP_JSON = """
{ "properties": [ {
"key": "",
"value": "something",
"type": "Literal",
"dataType": "boolean"
} }""";

private static final String MISSING_KEY_PROP_JSON = """
{ "properties": [ {
"value": "something",
"type": "Literal",
"dataType": "boolean"
} }""";

private static final String NULL_KEY_PROP_JSON = """
{ "properties": [ {
"key": null,
"value": "something",
"type": "Literal",
"dataType": "boolean"
} }""";

private static final String MISSING_TYPE_PROP_JSON = """
{ "properties": [ {
"key": "http://a.key",
"value": "something",
"dataType": "boolean"
} }""";

private static final String NULL_TYPE_PROP_JSON = """
{ "properties": [ {
"key": "http://a.key",
"value": "something",
"type": null,
"dataType": "boolean"
} }""";

private static final String INVALID_TYPE_PROP_JSON = """
{ "properties": [ {
"key": "http://a.key",
"value": "something",
"type": "this could also be empty",
"dataType": "boolean"
} }""";

private TestRunner testRunner;

@BeforeEach
Expand All @@ -75,20 +147,26 @@ public void missingIdentifierTransitionsToFail() throws IOException {
assertThat(json.get("error").toString(), is(equalTo("invalid twin: missing property http://schema.org/missing_identifier")));
}

@ParameterizedTest
@ValueSource(strings = {
NULL_VALUE_PROP_JSON, MISSING_VALUE_PROP_JSON, EMPTY_KEY_PROP_JSON, MISSING_KEY_PROP_JSON, NULL_KEY_PROP_JSON, MISSING_TYPE_PROP_JSON, NULL_TYPE_PROP_JSON, INVALID_TYPE_PROP_JSON
})
public void wrongJsonTransitionsToFail(String badJsonString) {
testRunner.enqueue(badJsonString);
testRunner.run(1);
//assert the input Q is empty and the flowfile is processed
testRunner.assertQueueEmpty();
List<MockFlowFile> failure = testRunner.getFlowFilesForRelationship(Constants.FAILURE);
MockFlowFile outputFlowfile = failure.getFirst();
String outputFlowfileContent = new String(testRunner.getContentAsByteArray(outputFlowfile));
Gson gson = new Gson();
Map<String, Object> json = (Map<String, Object>) gson.fromJson(outputFlowfileContent, Map.class);
assertThat(json.get("error").toString(), containsString("MalformedJsonException"));
}

@Test
public void invalidJsonTransitionsToFail() {
testRunner.enqueue("""
{
"properties": [
{
"key": "http://data.iotics.com/nifi/isOperational",
"value": "true",
"type": "Literal",
"dataType": "boolean"
},
}
""");
testRunner.enqueue(INVALID_JSON);
testRunner.run(1);
//assert the input Q is empty and the flowfile is processed
testRunner.assertQueueEmpty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public MyProperty(String key, StringLiteral value) {
}

public static MyProperty factory(Property property) {
if(property == null){
throw new IllegalArgumentException("null property");
}
String key = property.getKey();
if (property.hasLiteralValue())
return new MyProperty(key, property.getLiteralValue());
Expand All @@ -32,7 +35,7 @@ public static MyProperty factory(Property property) {
return new MyProperty(key, property.getUriValue());
if (property.hasStringLiteralValue())
return new MyProperty(key, property.getStringLiteralValue());
throw new IllegalArgumentException("invalid property type: " + property);
throw new IllegalArgumentException("invalid property type, missing value: " + property.getKey());
}

public static Value factory(MyValue val) {
Expand All @@ -45,8 +48,15 @@ public static Value factory(MyValue val) {

public static Property factory(MyProperty prop) {
String key = prop.key();
if(key == null) {
throw new IllegalArgumentException("invalid property: missing key. " + prop);
}
Property.Builder pBuilder = Property.newBuilder().setKey(key);
String objValue = prop.value();
if(objValue == null) {
throw new IllegalArgumentException("invalid property: missing value. " + prop);
}

switch (prop.type()) {
case "Uri" -> pBuilder.setUriValue(Uri.newBuilder().setValue(prop.value()).build());
case "StringLiteral" -> pBuilder.setStringLiteralValue(StringLiteral.newBuilder()
Expand Down

0 comments on commit 24f230a

Please sign in to comment.