From 4dcffc8b96a0b862cf9e79fd4bf2661e17ca5cae Mon Sep 17 00:00:00 2001 From: "emmanuel.duchastenier@bonitasoft.com" Date: Fri, 13 Sep 2024 09:36:54 +0200 Subject: [PATCH] feat(case counters): implement Subscription API (#3140) * community code real implementation for Community counters + unit tests on Engine API + Rest controller * implement SP version of PlatformInformationAPI Relates to https://bonitasoft.atlassian.net/browse/BPM-242 --- .../engine/api/TenantAPIAccessor.java | 4 +- .../api/platform/PlatformInformationAPI.java | 5 +- .../platform/PlatformInformationAPIImpl.java | 22 +++++-- .../execution/ProcessStarterVerifier.java | 9 +++ .../execution/ProcessStarterVerifierImpl.java | 7 ++- .../engine/service/ServiceAccessor.java | 3 + .../service/impl/SpringServiceAccessor.java | 6 ++ .../PlatformInformationAPIImplTest.java | 53 +++++++++++++++++ bpm/bonita-web-server/build.gradle | 15 +++-- .../server/api/AbstractRESTController.java | 9 --- ....java => SystemInformationController.java} | 20 ++++++- .../SystemInformationControllerTest.java | 58 +++++++++++++++++++ .../dynamic-permissions-checks.properties | 2 + 13 files changed, 186 insertions(+), 27 deletions(-) create mode 100644 bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImplTest.java rename bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/{PlatformInformationController.java => SystemInformationController.java} (63%) create mode 100644 bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationControllerTest.java diff --git a/bpm/bonita-client/src/main/java/org/bonitasoft/engine/api/TenantAPIAccessor.java b/bpm/bonita-client/src/main/java/org/bonitasoft/engine/api/TenantAPIAccessor.java index 9365158802d..519ed39342d 100644 --- a/bpm/bonita-client/src/main/java/org/bonitasoft/engine/api/TenantAPIAccessor.java +++ b/bpm/bonita-client/src/main/java/org/bonitasoft/engine/api/TenantAPIAccessor.java @@ -134,8 +134,8 @@ public static MaintenanceAPI getMaintenanceAPI(final APISession session) return getAPI(MaintenanceAPI.class, session); } - public static PlatformInformationAPI getPlatformInformationAPI() + public static PlatformInformationAPI getPlatformInformationAPI(final APISession session) throws ServerAPIException, BonitaHomeNotSetException, UnknownAPITypeException { - return getAPI(PlatformInformationAPI.class); + return getAPI(PlatformInformationAPI.class, session); } } diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/platform/PlatformInformationAPI.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/platform/PlatformInformationAPI.java index 28d66ec45ac..29d5041fbcd 100644 --- a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/platform/PlatformInformationAPI.java +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/platform/PlatformInformationAPI.java @@ -15,11 +15,10 @@ import java.util.Map; -import org.bonitasoft.engine.api.NoSessionRequired; +import org.bonitasoft.engine.platform.PlatformNotFoundException; -@NoSessionRequired public interface PlatformInformationAPI { - Map getPlatformInformation(); + Map getPlatformInformation() throws PlatformNotFoundException; } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImpl.java index 746ec79c1c2..2f54c6c3eda 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImpl.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImpl.java @@ -13,10 +13,15 @@ **/ package org.bonitasoft.engine.api.impl.platform; +import static java.lang.String.valueOf; +import static org.bonitasoft.engine.execution.ProcessStarterVerifierImpl.LIMIT; + import java.util.Map; import org.bonitasoft.engine.api.impl.AvailableInMaintenanceMode; import org.bonitasoft.engine.api.platform.PlatformInformationAPI; +import org.bonitasoft.engine.execution.ProcessStarterVerifier; +import org.bonitasoft.engine.service.ServiceAccessorSingleton; /** * Provides runtime information about the platform. @@ -28,12 +33,21 @@ @AvailableInMaintenanceMode public class PlatformInformationAPIImpl implements PlatformInformationAPI { + private final ProcessStarterVerifier processStarterVerifier; + + public PlatformInformationAPIImpl() { + this.processStarterVerifier = ServiceAccessorSingleton.getInstance().getProcessStarterVerifier(); + } + + protected PlatformInformationAPIImpl(ProcessStarterVerifier processStarterVerifier) { + this.processStarterVerifier = processStarterVerifier; + } + @Override public Map getPlatformInformation() { return Map.of( - "edition", "subscription", - "caseCounterLimit", "75", - "caseCounter", "68", - "subscriptionStartTimestamp", "1440806400000"); + "edition", "community", + "caseCounter", valueOf(processStarterVerifier.getCurrentNumberOfStartedProcessInstances()), + "caseCounterLimit", valueOf(LIMIT)); } } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifier.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifier.java index 814af4fa309..4a70f186db3 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifier.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifier.java @@ -28,4 +28,13 @@ public interface ProcessStarterVerifier { * @throws SProcessInstanceCreationException if the process is not in a valid state to start */ void verify(SProcessInstance processInstance) throws SProcessInstanceCreationException; + + /** + * Get the current number of started process instances. + * + * @return -1 if non relevant in this context + */ + default long getCurrentNumberOfStartedProcessInstances() { + return -1; + } } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifierImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifierImpl.java index 0315a26f7b1..ef3886ea468 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifierImpl.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/execution/ProcessStarterVerifierImpl.java @@ -59,7 +59,7 @@ public class ProcessStarterVerifierImpl implements ProcessStarterVerifier { private final List counters = Collections.synchronizedList(new ArrayList<>()); @Autowired - ProcessStarterVerifierImpl(PlatformRetriever platformRetriever, + public ProcessStarterVerifierImpl(PlatformRetriever platformRetriever, PlatformInformationService platformInformationService, TransactionService transactionService, ProcessInstanceService processInstanceService) throws Exception { @@ -139,6 +139,11 @@ List readCounters() { } } + @Override + public long getCurrentNumberOfStartedProcessInstances() { + return counters.size(); + } + String encryptDataBeforeSendingToDatabase(List counters) throws IOException { return encrypt(OBJECT_MAPPER.writeValueAsBytes(counters)); } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/ServiceAccessor.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/ServiceAccessor.java index ae58dd34df6..98657a0d682 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/ServiceAccessor.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/ServiceAccessor.java @@ -59,6 +59,7 @@ import org.bonitasoft.engine.execution.FlowNodeExecutor; import org.bonitasoft.engine.execution.ProcessExecutor; import org.bonitasoft.engine.execution.ProcessInstanceInterruptor; +import org.bonitasoft.engine.execution.ProcessStarterVerifier; import org.bonitasoft.engine.execution.archive.BPMArchiverService; import org.bonitasoft.engine.execution.event.EventsHandler; import org.bonitasoft.engine.execution.state.FlowNodeStateManager; @@ -311,4 +312,6 @@ public interface ServiceAccessor { PlatformRetriever getPlatformRetriever(); InstallationService getInstallationService(); + + ProcessStarterVerifier getProcessStarterVerifier(); } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringServiceAccessor.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringServiceAccessor.java index 8f7916fc3f2..8cfdc85c3bd 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringServiceAccessor.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringServiceAccessor.java @@ -60,6 +60,7 @@ import org.bonitasoft.engine.execution.FlowNodeExecutor; import org.bonitasoft.engine.execution.ProcessExecutor; import org.bonitasoft.engine.execution.ProcessInstanceInterruptor; +import org.bonitasoft.engine.execution.ProcessStarterVerifier; import org.bonitasoft.engine.execution.archive.BPMArchiverService; import org.bonitasoft.engine.execution.event.EventsHandler; import org.bonitasoft.engine.execution.state.FlowNodeStateManager; @@ -644,4 +645,9 @@ public PlatformRetriever getPlatformRetriever() { public InstallationService getInstallationService() { return beanAccessor.getService(InstallationService.class); } + + @Override + public ProcessStarterVerifier getProcessStarterVerifier() { + return beanAccessor.getService(ProcessStarterVerifier.class); + } } diff --git a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImplTest.java b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImplTest.java new file mode 100644 index 00000000000..f5f6c90dd95 --- /dev/null +++ b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/platform/PlatformInformationAPIImplTest.java @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2024 Bonitasoft S.A. + * Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble + * This library is free software; you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation + * version 2.1 of the License. + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + * Floor, Boston, MA 02110-1301, USA. + **/ +package org.bonitasoft.engine.api.impl.platform; + +import static java.lang.String.valueOf; +import static org.assertj.core.api.Assertions.assertThat; +import static org.bonitasoft.engine.execution.ProcessStarterVerifierImpl.LIMIT; +import static org.mockito.Mockito.doReturn; + +import java.util.Map; + +import org.bonitasoft.engine.execution.ProcessStarterVerifier; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class PlatformInformationAPIImplTest { + + @Mock + private ProcessStarterVerifier processStarterVerifier; + + @InjectMocks + private PlatformInformationAPIImpl platformInformationAPI; + + @Test + void platformInformationAPI_should_return_case_counters_info() { + //given + doReturn(120L).when(processStarterVerifier).getCurrentNumberOfStartedProcessInstances(); + + //when + final Map platformInformation = platformInformationAPI.getPlatformInformation(); + + //then + assertThat(platformInformation).containsAllEntriesOf(Map.of( + "edition", "community", + "caseCounter", "120", + "caseCounterLimit", valueOf(LIMIT))); + } +} diff --git a/bpm/bonita-web-server/build.gradle b/bpm/bonita-web-server/build.gradle index 73a53a5fb57..3355db647ac 100644 --- a/bpm/bonita-web-server/build.gradle +++ b/bpm/bonita-web-server/build.gradle @@ -51,10 +51,14 @@ dependencies { testImplementation "org.mockito:mockito-core:${Deps.mockitoVersion}" testImplementation "org.hamcrest:hamcrest:${Deps.hamcrestVersion}" testImplementation "junit:junit:${Deps.junit4Version}" + testImplementation libs.junit5api + testImplementation "org.mockito:mockito-junit-jupiter:${Deps.mockitoVersion}" + testRuntimeOnly libs.junitJupiterEngine + testRuntimeOnly libs.junitVintageEngine } configurations { - all { + configureEach { // Specify woodstox version to override the version pulled by jackson-dataformat-xml (transitive dep of restlet) resolutionStrategy.force "com.fasterxml.woodstox:woodstox-core:${Deps.woodstoxCoreVersion}" // Specify Guava version to override the version pulled by owasp-java-html-sanitizer @@ -88,16 +92,17 @@ tasks.named("build") { dependsOn tasks.named("buildZip") } -tasks.named("test") { - dependsOn tasks.named("testsJar") -} - tasks.register('testsJar', Jar) { dependsOn testClasses archiveClassifier = 'tests' from(sourceSets.test.output) } +test { + useJUnitPlatform { includeEngines 'junit-jupiter', 'junit-vintage' } + dependsOn tasks.named("testsJar") +} + artifacts { tests testsJar } diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/AbstractRESTController.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/AbstractRESTController.java index 4ab0fe3e720..3dd84dad83e 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/AbstractRESTController.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/AbstractRESTController.java @@ -16,11 +16,6 @@ import javax.servlet.http.HttpSession; import org.bonitasoft.console.common.server.utils.SessionUtil; -import org.bonitasoft.engine.api.TenantAPIAccessor; -import org.bonitasoft.engine.api.platform.PlatformInformationAPI; -import org.bonitasoft.engine.exception.BonitaHomeNotSetException; -import org.bonitasoft.engine.exception.ServerAPIException; -import org.bonitasoft.engine.exception.UnknownAPITypeException; import org.bonitasoft.engine.session.APISession; import org.springframework.http.HttpStatus; import org.springframework.web.server.ResponseStatusException; @@ -38,8 +33,4 @@ public APISession getApiSession(HttpSession session) { return apiSession; } - protected PlatformInformationAPI getPlatformInformationAPI() - throws BonitaHomeNotSetException, ServerAPIException, UnknownAPITypeException { - return TenantAPIAccessor.getPlatformInformationAPI(); - } } diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/PlatformInformationController.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationController.java similarity index 63% rename from bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/PlatformInformationController.java rename to bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationController.java index 9b42461aa58..5f044a26646 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/PlatformInformationController.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationController.java @@ -15,8 +15,16 @@ import java.util.Map; +import javax.servlet.http.HttpSession; + import lombok.extern.slf4j.Slf4j; +import org.bonitasoft.engine.api.TenantAPIAccessor; +import org.bonitasoft.engine.api.platform.PlatformInformationAPI; import org.bonitasoft.engine.exception.BonitaException; +import org.bonitasoft.engine.exception.BonitaHomeNotSetException; +import org.bonitasoft.engine.exception.ServerAPIException; +import org.bonitasoft.engine.exception.UnknownAPITypeException; +import org.bonitasoft.engine.session.APISession; import org.bonitasoft.web.rest.server.api.AbstractRESTController; import org.bonitasoft.web.toolkit.client.common.exception.api.APIException; import org.springframework.http.MediaType; @@ -27,14 +35,20 @@ @Slf4j @RestController @RequestMapping("/API/system/information") -public class PlatformInformationController extends AbstractRESTController { +public class SystemInformationController extends AbstractRESTController { @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) - public Map getPlatformInfo() { + public Map getPlatformInfo(HttpSession session) { try { - return getPlatformInformationAPI().getPlatformInformation(); + return getPlatformInformationAPI(getApiSession(session)).getPlatformInformation(); } catch (final BonitaException e) { throw new APIException(e); } } + + protected PlatformInformationAPI getPlatformInformationAPI(APISession apiSession) + throws BonitaHomeNotSetException, ServerAPIException, UnknownAPITypeException { + return TenantAPIAccessor.getPlatformInformationAPI(apiSession); + } + } diff --git a/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationControllerTest.java b/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationControllerTest.java new file mode 100644 index 00000000000..9148591d4e2 --- /dev/null +++ b/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/platform/SystemInformationControllerTest.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2024 Bonitasoft S.A. + * Bonitasoft, 32 rue Gustave Eiffel - 38000 Grenoble + * This library is free software; you can redistribute it and/or modify it under the terms + * of the GNU Lesser General Public License as published by the Free Software Foundation + * version 2.1 of the License. + * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License along with this + * program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth + * Floor, Boston, MA 02110-1301, USA. + **/ +package org.bonitasoft.web.rest.server.api.platform; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +import java.util.Map; + +import javax.servlet.http.HttpSession; + +import org.bonitasoft.engine.api.platform.PlatformInformationAPI; +import org.bonitasoft.engine.session.APISession; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class SystemInformationControllerTest { + + @Mock + private PlatformInformationAPI platformInformationAPI; + + @Spy + private SystemInformationController systemInformationController; + + @Test + void get_platform_information_should_return_raw_value_from_Engine() throws Exception { + //given + APISession apiSession = mock(APISession.class); + final HttpSession httpSession = mock(HttpSession.class); + doReturn(apiSession).when(systemInformationController).getApiSession(httpSession); + doReturn(platformInformationAPI).when(systemInformationController).getPlatformInformationAPI(apiSession); + final Map expectedInfo = Map.of("key", "value"); + doReturn(expectedInfo).when(platformInformationAPI).getPlatformInformation(); + + //when + final Map platformInfo = systemInformationController.getPlatformInfo(httpSession); + + //then + assertThat(platformInfo).isEqualTo(expectedInfo); + } + +} diff --git a/services/bonita-authorization/src/main/resources/org/bonitasoft/engine/authorization/properties/dynamic-permissions-checks.properties b/services/bonita-authorization/src/main/resources/org/bonitasoft/engine/authorization/properties/dynamic-permissions-checks.properties index e20da874d4f..fc74aed35c1 100644 --- a/services/bonita-authorization/src/main/resources/org/bonitasoft/engine/authorization/properties/dynamic-permissions-checks.properties +++ b/services/bonita-authorization/src/main/resources/org/bonitasoft/engine/authorization/properties/dynamic-permissions-checks.properties @@ -167,6 +167,8 @@ GET|living/application=[profile|Administrator, check|org.bonitasoft.permissions. # Secure application menu resource GET|living/application-menu=[profile|Administrator, check|org.bonitasoft.permissions.ApplicationMenuPermissionRule] +# Platform information +GET|system/information=[profile|Administrator] #Servlets GET|portal/documentDownload=[profile|Administrator, check|org.bonitasoft.permissions.DownloadDocumentPermissionRule]