Skip to content

Commit

Permalink
Merge branch 'backport-4167' into release-2.0.x
Browse files Browse the repository at this point in the history
  • Loading branch information
Coduz committed Feb 4, 2025
2 parents 7b043f9 + b52cd7f commit 1005e50
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2018, 2022 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eurotech - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua.commons.rest.errors;

import org.eclipse.kapua.kapuaIntegrityConstraintViolationException;
import org.eclipse.kapua.commons.rest.model.errors.ExceptionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
public class KapuaIntegrityConstraintViolationExceptionMapper implements ExceptionMapper<kapuaIntegrityConstraintViolationException> {
private static final Logger LOG = LoggerFactory.getLogger(kapuaIntegrityConstraintViolationException.class);

private static final Status STATUS = Status.CONFLICT;
@Inject
public ExceptionConfigurationProvider exceptionConfigurationProvider;

@Override
public Response toResponse(kapuaIntegrityConstraintViolationException kapuaIntegrityConstraintViolationException) {
final boolean showStackTrace = exceptionConfigurationProvider.showStackTrace();
LOG.error(kapuaIntegrityConstraintViolationException.getMessage(), kapuaIntegrityConstraintViolationException);
return Response
.status(STATUS)
.entity(new ExceptionInfo(STATUS.getStatusCode(), kapuaIntegrityConstraintViolationException, showStackTrace))
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.KapuaIllegalNullArgumentException;
import org.eclipse.kapua.KapuaOptimisticLockingException;
import org.eclipse.kapua.kapuaIntegrityConstraintViolationException;
import org.eclipse.persistence.exceptions.DatabaseException;

import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
import javax.persistence.RollbackException;
import java.sql.SQLIntegrityConstraintViolationException;

/**
* Exception utilities
Expand Down Expand Up @@ -99,6 +101,12 @@ public static KapuaException convertPersistenceException(Exception he) {

}
break;
default: {
if (cve.getInternalException() instanceof SQLIntegrityConstraintViolationException) {
String message = cve.getMessage().contains("FOREIGN KEY") ? "This entity relates to other entities and cannot be deleted." : "";
ee = new kapuaIntegrityConstraintViolationException(message);
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
package org.eclipse.kapua.commons.util;

import java.lang.reflect.Constructor;
import java.sql.SQLIntegrityConstraintViolationException;

import javax.persistence.OptimisticLockException;
import javax.persistence.PersistenceException;
Expand All @@ -22,6 +23,7 @@
import org.eclipse.kapua.KapuaException;
import org.eclipse.kapua.KapuaIllegalNullArgumentException;
import org.eclipse.kapua.KapuaOptimisticLockingException;
import org.eclipse.kapua.kapuaIntegrityConstraintViolationException;
import org.eclipse.kapua.qa.markers.junit.JUnitTests;

import org.eclipse.persistence.exceptions.DatabaseException;
Expand Down Expand Up @@ -111,9 +113,21 @@ public void convertPersistenceDatabaseExceptionTest() {
Mockito.when(mockedDatabaseException.getInternalException()).thenReturn(mockedDatabaseException);
Assert.assertEquals("ComparisonFailure not expected for: " + exception,kapuaException.toString(), KapuaExceptionUtils.convertPersistenceException(exception).toString());

Mockito.verify(mockedDatabaseException, Mockito.times(12)).getInternalException();
Mockito.verify(mockedDatabaseException, Mockito.times(12)).getMessage();
Mockito.verify(mockedDatabaseException, Mockito.times(13)).getErrorCode();
//SQL foreign key constraint violation
SQLIntegrityConstraintViolationException mockedDatabaseException2 = Mockito.mock(SQLIntegrityConstraintViolationException.class);
Mockito.when(mockedDatabaseException.getInternalException()).thenReturn(mockedDatabaseException2);
Mockito.when(mockedDatabaseException.getMessage()).thenReturn("FOREIGN KEY");
kapuaIntegrityConstraintViolationException ke = new kapuaIntegrityConstraintViolationException("This entity relates to other entities and cannot be deleted.");
Assert.assertEquals("ComparisonFailure not expected for: " + exception,ke.toString(), KapuaExceptionUtils.convertPersistenceException(exception).toString());

//generic SQL constraint violation
Mockito.when(mockedDatabaseException.getMessage()).thenReturn("another message different from for3ign key but always SQL integrity constraint violation stuff");
kapuaIntegrityConstraintViolationException ke2 = new kapuaIntegrityConstraintViolationException("");
Assert.assertEquals("ComparisonFailure not expected for: " + exception,ke2.toString(), KapuaExceptionUtils.convertPersistenceException(exception).toString());

Mockito.verify(mockedDatabaseException, Mockito.times(15)).getInternalException();
Mockito.verify(mockedDatabaseException, Mockito.times(14)).getMessage();
Mockito.verify(mockedDatabaseException, Mockito.times(15)).getErrorCode();
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Scenario: Initialize test environment
| test_name_1 | read,write |
Then A domain was created
And The domain matches the creator
Given I expect the exception "KapuaException" with the text "Error during Persistence Operation"
Given I expect the exception "kapuaIntegrityConstraintViolationException" with the text "Entity constraint violation error."
When I create the domain
| name | actions |
| test_name_1 | read,write |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ Feature: User Coupling
And I set the reserved user for the connection from device "device-1" in account "test-acc-1" to "test-user-1"
Then I set the user coupling mode for the connection from device "device-2" in account "test-acc-1" to "STRICT"
# Try to set a duplicate reserved user
Given I expect the exception "KapuaException" with the text "Error during Persistence Operation"
Given I expect the exception "kapuaIntegrityConstraintViolationException" with the text "Entity constraint violation error."
When I set the reserved user for the connection from device "device-2" in account "test-acc-1" to "test-user-1"
Then An exception was thrown
# Reserved users must be unique!
Expand Down Expand Up @@ -874,7 +874,7 @@ Feature: User Coupling
And I set the reserved user for the connection from device "device-1" in account "test-acc-1" to "test-user-1"
Then I set the user coupling mode for the connection from device "device-2" in account "test-acc-1" to "STRICT"
# Try to set a duplicate reserved user
Given I expect the exception "KapuaException" with the text "Error during Persistence Operation"
Given I expect the exception "kapuaIntegrityConstraintViolationException" with the text "Entity constraint violation error."
When I set the reserved user for the connection from device "device-2" in account "test-acc-1" to "test-user-1"
Then An exception was thrown
# Reserved users must be unique!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,13 @@ public enum KapuaErrorCodes implements KapuaErrorCode {
* Some parsing failed for some reason
* @since 2.0.0
*/
PARSING_ERROR
PARSING_ERROR,

/**
* Sql integrity has been violated for some reason
* @since 2.0.0
*/
DATASTORE_INTEGRITY_VIOLATION


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2016, 2022 Eurotech and/or its affiliates and others
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Eurotech - initial API and implementation
*******************************************************************************/
package org.eclipse.kapua;

/**
* kapuaIntegrityConstraintViolationException is thrown when the integrity constraints of the underlying datastore have been violated
*
* @since 2.0.0
*/
public class kapuaIntegrityConstraintViolationException extends KapuaException {

/**
* Constructor.
*
* @since 2.0.0
*/
public kapuaIntegrityConstraintViolationException() {
super(KapuaErrorCodes.DATASTORE_INTEGRITY_VIOLATION);
}

/**
* Constructor.
*
* @since 2.0.0
*/
public kapuaIntegrityConstraintViolationException(String detailedMessage) {
super(KapuaErrorCodes.DATASTORE_INTEGRITY_VIOLATION, detailedMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ UNAUTHENTICATED=No authenticated Subject found in context.
# Deprecated codes
USER_ALREADY_RESERVED_BY_ANOTHER_CONNECTION=This user is already reserved for another connection. Please select different user for this connection.
DEVICE_NOT_FOUND=The selected devices were not found. Please refresh device list.
PARSING_ERROR=Error while parsing: {0}
PARSING_ERROR=Error while parsing: {0}
DATASTORE_INTEGRITY_VIOLATION=Entity constraint violation error. {0}

0 comments on commit 1005e50

Please sign in to comment.