@Test public void translateCheckConstraintViolation() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getTable()).thenReturn("entity"); when(serverErrorMessage.getConstraint()).thenReturn("entity_column_chk"); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateCheckConstraintViolation( new PSQLException(serverErrorMessage)); assertEquals(e.getMessage(), "Unknown enum value for attribute 'column' of entity 'entity'."); }
@Test public void translateInvalidIntegerExceptionDate() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getMessage()) .thenReturn("invalid input syntax for type date: \"str1\""); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateInvalidIntegerException( new PSQLException(serverErrorMessage)); assertEquals(e.getMessage(), "Value [str1] of this entity attribute is not of type [DATE]."); }
@Test public void translateDependentObjectsStillExistNoDoubleQuotes() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("2BP01"); when(serverErrorMessage.getDetail()) .thenReturn("constraint my_foreign_key_constraint on table xxx depends on table yyy"); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateDependentObjectsStillExist( new PSQLException(serverErrorMessage)); assertEquals(e.getMessage(), "Cannot delete entity 'xxx' because entity 'yyy' depends on it."); }
@Test public void translateUndefinedColumnException() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("42703"); when(serverErrorMessage.getMessage()) .thenReturn("Undefined column: 7 ERROR: column \"test\" does not exist"); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateUndefinedColumnException( new PSQLException(serverErrorMessage)); assertEquals(e.getMessage(), "Undefined column: 7 ERROR: column \"test\" does not exist"); }
@Test public void testWrongIntValue() throws IOException { try { importer.importEntities( loadTestFile("wrong-int-type.xlsx"), DatabaseAction.ADD_UPDATE_EXISTING); fail("Should have thrown MolgenisValidationException"); } catch (MolgenisValidationException e) { assertEquals(e.getViolations().size(), 1); assertEquals(e.getViolations().iterator().next().getViolatedAttribute().getName(), "age"); assertEquals(e.getViolations().iterator().next().getRownr(), 1); } }
@Test public void testXrefCircular() throws IOException { try { importer.importEntities( loadTestFile("xref-circular.xlsx"), DatabaseAction.ADD_UPDATE_EXISTING); fail("Should have thrown MolgenisValidationException"); } catch (MolgenisValidationException e) { assertEquals(e.getViolations().size(), 2); assertEquals(e.getViolations().iterator().next().getViolatedAttribute().getName(), "father"); assertEquals(e.getViolations().iterator().next().getRownr(), 1); } }
@Test public void translateReadonlyViolationNoDoubleQuotes() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getMessage()) .thenReturn("Updating read-only column attr of table entity with id [abc] is not allowed"); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateReadonlyViolation( new PSQLException(serverErrorMessage)); assertEquals( e.getMessage(), "Updating read-only attribute 'attr' of entity 'entity' with id 'abc' is not allowed."); }
@Test public void translateNotNullViolationNoDoubleQuotes() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("23502"); when(serverErrorMessage.getTable()).thenReturn("xxx"); when(serverErrorMessage.getMessage()) .thenReturn("null value in column yyy violates not-null constraint"); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateNotNullViolation( new PSQLException(serverErrorMessage)); assertEquals(e.getMessage(), "The attribute 'yyy' of entity 'xxx' can not be null."); }
@Test public void translateUniqueKeyViolation() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("23505"); when(serverErrorMessage.getTable()).thenReturn("mytable"); when(serverErrorMessage.getDetail()).thenReturn("Key (mycolumn)=(myvalue) already exists."); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateUniqueKeyViolation( new PSQLException(serverErrorMessage)); assertEquals( e.getMessage(), "Duplicate value 'myvalue' for unique attribute 'mycolumn' from entity 'mytable'."); }
@Test public void translateForeignKeyViolation() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("23503"); when(serverErrorMessage.getTable()).thenReturn("mytable"); when(serverErrorMessage.getDetail()).thenReturn("... (mycolumn) ... (myvalue) ..."); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateForeignKeyViolation( new PSQLException(serverErrorMessage)); assertEquals( e.getMessage(), "Unknown xref value 'myvalue' for attribute 'mycolumn' of entity 'mytable'."); }
@Test public void translateDependentObjectsStillExistMultipleDependentTables() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("2BP01"); when(serverErrorMessage.getDetail()) .thenReturn( "constraint my_foreign_key_constraint on table \"myTable\" depends on table \"myDependentTable\"\nconstraint myOther_foreign_key_constraint on table \"myTable\" depends on table \"myOtherDependentTable\""); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateDependentObjectsStillExist( new PSQLException(serverErrorMessage)); assertEquals( e.getMessage(), "Cannot delete entity 'myTable' because entities 'myDependentTable, myOtherDependentTable' depend on it."); }
@Test public void translateForeignKeyViolationStillReferenced() { ServerErrorMessage serverErrorMessage = mock(ServerErrorMessage.class); when(serverErrorMessage.getSQLState()).thenReturn("23503"); when(serverErrorMessage.getTable()).thenReturn("mytable"); when(serverErrorMessage.getDetail()) .thenReturn("Key (mycolumn)=(myvalue) is still referenced from table \"mytable\""); //noinspection ThrowableResultOfMethodCallIgnored MolgenisValidationException e = PostgreSqlExceptionTranslator.translateForeignKeyViolation( new PSQLException(serverErrorMessage)); assertEquals( e.getMessage(), "Value 'myvalue' for attribute 'mycolumn' is referenced by entity 'mytable'."); }
@ExceptionHandler(MolgenisValidationException.class) @ResponseStatus(BAD_REQUEST) @ResponseBody public ErrorMessageResponse handleValidationException(MolgenisValidationException e) { LOG.info("Validation exception occurred.", e); return new ErrorMessageResponse(new ErrorMessage(e.getMessage())); }
@Override @Transactional(rollbackFor = IOException.class) public EntityImportReport doImport( RepositoryCollection repositories, DatabaseAction databaseAction) throws IOException { // All new repository identifiers List<String> newRepoIdentifiers = new ArrayList<String>(); // First import entities, the data sheets are ignored in the entitiesimporter EntityImportReport importReport = entitiesImporter.importEntities(repositories, databaseAction); // RULE: Feature can only belong to one Protocol in a DataSet. Check it (see issue #1136) checkFeatureCanOnlyBelongToOneProtocolForOneDataSet(); // Import data sheets for (String name : repositories.getEntityNames()) { Repository repository = repositories.getRepositoryByEntityName(name); if (repository.getName().startsWith(DATASET_SHEET_PREFIX)) { // Import DataSet sheet, create new OmxRepository String identifier = repository.getName().substring(DATASET_SHEET_PREFIX.length()); if (!dataService.hasRepository(identifier)) { dataService.addRepository( new AggregateableCrudRepositorySecurityDecorator( new OmxRepository(dataService, searchService, identifier, entityValidator))); newRepoIdentifiers.add(identifier); DataSet dataSet = dataService.findOne( DataSet.ENTITY_NAME, new QueryImpl().eq(DataSet.IDENTIFIER, identifier), DataSet.class); List<Protocol> protocols = ProtocolUtils.getProtocolDescendants(dataSet.getProtocolUsed()); List<ObservableFeature> categoricalFeatures = new ArrayList<ObservableFeature>(); for (Protocol protocol : protocols) { List<ObservableFeature> observableFeatures = protocol.getFeatures(); if (observableFeatures != null) { for (ObservableFeature observableFeature : observableFeatures) { String dataType = observableFeature.getDataType(); FieldType type = MolgenisFieldTypes.getType(dataType); if (type.getEnumType() == FieldTypeEnum.CATEGORICAL) { categoricalFeatures.add(observableFeature); } } } } for (ObservableFeature categoricalFeature : categoricalFeatures) { if (!dataService.hasRepository( OmxLookupTableEntityMetaData.createOmxLookupTableEntityMetaDataName( categoricalFeature.getIdentifier()))) { dataService.addRepository( new OmxLookupTableRepository( dataService, categoricalFeature.getIdentifier(), queryResolver)); newRepoIdentifiers.add( OmxLookupTableEntityMetaData.createOmxLookupTableEntityMetaDataName( categoricalFeature.getIdentifier())); } } } // Check if all column names in the excel sheet exist as attributes of the entity Set<ConstraintViolation> violations = Sets.newLinkedHashSet(); EntityMetaData meta = dataService.getEntityMetaData(identifier); for (AttributeMetaData attr : repository.getEntityMetaData().getAttributes()) { if (meta.getAttribute(attr.getName()) == null) { String message = String.format( "Unknown attributename '%s' for entity '%s'. Sheet: '%s'", attr.getName(), meta.getName(), repository.getName()); violations.add(new ConstraintViolation(message, attr.getName(), null, null, meta, 0)); } } if (!violations.isEmpty()) { throw new MolgenisValidationException(violations); } // Import data into new OmxRepository try { dataService.add(identifier, repository); } catch (MolgenisValidationException e) { // Add sheet info for (ConstraintViolation violation : e.getViolations()) { if (violation.getRownr() > 0) { // Rownr +1 for header violation.setImportInfo( String.format( "Sheet: '%s', row: %d", repository.getName(), violation.getRownr() + 1)); } else { violation.setImportInfo(String.format("Sheet: '%s'", repository.getName())); } } for (String newRepoIdentifier : newRepoIdentifiers) { dataService.removeRepository(newRepoIdentifier); } throw e; } int count = (int) RepositoryUtils.count(repository); importReport.addEntityCount(identifier, count); importReport.addNrImported(count); } } return importReport; }