diff --git a/commons-rest/errors/src/main/java/org/eclipse/kapua/commons/rest/errors/KapuaMaxNumberOfItemsReachedExceptionMapper.java b/commons-rest/errors/src/main/java/org/eclipse/kapua/commons/rest/errors/KapuaMaxNumberOfItemsReachedExceptionMapper.java new file mode 100644 index 00000000000..08cbd994ede --- /dev/null +++ b/commons-rest/errors/src/main/java/org/eclipse/kapua/commons/rest/errors/KapuaMaxNumberOfItemsReachedExceptionMapper.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2024 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 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; + +import org.eclipse.kapua.KapuaMaxNumberOfItemsReachedException; +import org.eclipse.kapua.commons.rest.model.errors.MaxNumberOfItemsReachedExceptionInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Provider +public class KapuaMaxNumberOfItemsReachedExceptionMapper implements ExceptionMapper { + + private static final Logger LOG = LoggerFactory.getLogger(KapuaMaxNumberOfItemsReachedExceptionMapper.class); + private final boolean showStackTrace; + + + @Inject + public KapuaMaxNumberOfItemsReachedExceptionMapper(ExceptionConfigurationProvider exceptionConfigurationProvider) { + this.showStackTrace = exceptionConfigurationProvider.showStackTrace(); + } + + + @Override + public Response toResponse(KapuaMaxNumberOfItemsReachedException kapuaMaxNumberOfItemsReachedException) { + LOG.error(kapuaMaxNumberOfItemsReachedException.getMessage(), kapuaMaxNumberOfItemsReachedException); + return Response + .status(Status.FORBIDDEN) + .entity(new MaxNumberOfItemsReachedExceptionInfo(Status.FORBIDDEN.getStatusCode(), kapuaMaxNumberOfItemsReachedException, showStackTrace)) + .build(); + } +} diff --git a/commons-rest/model/src/main/java/org/eclipse/kapua/commons/rest/model/errors/MaxNumberOfItemsReachedExceptionInfo.java b/commons-rest/model/src/main/java/org/eclipse/kapua/commons/rest/model/errors/MaxNumberOfItemsReachedExceptionInfo.java new file mode 100644 index 00000000000..0768e12fc6b --- /dev/null +++ b/commons-rest/model/src/main/java/org/eclipse/kapua/commons/rest/model/errors/MaxNumberOfItemsReachedExceptionInfo.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2024 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.model.errors; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +import org.eclipse.kapua.KapuaMaxNumberOfItemsReachedException; + +@XmlRootElement(name = "maxNumberOfItemsReachedExceptionInfo") +@XmlAccessorType(XmlAccessType.FIELD) +public class MaxNumberOfItemsReachedExceptionInfo extends ExceptionInfo { + + @XmlElement(name = "entityType") + private String entityType; + + + /** + * Constructor. + * + * @since 2.0.0 + */ + protected MaxNumberOfItemsReachedExceptionInfo() { + super(); + } + + + /** + * Constructor. + * + * @param httpStatusCode The http status code of the response containing this info + * @param kapuaMaxNumberOfItemsReachedException The root exception. + * @since 2.0.0 + */ + public MaxNumberOfItemsReachedExceptionInfo(int httpStatusCode, KapuaMaxNumberOfItemsReachedException kapuaMaxNumberOfItemsReachedException, boolean showStackTrace) { + super(httpStatusCode, kapuaMaxNumberOfItemsReachedException, showStackTrace); + this.entityType = kapuaMaxNumberOfItemsReachedException.getEntityType(); + } + + + /** + * Gets the {@link KapuaMaxNumberOfItemsReachedException#getEntityType()}. + * + * @return The {@link KapuaMaxNumberOfItemsReachedException#getEntityType()}. + * @since 2.0.0 + */ + public String getEntityType() { + return entityType; + } + +} diff --git a/qa/common/src/main/java/org/eclipse/kapua/qa/common/BasicSteps.java b/qa/common/src/main/java/org/eclipse/kapua/qa/common/BasicSteps.java index 1cebf7f2361..2b8399c9b13 100644 --- a/qa/common/src/main/java/org/eclipse/kapua/qa/common/BasicSteps.java +++ b/qa/common/src/main/java/org/eclipse/kapua/qa/common/BasicSteps.java @@ -18,17 +18,6 @@ import java.util.Map; import javax.inject.Inject; -import com.google.common.base.Strings; -import com.google.inject.Singleton; -import io.cucumber.java.After; -import io.cucumber.java.Before; -import io.cucumber.java.DataTableType; -import io.cucumber.java.ParameterType; -import io.cucumber.java.Scenario; -import io.cucumber.java.en.And; -import io.cucumber.java.en.Given; -import io.cucumber.java.en.Then; -import io.cucumber.java.en.When; import org.apache.shiro.SecurityUtils; import org.eclipse.kapua.commons.crypto.setting.CryptoSettingKeys; import org.eclipse.kapua.commons.security.KapuaSecurityUtils; @@ -61,6 +50,17 @@ import org.junit.Assert; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.base.Strings; +import com.google.inject.Singleton; +import io.cucumber.java.After; +import io.cucumber.java.Before; +import io.cucumber.java.DataTableType; +import io.cucumber.java.ParameterType; +import io.cucumber.java.Scenario; +import io.cucumber.java.en.And; +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; @Singleton public class BasicSteps extends TestBase { @@ -88,6 +88,7 @@ public class BasicSteps extends TestBase { private static final String LAST_ACCOUNT_ID = "LastAccountId"; private static final String LAST_USER_ID = "LastUserId"; private static final String EXCEPTION_NAME = "ExceptionName"; + private static final String STATUS_CODE = "StatusCode"; private static final String EXCEPTION_CAUGHT = "ExceptionCaught"; private static final String ASSERT_ERROR_NAME = "AssertErrorName"; private static final String ASSERT_ERROR_CAUGHT = "AssertErrorCaught"; @@ -532,6 +533,12 @@ public void noExceptionCaught() { Assert.assertFalse("An unexpected exception was raised!", exCaught); } + @Then("Response status code match") + public void statusCodeMatch() { + final int statusCode = stepData.contains(STATUS_CODE) ? (int) stepData.get(STATUS_CODE) : -1; + Assert.assertEquals(statusCode, stepData.get("StatusCode")); + } + @Then("I count {int}") public void checkCountResult(int num) { Assert.assertEquals(num, stepData.getCount()); @@ -588,6 +595,12 @@ public void iExpectTheException(String name) { stepData.put(EXCEPTION_NAME, name); } + @And("I expect the response status code {int}") + public void iExpectTheStatusCode(int statusCode) { + stepData.put("StatusCodeExpected", true); + stepData.put(STATUS_CODE, statusCode); + } + @Then("An assertion error was thrown") public void anAssertionErrorWasThrown() { String assertErrorName = stepData.contains(ASSERT_ERROR_NAME) ? (String) stepData.get(ASSERT_ERROR_NAME) : "Unknown"; diff --git a/qa/integration/src/test/resources/features/account/AccountDeviceRegistryService.feature b/qa/integration/src/test/resources/features/account/AccountDeviceRegistryService.feature index ebc2a4e85fc..1e54d182e16 100644 --- a/qa/integration/src/test/resources/features/account/AccountDeviceRegistryService.feature +++ b/qa/integration/src/test/resources/features/account/AccountDeviceRegistryService.feature @@ -56,8 +56,10 @@ Feature: Account Device Registry Service Integration Tests And I create a device with name "Device3" Then No exception was thrown Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 When I create a device with name "Device4" Then An exception was thrown + And Response status code match And I logout Scenario: Creating Devices Under Account That Does Not Allow Devices diff --git a/qa/integration/src/test/resources/features/account/AccountGroupService.feature b/qa/integration/src/test/resources/features/account/AccountGroupService.feature index 90957fe3d7d..f80fc33a698 100644 --- a/qa/integration/src/test/resources/features/account/AccountGroupService.feature +++ b/qa/integration/src/test/resources/features/account/AccountGroupService.feature @@ -54,8 +54,10 @@ Feature: Account Group Service Integration Tests And I create a group with name "Group2" And I create a group with name "Group3" Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 And I create a group with name "Group4" Then An exception was thrown + And Response status code match And I logout Scenario: Creating Groups Under Account That Does Not Allow Groups diff --git a/qa/integration/src/test/resources/features/account/AccountJobService.feature b/qa/integration/src/test/resources/features/account/AccountJobService.feature index 407f35b3aab..364c73376c0 100644 --- a/qa/integration/src/test/resources/features/account/AccountJobService.feature +++ b/qa/integration/src/test/resources/features/account/AccountJobService.feature @@ -57,8 +57,10 @@ Feature: Account Job Service Integration Tests And I create a job with the name "job3" Then No exception was thrown Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 When I create a job with the name "job4" Then An exception was thrown + And Response status code match And I logout Scenario: Creating Jobs Under Account That Does Not Allow Jobs diff --git a/qa/integration/src/test/resources/features/account/AccountRoleService.feature b/qa/integration/src/test/resources/features/account/AccountRoleService.feature index 45b9aaf4b36..6a6ee0032c2 100644 --- a/qa/integration/src/test/resources/features/account/AccountRoleService.feature +++ b/qa/integration/src/test/resources/features/account/AccountRoleService.feature @@ -55,8 +55,10 @@ Feature: Account Role Service Integration Tests And I create role "role2" in account "acc1" And I create role "role3" in account "acc1" Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 When I create role "role4" in account "acc1" Then An exception was thrown + And Response status code match And I logout Scenario: Creating Roles Under Account That Does Not Allow Roles diff --git a/qa/integration/src/test/resources/features/account/AccountServiceCreation.feature b/qa/integration/src/test/resources/features/account/AccountServiceCreation.feature index c4cc727ab66..f695a3b211c 100644 --- a/qa/integration/src/test/resources/features/account/AccountServiceCreation.feature +++ b/qa/integration/src/test/resources/features/account/AccountServiceCreation.feature @@ -217,8 +217,10 @@ Feature: Account Service Tests | integer | maxNumberChildEntities | 0 | Then I select account "acc1" Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 And I create an account with name "acc11", organization name "acc11" and email address "acc11@org.com" Then An exception was thrown + And Response status code match Then I logout Scenario: Creating Sub-accounts When InfiniteChildAccounts Is Set To True And maxNumberChildAccounts Is Set diff --git a/qa/integration/src/test/resources/features/account/AccountTagService.feature b/qa/integration/src/test/resources/features/account/AccountTagService.feature index 4c3adeef6b6..dd7317cdf06 100644 --- a/qa/integration/src/test/resources/features/account/AccountTagService.feature +++ b/qa/integration/src/test/resources/features/account/AccountTagService.feature @@ -55,8 +55,10 @@ Feature: Account Tag Service Integration Tests And I create tag with name "tag2" without description And I create tag with name "tag3" without description Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 When I create tag with name "tag4" without description Then An exception was thrown + And Response status code match And I logout Scenario: Creating Tags Under Account That Does Not Allow Tags diff --git a/qa/integration/src/test/resources/features/account/AccountUserService.feature b/qa/integration/src/test/resources/features/account/AccountUserService.feature index 73a4313e9dc..f211281f0b2 100644 --- a/qa/integration/src/test/resources/features/account/AccountUserService.feature +++ b/qa/integration/src/test/resources/features/account/AccountUserService.feature @@ -55,8 +55,10 @@ Feature: Account User Service Integration Tests And I create user with name "user2" And I create user with name "user3" Given I expect the exception "KapuaMaxNumberOfItemsReachedException" with the text "*" + And I expect the response status code 403 When I create user with name "user4" Then An exception was thrown + And Response status code match And I logout Scenario: Creating Users Under Account That Does Not Allow Users