/* * Copyright 2015 Open mHealth * * 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. */ package org.openmhealth.schema.service; import com.github.fge.jackson.JacksonUtils; import com.github.fge.jsonschema.core.exceptions.ProcessingException; import com.github.fge.jsonschema.core.report.LogLevel; import com.github.fge.jsonschema.core.report.ProcessingMessage; import com.github.fge.jsonschema.core.report.ProcessingReport; import org.openmhealth.schema.domain.DataFile; import org.openmhealth.schema.domain.SchemaFile; import org.openmhealth.schema.domain.ValidationSummary; import org.openmhealth.schema.domain.omh.SchemaVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.Collection; import static org.openmhealth.schema.domain.DataFileValidationResult.PASS; /** * A primitive validation service implementation. This implementation currently logs failures, but will eventually * return reports that can be rendered in a browser. * * @author Emerson Farrugia */ @Service public class ValidationServiceImpl implements ValidationService { private static final Logger log = LoggerFactory.getLogger(ValidationServiceImpl.class); @Override public ValidationSummary validateDataFiles(Collection<SchemaFile> schemaFiles, Collection<DataFile> dataFiles) { ValidationSummary validationSummary = new ValidationSummary(); try { for (SchemaFile schemaFile : schemaFiles) { log.debug(schemaFile.getSchemaId().toString()); for (DataFile dataFile : dataFiles) { if (!dataFile.getSchemaId().getName().equals(schemaFile.getSchemaId().getName())) { continue; } SchemaVersion dataFileVersion = dataFile.getSchemaId().getVersion(); SchemaVersion schemaFileVersion = schemaFile.getSchemaId().getVersion(); if (dataFileVersion.getMajor() != schemaFileVersion.getMajor()) { continue; } // a data point conforms to the schema listed in its header and newer minor versions of that schema if (dataFileVersion.getMinor() > schemaFileVersion.getMinor()) { continue; } ProcessingReport report = schemaFile.getJsonSchema().validate(dataFile.getData()); validationSummary.incrementAttempted(); if (dataFile.getExpectedValidationResult() == PASS) { if (report.isSuccess()) { log.debug("> {} -- OK (passed as expected)", dataFile.getName()); validationSummary.incrementSucceeded(); } else { if (!log.isDebugEnabled()) { log.warn(schemaFile.getSchemaId().toString()); } log.error("> {} -- NOT OK (failed but was expected to pass)", dataFile.getName()); for (ProcessingMessage processingMessage : report) { if (processingMessage.getLogLevel() != LogLevel.WARNING) { log.error(JacksonUtils.prettyPrint(processingMessage.asJson())); } } validationSummary.incrementFailed(); } } else { if (!report.isSuccess()) { log.debug("> {} -- OK (failed as expected)", dataFile.getName()); validationSummary.incrementSucceeded(); } else { if (!log.isDebugEnabled()) { log.warn(schemaFile.getSchemaId().toString()); } log.error("> {} -- NOT OK (passed but was expected to fail)", dataFile.getName()); for (ProcessingMessage processingMessage : report) { if (processingMessage.getLogLevel() != LogLevel.WARNING) { log.error(JacksonUtils.prettyPrint(processingMessage.asJson())); } } validationSummary.incrementFailed(); } } } } } catch (ProcessingException e) { throw new RuntimeException("The specified data files and schemas can't be validated.", e); } return validationSummary; } }