@NoArgsConstructor\r
public class MeasFilterConfig {\r
\r
+ @GSONRequired\r
@SerializedName("filters")\r
public List<Filter> filters;\r
\r
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
+import lombok.NonNull;
+
import java.lang.reflect.Field;
import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
/**
@Override
public T deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
T obj = new Gson().fromJson(jsonElement, type);
- for (Field field : obj.getClass().getDeclaredFields()) {
- if (field.getAnnotation(GSONRequired.class) != null) {
- field.setAccessible(true);
- try {
- if (field.get(obj) == null) {
- throw new JsonParseException(String.format("Field: '%s', is required but not found.", field.getName()));
- }
- } catch (Exception exception) {
- throw new JsonParseException("Failed to check fields.", exception);
- }
+ validateRequiredFields(obj.getClass().getDeclaredFields(), obj);
+ return obj;
+ }
+
+ private void validateRequiredFields(@NonNull Field[] fields, @NonNull Object pojo) {
+ if (pojo instanceof List) {
+ final List<?> pojoList = (List<?>) pojo;
+ for (final Object pojoListPojo : pojoList) {
+ validateRequiredFields(pojoListPojo.getClass().getDeclaredFields(), pojoListPojo);
}
}
- return obj;
+ Stream.of(fields)
+ .filter(field -> field.getAnnotation(GSONRequired.class) != null)
+ .forEach(field -> {
+ try {
+ field.setAccessible(true);
+ Object fieldObj = Optional.ofNullable(field.get(pojo))
+ .orElseThrow(()-> new JsonParseException(
+ String.format("Field '%s' in class '%s' is required but not found.",
+ field.getName(), pojo.getClass().getSimpleName())));
+
+ Field[] declaredFields = fieldObj.getClass().getDeclaredFields();
+ validateRequiredFields(declaredFields, fieldObj);
+ }
+ catch (Exception exception) {
+ throw new JsonParseException("Failed to check fields.", exception);
+ }
+ });
}
}
import java.io.IOException;\r
import java.io.InputStreamReader;\r
import java.net.UnknownHostException;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
\r
import static org.junit.Assert.assertEquals;\r
import static org.junit.Assert.assertTrue;\r
import org.powermock.modules.junit4.PowerMockRunner;\r
\r
import com.google.gson.Gson;\r
+import com.google.gson.JsonObject;\r
+import com.google.gson.JsonParser;\r
\r
import ch.qos.logback.classic.spi.ILoggingEvent;\r
import ch.qos.logback.core.read.ListAppender;\r
\r
@Test\r
public void mapper_parse_valid_json_missing_attributes() throws Exception {\r
- when(sender.send(anyString())).thenReturn(getFileContents("incomplete_mapper_config.json"));\r
- assertThrows(MapperConfigException.class, this::getMapperConfig);\r
+ Map<String,String> invalidConfigs = new HashMap<>();\r
+ invalidConfigs.put("streams_subscribes", "{}");\r
+ invalidConfigs.put("streams_publishes", "{}");\r
+ invalidConfigs.put("streams_publishes", null);\r
+ invalidConfigs.remove("streams_publishes");\r
+ invalidConfigs.put("pm-mapper-filter", null);\r
+ invalidConfigs.put("pm-mapper-filter", "{}");\r
+ invalidConfigs.put("pm-mapper-filter", "{ \"filters\": null},");\r
+ invalidConfigs.put("pm-mapper-filter", "{ \"filters\": [{\"pmDefVsn\": \"V9\"}] },");\r
+\r
+ invalidConfigs.forEach( (k,v) -> {\r
+ try {\r
+ when(sender.send(anyString())).thenReturn( getInvalidConfig(k,v));\r
+ assertThrows(MapperConfigException.class, this::getMapperConfig);\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ });\r
}\r
\r
private MapperConfig getMapperConfig()\r
return fileAsString;\r
}\r
\r
+ private String getInvalidConfig(String validKey, String invalidValue) {\r
+ JsonObject invalidConfigJson = new JsonParser().parse(validMapperConfig).getAsJsonObject();\r
+ invalidConfigJson.addProperty(validKey, invalidValue);\r
+ return invalidConfigJson.toString();\r
+ }\r
+\r
}\r
+++ /dev/null
-{\r
- "_comment": "This mapper config is missing streams_subscribes",\r
- "pm-mapper-filter": {\r
- "filters": "{[]}"\r
- },\r
- "3GPP.schema.file": "{\"3GPP_Schema\":\"./etc/3GPP_relaxed_schema.xsd\"}",\r
- "streams_subscribes": null,\r
- "streams_publishes": {\r
- "pm_mapper_handle_out": {\r
- "type": "message_router",\r
- "aaf_password": null,\r
- "dmaap_info": {\r
- "topic_url": "https://we-are-message-router.us:3905/events/some-topic",\r
- "client_role": null,\r
- "location": null,\r
- "client_id": null\r
- },\r
- "aaf_username": null\r
- }\r
- },\r
- "some parameter": "unauthenticated.PM_VES_OUTPUT",\r
- "some field": "1",\r
- "services_calls": {}\r
-}
\ No newline at end of file