Browse Source

HTTP status 409 (Conflict) on EntityVersionMismatchException

pull/11112/head
ViacheslavKlimov 2 years ago
parent
commit
8a3f99d651
  1. 3
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  2. 1
      application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java
  3. 16
      application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java
  4. 24
      common/data/src/main/java/org/thingsboard/server/common/data/exception/EntityVersionMismatchException.java
  5. 1
      common/data/src/main/java/org/thingsboard/server/common/data/exception/ThingsboardErrorCode.java
  6. 3
      dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java

3
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -64,6 +64,7 @@ import org.thingsboard.server.common.data.asset.AssetProfile;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.exception.EntityVersionMismatchException;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AlarmCommentId;
@ -381,6 +382,8 @@ public abstract class BaseController {
log.warn("Database error: {} - {}", errorType, ExceptionUtils.getRootCauseMessage(exception));
}
return new ThingsboardException("Database error", ThingsboardErrorCode.GENERAL);
} else if (exception instanceof EntityVersionMismatchException) {
return new ThingsboardException(exception.getMessage(), exception, ThingsboardErrorCode.CONFLICT);
}
return new ThingsboardException(exception.getMessage(), exception, ThingsboardErrorCode.GENERAL);
}

1
application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java

@ -91,6 +91,7 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand
errorCodeToStatusMap.put(ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS);
errorCodeToStatusMap.put(ThingsboardErrorCode.TOO_MANY_UPDATES, HttpStatus.TOO_MANY_REQUESTS);
errorCodeToStatusMap.put(ThingsboardErrorCode.SUBSCRIPTION_VIOLATION, HttpStatus.FORBIDDEN);
errorCodeToStatusMap.put(ThingsboardErrorCode.CONFLICT, HttpStatus.CONFLICT);
}
private static ThingsboardErrorCode statusToErrorCode(HttpStatus status) {

16
application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java

@ -1585,6 +1585,22 @@ public class DeviceControllerTest extends AbstractControllerTest {
Assert.assertEquals(newAttributeValue, actualAttribute.get("value"));
}
@Test
public void testSaveDeviceWithOutdatedVersion() throws Exception {
Device device = createDevice("Device v1");
assertThat(device.getVersion()).isOne();
device.setName("Device v2");
device = doPost("/api/device", device, Device.class);
assertThat(device.getVersion()).isEqualTo(2);
device.setVersion(1);
String response = doPost("/api/device", device).andExpect(status().isConflict())
.andReturn().getResponse().getContentAsString();
assertThat(JacksonUtil.toJsonNode(response).get("message").asText())
.containsIgnoringCase("already changed by someone else");
}
private Device createDevice(String name) {
Device device = new Device();
device.setName(name);

24
common/data/src/main/java/org/thingsboard/server/common/data/exception/EntityVersionMismatchException.java

@ -0,0 +1,24 @@
/**
* Copyright © 2016-2024 The Thingsboard Authors
*
* 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.thingsboard.server.common.data.exception;
public class EntityVersionMismatchException extends RuntimeException {
public EntityVersionMismatchException(String message, Throwable cause) {
super(message, cause);
}
}

1
common/data/src/main/java/org/thingsboard/server/common/data/exception/ThingsboardErrorCode.java

@ -29,6 +29,7 @@ public enum ThingsboardErrorCode {
ITEM_NOT_FOUND(32),
TOO_MANY_REQUESTS(33),
TOO_MANY_UPDATES(34),
CONFLICT(35),
SUBSCRIPTION_VIOLATION(40),
PASSWORD_VIOLATION(45);

3
dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractDao.java

@ -27,6 +27,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.thingsboard.server.common.data.HasVersion;
import org.thingsboard.server.common.data.exception.EntityVersionMismatchException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.Dao;
import org.thingsboard.server.dao.DaoUtil;
@ -78,7 +79,7 @@ public abstract class JpaAbstractDao<E extends BaseEntity<D>, D>
try {
entity = doSave(entity, isNew);
} catch (OptimisticLockException e) {
throw new IllegalStateException("The entity was already changed by someone else");
throw new EntityVersionMismatchException("The entity was already changed by someone else", e);
}
return DaoUtil.getData(entity);
}

Loading…
Cancel
Save