/* * Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute * Copyright [2016-2017] EMBL-European Bioinformatics Institute * * 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.ensembl.healthcheck.testcase.generic; import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; import org.ensembl.healthcheck.DatabaseRegistryEntry; import org.ensembl.healthcheck.DatabaseType; import org.ensembl.healthcheck.ReportManager; import org.ensembl.healthcheck.Team; import org.ensembl.healthcheck.Species; import org.ensembl.healthcheck.testcase.AbstractTemplatedTestCase; import org.ensembl.healthcheck.testcase.Priority; import org.ensembl.healthcheck.util.DBUtils; import org.ensembl.healthcheck.util.SqlTemplate; public class ProductionAnalysisLogicName extends AbstractTemplatedTestCase { public ProductionAnalysisLogicName() { addToGroup("production"); addToGroup("pre-compara-handover"); addToGroup("post-compara-handover"); addToGroup("post-projection"); setDescription("Check that the content of the analysis logic names in the core databases are subsets of production"); setPriority(Priority.AMBER); setEffect("Discrepancies between tables can cause problems"); setFix("Resync tables"); setTeamResponsible(Team.GENEBUILD); setSecondTeamResponsible(Team.RELEASE_COORDINATOR); } public void types() { removeAppliesToType(DatabaseType.SANGER_VEGA); removeAppliesToType(DatabaseType.VEGA); } @Override protected boolean runTest(DatabaseRegistryEntry dbre) { boolean result = true; Species dbSpecies = dbre.getSpecies(); String species = dbSpecies.toString(); if (species == null || species.equalsIgnoreCase("unknown")) { species = dbre.getAlias(); } String databaseType = dbre.getType().getName(); Set<String> coreLogicNames = getLogicNamesDb(dbre); Set<String> productionLogicNames = getLogicNamesFromProduction(dbre, species, databaseType); Set<String> coreDbVersion = getDbVersionCore(dbre); Set<String> productionDbVersion = getDbVersionProduction(dbre, coreLogicNames); result &= checkHasDbVersion(dbre, productionDbVersion, coreDbVersion, databaseType); result &= checkHasDbVersion(dbre, coreDbVersion, productionDbVersion, "production"); if(!dbre.isMultiSpecies()) { // checks are inappropriate for a multispecies database where individual mappings // are not stored in the production database result &= testForIdentity(dbre, coreLogicNames, productionLogicNames, "production"); result &= testForIdentity(dbre, productionLogicNames, coreLogicNames, databaseType); } return result; } /** * Minuses the elements in the second collection from the first. Anything * remaining in the first collection cannot exist in the second set */ private <T extends CharSequence> boolean testForIdentity(DatabaseRegistryEntry dbre, Collection<T> core, Collection<T> toRemove, String type) { Set<T> missing = new HashSet<T>(core); missing.removeAll(toRemove); if(missing.isEmpty()) { return true; } for(CharSequence name: missing) { String msg = String.format("The logic name '%s' is missing from %s", name, type); ReportManager.problem(this, dbre.getConnection(), msg); } return false; } private <T extends CharSequence> boolean checkHasDbVersion(DatabaseRegistryEntry dbre, Collection<T> core, Collection<T> production, String type) { Set<T> missing = new HashSet<T>(core); missing.removeAll(production); if(missing.isEmpty()) { return true; } for(CharSequence name: missing) { String msg = String.format("Analysis '%s' in %s db should have a dbversion", name, type); ReportManager.problem(this, dbre.getConnection(), msg); } return false; } private Set<String> getLogicNamesDb(DatabaseRegistryEntry dbre) { SqlTemplate t = DBUtils.getSqlTemplate(dbre); String sql = "select logic_name from analysis join analysis_description using (analysis_id)"; List<String> results = t.queryForDefaultObjectList(sql, String.class); return new HashSet<String>(results); } private Set<String> getLogicNamesFromProduction(DatabaseRegistryEntry dbre, String species, String databaseType) { SqlTemplate t = DBUtils.getSqlTemplate(getProductionDatabase()); String sql = "select logic_name from analysis_description ad, species s, analysis_web_data aw where ad.analysis_description_id = aw.analysis_description_id and aw.species_id = s.species_id and s.db_name = '" + species + "' and aw.db_type = '" + databaseType + "' and s.is_current = 1 and ad.is_current = 1"; List<String> results = t.queryForDefaultObjectList(sql, String.class); return new HashSet<String>(results); } private Set<String> getDbVersionCore(DatabaseRegistryEntry dbre) { SqlTemplate t = DBUtils.getSqlTemplate(dbre); String sql = "SELECT logic_name FROM analysis where !isnull(db_version)"; List<String> results = t.queryForDefaultObjectList(sql, String.class); return new HashSet<String>(results); } private Set<String> getDbVersionProduction(DatabaseRegistryEntry dbre, Set<String> analysisList) { SqlTemplate t = DBUtils.getSqlTemplate(getProductionDatabase()); Set<String> results = new HashSet<String>(); for (String analysis : analysisList) { String sql = "SELECT logic_name FROM analysis_description where logic_name = '" + analysis + "' and db_version = 1"; results.addAll(t.queryForDefaultObjectList(sql, String.class)); } return results; } }