From 62c9f412c42227bfe546f072b2a7e1e9cc87c45e Mon Sep 17 00:00:00 2001 From: Haroun El Alami Date: Mon, 11 Sep 2023 14:34:01 +0200 Subject: [PATCH] feat(maintenance mode): add maintenance java API interface (#2701) --------- Co-authored-by: abirembaut --- .../cache/ehcache/CacheConfigurationIT.java | 1 - .../platform/model/impl/PlatformTest.java | 2 + .../engine/api/TenantAPIAccessor.java | 4 + .../bonitasoft/engine/api/MaintenanceAPI.java | 79 +++++++++++ .../engine/api/TenantAdministrationAPI.java | 4 + .../engine/maintenance/MaintenanceInfo.java | 36 +++++ .../MaintenanceInfoNotFoundException.java | 27 ++++ .../maintenance/impl/MaintenanceInfoImpl.java | 38 +++++ .../engine/api/impl/MaintenanceAPIImpl.java | 129 +++++++++++++++++ .../service/impl/APIAccessResolverImpl.java | 1 + .../resources/bonita-platform-community.xml | 13 -- .../api/impl/MaintenanceAPIImplTest.java | 132 ++++++++++++++++++ .../engine/platform/PlatformManagerTest.java | 3 +- .../platform/setup/ScriptExecutor.java | 5 +- .../main/resources/sql/h2/createTables.sql | 2 + .../main/resources/sql/mysql/createTables.sql | 2 + .../resources/sql/oracle/createTables.sql | 2 + .../resources/sql/postgres/createTables.sql | 2 + .../resources/sql/sqlserver/createTables.sql | 2 + .../engine/platform/PlatformService.java | 3 + .../platform/impl/PlatformServiceImpl.java | 46 ++---- .../engine/platform/model/SPlatform.java | 16 ++- .../model/builder/SPlatformUpdateBuilder.java | 33 +++++ .../impl/SPlatformUpdateBuilderImpl.java | 49 +++++++ .../platform/PlatformServiceImplTest.java | 55 +------- 25 files changed, 577 insertions(+), 109 deletions(-) create mode 100644 bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/MaintenanceAPI.java create mode 100644 bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfo.java create mode 100644 bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfoNotFoundException.java create mode 100644 bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/impl/MaintenanceInfoImpl.java create mode 100644 bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImpl.java create mode 100644 bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImplTest.java create mode 100644 services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/SPlatformUpdateBuilder.java create mode 100644 services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/impl/SPlatformUpdateBuilderImpl.java diff --git a/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/cache/ehcache/CacheConfigurationIT.java b/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/cache/ehcache/CacheConfigurationIT.java index 598f9a0f2da..341f48f7079 100644 --- a/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/cache/ehcache/CacheConfigurationIT.java +++ b/bonita-integration-tests/bonita-integration-tests-local/src/test/java/org/bonitasoft/engine/cache/ehcache/CacheConfigurationIT.java @@ -35,7 +35,6 @@ public void setUp() { public void all_required_cache_configurations_should_exist() { assertThat(cacheService.getCacheConfigurationNames()).containsExactlyInAnyOrder( "CONFIGURATION_FILES_CACHE", - "PLATFORM", "USER_FILTER", "transient_data", "GROOVY_SCRIPT_CACHE_NAME", diff --git a/bonita-integration-tests/bonita-query-tests/src/test/java/org/bonitasoft/engine/platform/model/impl/PlatformTest.java b/bonita-integration-tests/bonita-query-tests/src/test/java/org/bonitasoft/engine/platform/model/impl/PlatformTest.java index 2da91a5c093..08f2e754053 100644 --- a/bonita-integration-tests/bonita-query-tests/src/test/java/org/bonitasoft/engine/platform/model/impl/PlatformTest.java +++ b/bonita-integration-tests/bonita-query-tests/src/test/java/org/bonitasoft/engine/platform/model/impl/PlatformTest.java @@ -62,6 +62,8 @@ public void should_save_and_get_SPlatform() { entry("CREATED_BY", "The almighty"), entry("INITIAL_BONITA_VERSION", "5.9.0"), entry("APPLICATION_VERSION", "0.0.0"), + entry("MAINTENANCE_MESSAGE", null), + entry("MAINTENANCE_MESSAGE_ACTIVE", false), entry("VERSION", "1.2"), entry("INFORMATION", "some infos XYZ")); } 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 74aa772838f..3bee0153856 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 @@ -128,4 +128,8 @@ public static ApplicationAPI getApplicationAPI(final APISession session) return getAPI(ApplicationAPI.class, session); } + public static MaintenanceAPI getMaintenanceAPI(final APISession session) + throws BonitaHomeNotSetException, ServerAPIException, UnknownAPITypeException { + return getAPI(MaintenanceAPI.class, session); + } } diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/MaintenanceAPI.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/MaintenanceAPI.java new file mode 100644 index 00000000000..4ed2a6187b8 --- /dev/null +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/MaintenanceAPI.java @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2023 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; + +import org.bonitasoft.engine.exception.UpdateException; +import org.bonitasoft.engine.maintenance.MaintenanceInfo; +import org.bonitasoft.engine.maintenance.MaintenanceInfoNotFoundException; +import org.bonitasoft.engine.platform.PlatformNotFoundException; + +/** + * This API gives access to maintenance administration tasks such as enabling maintenance mode and also enable/disable + * maintenance message. + */ +public interface MaintenanceAPI { + + /** + * Retrieve maintenance info details + * + * @return MaintenanceInfo + * @throws MaintenanceInfoNotFoundException + * @throws PlatformNotFoundException + */ + MaintenanceInfo getMaintenanceInfo() throws MaintenanceInfoNotFoundException, PlatformNotFoundException; + + /** + * Enable maintenance mode + * This method replaces {@link TenantAdministrationAPI#pause()} + * When maintenance mode is enabled, All BPM and BDM APIs are not accessible. + * + * @throws UpdateException + * if maintenance state cannot be updated. + */ + void enableMaintenanceMode() throws UpdateException; + + /** + * Disable maintenance mode + * This method replaces {@link TenantAdministrationAPI#resume()} + * + * @throws UpdateException + * if maintenance state cannot be updated. + */ + void disableMaintenanceMode() throws UpdateException; + + /** + * Update maintenance message + * This message will be displayed in bonita apps if enabled + * + * @throws UpdateException + * if maintenance message cannot be updated. + */ + void updateMaintenanceMessage(String message) throws UpdateException; + + /** + * Enable maintenance message + * + * @throws UpdateException + * if maintenance message cannot be enabled. + */ + void enableMaintenanceMessage() throws UpdateException; + + /** + * Disable maintenance message + * + * @throws UpdateException + * if maintenance message cannot be disabled. + */ + void disableMaintenanceMessage() throws UpdateException; +} diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/TenantAdministrationAPI.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/TenantAdministrationAPI.java index f071e07bc5e..a749e782feb 100644 --- a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/TenantAdministrationAPI.java +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/TenantAdministrationAPI.java @@ -45,7 +45,9 @@ public interface TenantAdministrationAPI { * * @throws org.bonitasoft.engine.exception.UpdateException * if the tenant cannot be paused. + * This method is deprecated, use {@link MaintenanceAPI#enableMaintenanceMode()} instead. */ + @Deprecated void pause() throws UpdateException; /** @@ -53,7 +55,9 @@ public interface TenantAdministrationAPI { * * @throws org.bonitasoft.engine.exception.UpdateException * if the tenant cannot be resumed. + * This method is deprecated, use {@link MaintenanceAPI#disableMaintenanceMode()} ()} instead. */ + @Deprecated void resume() throws UpdateException; /** diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfo.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfo.java new file mode 100644 index 00000000000..1efb23407bd --- /dev/null +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfo.java @@ -0,0 +1,36 @@ +/** + * Copyright (C) 2023 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.maintenance; + +import org.bonitasoft.engine.bpm.BonitaObject; + +/** + * This object holds maintenance details such as maintenance state and message. + */ +public interface MaintenanceInfo extends BonitaObject { + + public State getMaintenanceState(); + + public String getMaintenanceMessage(); + + public boolean isMaintenanceMessageActive(); + + /** + * Activation state of platform maintenance + */ + public enum State { + + ENABLED, DISABLED + } +} diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfoNotFoundException.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfoNotFoundException.java new file mode 100644 index 00000000000..d9ef071effa --- /dev/null +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/MaintenanceInfoNotFoundException.java @@ -0,0 +1,27 @@ +/** + * Copyright (C) 2023 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.maintenance; + +import org.bonitasoft.engine.exception.NotFoundException; + +public class MaintenanceInfoNotFoundException extends NotFoundException { + + public MaintenanceInfoNotFoundException(String message) { + super(message); + } + + public MaintenanceInfoNotFoundException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/impl/MaintenanceInfoImpl.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/impl/MaintenanceInfoImpl.java new file mode 100644 index 00000000000..5744fab80ba --- /dev/null +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/maintenance/impl/MaintenanceInfoImpl.java @@ -0,0 +1,38 @@ +/** + * Copyright (C) 2023 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.maintenance.impl; + +import lombok.Builder; +import org.bonitasoft.engine.maintenance.MaintenanceInfo; + +@Builder +public class MaintenanceInfoImpl implements MaintenanceInfo { + + private State maintenanceState; + private String maintenanceMessage; + private boolean maintenanceMessageActive; + + public State getMaintenanceState() { + return maintenanceState; + } + + @Override + public String getMaintenanceMessage() { + return maintenanceMessage; + } + + public boolean isMaintenanceMessageActive() { + return maintenanceMessageActive; + } +} diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImpl.java new file mode 100644 index 00000000000..12164bbee69 --- /dev/null +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImpl.java @@ -0,0 +1,129 @@ +/** + * Copyright (C) 2023 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; + +import org.bonitasoft.engine.api.MaintenanceAPI; +import org.bonitasoft.engine.exception.BonitaRuntimeException; +import org.bonitasoft.engine.exception.UpdateException; +import org.bonitasoft.engine.maintenance.MaintenanceInfo; +import org.bonitasoft.engine.maintenance.MaintenanceInfoNotFoundException; +import org.bonitasoft.engine.maintenance.impl.MaintenanceInfoImpl; +import org.bonitasoft.engine.platform.PlatformNotFoundException; +import org.bonitasoft.engine.platform.PlatformService; +import org.bonitasoft.engine.platform.exception.SPlatformNotFoundException; +import org.bonitasoft.engine.platform.exception.SPlatformUpdateException; +import org.bonitasoft.engine.platform.exception.STenantNotFoundException; +import org.bonitasoft.engine.platform.model.SPlatform; +import org.bonitasoft.engine.platform.model.builder.SPlatformUpdateBuilder; +import org.bonitasoft.engine.platform.model.builder.impl.SPlatformUpdateBuilderImpl; +import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor; +import org.bonitasoft.engine.service.ServiceAccessor; +import org.bonitasoft.engine.service.impl.ServiceAccessorFactory; +import org.bonitasoft.engine.tenant.TenantStateManager; + +/** + * This API gives access to maintenance administration tasks. + */ +public class MaintenanceAPIImpl implements MaintenanceAPI { + + public MaintenanceAPIImpl() { + } + + protected ServiceAccessor getServiceAccessor() { + try { + return ServiceAccessorFactory.getInstance().createServiceAccessor(); + } catch (final Exception e) { + throw new BonitaRuntimeException(e); + } + } + + @Override + public MaintenanceInfo getMaintenanceInfo() throws MaintenanceInfoNotFoundException, PlatformNotFoundException { + try { + PlatformService platformService = getServiceAccessor().getPlatformService(); + MaintenanceInfo.State state = platformService.getDefaultTenant().isPaused() ? MaintenanceInfo.State.ENABLED + : MaintenanceInfo.State.DISABLED; + SPlatform platform = platformService.getPlatform(); + return MaintenanceInfoImpl.builder() + .maintenanceMessage(platform.getMaintenanceMessage()) + .maintenanceMessageActive(platform.isMaintenanceMessageActive()) + .maintenanceState(state) + .build(); + } catch (STenantNotFoundException e) { + throw new MaintenanceInfoNotFoundException("Maintenance info not found", e); + } catch (SPlatformNotFoundException e) { + throw new PlatformNotFoundException(e.getMessage(), e); + } + } + + @Override + public void enableMaintenanceMode() throws UpdateException { + try { + TenantStateManager tenantStateManager = getServiceAccessor().getTenantStateManager(); + tenantStateManager.pause(); + } catch (Exception e) { + throw new UpdateException(e); + } + } + + @Override + public void disableMaintenanceMode() throws UpdateException { + try { + TenantStateManager tenantStateManager = getServiceAccessor().getTenantStateManager(); + tenantStateManager.resume(); + disableMaintenanceMessage(); + } catch (Exception e) { + throw new UpdateException(e); + } + } + + @Override + public void updateMaintenanceMessage(String message) throws UpdateException { + try { + PlatformService platformService = getServiceAccessor().getPlatformService(); + platformService.updatePlatform(getPlatformUpdateBuilder() + .setMaintenanceMessage(message).done()); + } catch (SPlatformUpdateException e) { + throw new UpdateException(e); + } + } + + @Override + public void enableMaintenanceMessage() throws UpdateException { + try { + PlatformService platformService = getServiceAccessor().getPlatformService(); + platformService.updatePlatform(getPlatformUpdateBuilder() + .setMaintenanceMessageActive(true).done()); + } catch (SPlatformUpdateException e) { + throw new UpdateException(e); + } + } + + @Override + public void disableMaintenanceMessage() throws UpdateException { + try { + PlatformService platformService = getServiceAccessor().getPlatformService(); + platformService.updatePlatform(getPlatformUpdateBuilder() + .setMaintenanceMessageActive(false).done()); + } catch (SPlatformUpdateException e) { + throw new UpdateException(e); + } + } + + protected SPlatformUpdateBuilder getPlatformUpdateBuilder() { + return SPlatformUpdateBuilderImpl.builder() + .descriptor(new EntityUpdateDescriptor()) + .build(); + } +} diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/APIAccessResolverImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/APIAccessResolverImpl.java index 9d6017836c8..a395c736f4b 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/APIAccessResolverImpl.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/APIAccessResolverImpl.java @@ -44,6 +44,7 @@ public class APIAccessResolverImpl implements APIAccessResolver { apis.put(TenantAdministrationAPI.class.getName(), new TenantAdministrationAPIImpl()); apis.put(BusinessDataAPI.class.getName(), new BusinessDataAPIImpl()); apis.put(TemporaryContentAPI.class.getName(), new TemporaryContentAPIImpl()); + apis.put(MaintenanceAPI.class.getName(), new MaintenanceAPIImpl()); } @Override diff --git a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-platform-community.xml b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-platform-community.xml index 5d935434873..544b14437a6 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-platform-community.xml +++ b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-platform-community.xml @@ -157,19 +157,6 @@ - - - - - - - - - - - - - diff --git a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImplTest.java b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImplTest.java new file mode 100644 index 00000000000..3816c3d9fc5 --- /dev/null +++ b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/api/impl/MaintenanceAPIImplTest.java @@ -0,0 +1,132 @@ +/** + * Copyright (C) 2023 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; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +import org.bonitasoft.engine.maintenance.MaintenanceInfo; +import org.bonitasoft.engine.platform.PlatformService; +import org.bonitasoft.engine.platform.model.SPlatform; +import org.bonitasoft.engine.platform.model.STenant; +import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor; +import org.bonitasoft.engine.service.TenantServiceAccessor; +import org.bonitasoft.engine.tenant.TenantStateManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class MaintenanceAPIImplTest { + + public static final long TENANT_ID = 56423L; + + @Mock + private TenantServiceAccessor serviceAccessor; + @Mock + private PlatformService platformService; + @Mock + private TenantStateManager tenantStateManager; + @Spy + @InjectMocks + private MaintenanceAPIImpl maintenanceAPI; + + @Before + public void setup() throws Exception { + doReturn(platformService).when(serviceAccessor).getPlatformService(); + doReturn(tenantStateManager).when(serviceAccessor).getTenantStateManager(); + doReturn(serviceAccessor).when(maintenanceAPI).getServiceAccessor(); + } + + @Test + public void get_maintenance_info_should_retrieve_from_platform_service() throws Exception { + //given + STenant tenant = STenant.builder().status(STenant.PAUSED).build(); + SPlatform platform = SPlatform.builder() + .maintenanceMessage("maintenance msg") + .maintenanceMessageActive(true) + .build(); + + doReturn(tenant).when(platformService).getDefaultTenant(); + doReturn(platform).when(platformService).getPlatform(); + //when + MaintenanceInfo info = maintenanceAPI.getMaintenanceInfo(); + //then + assertThat(info.getMaintenanceState()).isEqualTo(MaintenanceInfo.State.ENABLED); + assertThat(info.getMaintenanceMessage()).isEqualTo(platform.getMaintenanceMessage()); + assertThat(info.isMaintenanceMessageActive()).isEqualTo(platform.isMaintenanceMessageActive()); + } + + @Test + public void enable_maintenance_mode_should_update_state_manager() throws Exception { + //given + doNothing().when(tenantStateManager).pause(); + //when + maintenanceAPI.enableMaintenanceMode(); + //then + verify(tenantStateManager).pause(); + } + + @Test + public void disable_maintenance_mode_should_update_state_manager() throws Exception { + //given + doNothing().when(tenantStateManager).resume(); + //when + maintenanceAPI.disableMaintenanceMode(); + //then + verify(tenantStateManager).resume(); + } + + @Test + public void update_maintenance_msg_should_pass_message_to_platform_service() throws Exception { + //given + doNothing().when(platformService).updatePlatform(any()); + //when + String msg = "maintenance msg"; + maintenanceAPI.updateMaintenanceMessage(msg); + //then + ArgumentCaptor captor = ArgumentCaptor.forClass(EntityUpdateDescriptor.class);; + verify(platformService).updatePlatform(captor.capture()); + assertThat(captor.getValue().getFields().containsValue(msg)); + } + + @Test + public void enable_maintenance_mode_msg_should_update_platform_service() throws Exception { + //given + doNothing().when(platformService).updatePlatform(any()); + //when + maintenanceAPI.enableMaintenanceMessage(); + //then + ArgumentCaptor captor = ArgumentCaptor.forClass(EntityUpdateDescriptor.class);; + verify(platformService).updatePlatform(captor.capture()); + assertThat(captor.getValue().getFields().containsValue(true)); + } + + @Test + public void disable_maintenance_mode_msg_should_update_platform_service() throws Exception { + //given + doNothing().when(platformService).updatePlatform(any()); + //when + maintenanceAPI.disableMaintenanceMessage(); + //then + ArgumentCaptor captor = ArgumentCaptor.forClass(EntityUpdateDescriptor.class);; + verify(platformService).updatePlatform(captor.capture()); + assertThat(captor.getValue().getFields().containsValue(false)); + } +} diff --git a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/platform/PlatformManagerTest.java b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/platform/PlatformManagerTest.java index a7fcb1cf2ae..ac56b589423 100644 --- a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/platform/PlatformManagerTest.java +++ b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/platform/PlatformManagerTest.java @@ -96,7 +96,8 @@ public void before() throws Exception { return null; }); doReturn(tenantManager).when(platformManager).getDefaultTenantStateManager(); - doReturn(new SPlatform("1.3", "1.1.0", "someUser", 123455, "0.0.0")).when(platformService).getPlatform(); + doReturn(new SPlatform("1.3", "1.1.0", "0.0.0", null, false, "someUser", 123455)).when(platformService) + .getPlatform(); doReturn(new SPlatformPropertiesImpl("1.3.0")).when(platformService).getSPlatformProperties(); tenant = new STenant(); tenant.setId(TENANT_ID); diff --git a/platform/platform-resources/src/main/java/org/bonitasoft/platform/setup/ScriptExecutor.java b/platform/platform-resources/src/main/java/org/bonitasoft/platform/setup/ScriptExecutor.java index 787a3f4dc03..32cfd618cc2 100644 --- a/platform/platform-resources/src/main/java/org/bonitasoft/platform/setup/ScriptExecutor.java +++ b/platform/platform-resources/src/main/java/org/bonitasoft/platform/setup/ScriptExecutor.java @@ -106,8 +106,9 @@ protected void insertPlatform() { String version = versionService.getPlatformSetupVersion(); String databaseSchemaVersion = versionService.getSupportedDatabaseSchemaVersion(); final String sql = String.format("INSERT INTO platform " + - "(id, version, initial_bonita_version, application_version, created, created_by) " + - "VALUES (1, '%s', '%s', '0.0.0', %d, 'platformAdmin')", + "(id, version, initial_bonita_version, application_version, maintenance_message_active, created, created_by) " + + + "VALUES (1, '%s', '%s', '0.0.0', false, %d, 'platformAdmin')", databaseSchemaVersion, version, System.currentTimeMillis()); new JdbcTemplate(datasource).update(sql); } diff --git a/platform/platform-resources/src/main/resources/sql/h2/createTables.sql b/platform/platform-resources/src/main/resources/sql/h2/createTables.sql index f7b56f6d6cb..280bfadcdf4 100644 --- a/platform/platform-resources/src/main/resources/sql/h2/createTables.sql +++ b/platform/platform-resources/src/main/resources/sql/h2/createTables.sql @@ -877,6 +877,8 @@ CREATE TABLE platform ( version VARCHAR(50) NOT NULL, initial_bonita_version VARCHAR(50) NOT NULL, application_version VARCHAR(50) NOT NULL, + maintenance_message LONGVARCHAR, + maintenance_message_active BOOLEAN NOT NULL, created BIGINT NOT NULL, created_by VARCHAR(50) NOT NULL, information CLOB, diff --git a/platform/platform-resources/src/main/resources/sql/mysql/createTables.sql b/platform/platform-resources/src/main/resources/sql/mysql/createTables.sql index 847252f97df..4431b6fa21d 100644 --- a/platform/platform-resources/src/main/resources/sql/mysql/createTables.sql +++ b/platform/platform-resources/src/main/resources/sql/mysql/createTables.sql @@ -879,6 +879,8 @@ CREATE TABLE platform ( version VARCHAR(50) NOT NULL, initial_bonita_version VARCHAR(50) NOT NULL, application_version VARCHAR(50) NOT NULL, + maintenance_message TEXT, + maintenance_message_active BOOLEAN NOT NULL, created BIGINT NOT NULL, created_by VARCHAR(50) NOT NULL, information TEXT, diff --git a/platform/platform-resources/src/main/resources/sql/oracle/createTables.sql b/platform/platform-resources/src/main/resources/sql/oracle/createTables.sql index 7bf76127ded..76bd5583e51 100644 --- a/platform/platform-resources/src/main/resources/sql/oracle/createTables.sql +++ b/platform/platform-resources/src/main/resources/sql/oracle/createTables.sql @@ -869,6 +869,8 @@ CREATE TABLE platform ( version VARCHAR2(50 CHAR) NOT NULL, initial_bonita_version VARCHAR2(50 CHAR) NOT NULL, application_version VARCHAR2(50 CHAR) NOT NULL, + maintenance_message VARCHAR2(1024 CHAR), + maintenance_message_active NUMBER(1) NOT NULL, created NUMBER(19, 0) NOT NULL, created_by VARCHAR2(50 CHAR) NOT NULL, information CLOB, diff --git a/platform/platform-resources/src/main/resources/sql/postgres/createTables.sql b/platform/platform-resources/src/main/resources/sql/postgres/createTables.sql index d1ed8217d5c..1dd2e41c3c6 100644 --- a/platform/platform-resources/src/main/resources/sql/postgres/createTables.sql +++ b/platform/platform-resources/src/main/resources/sql/postgres/createTables.sql @@ -880,6 +880,8 @@ CREATE TABLE platform ( version VARCHAR(50) NOT NULL, initial_bonita_version VARCHAR(50) NOT NULL, application_version VARCHAR(50) NOT NULL, + maintenance_message TEXT, + maintenance_message_active BOOLEAN NOT NULL, created INT8 NOT NULL, created_by VARCHAR(50) NOT NULL, information TEXT, diff --git a/platform/platform-resources/src/main/resources/sql/sqlserver/createTables.sql b/platform/platform-resources/src/main/resources/sql/sqlserver/createTables.sql index 595c96a00aa..e4efb65505e 100644 --- a/platform/platform-resources/src/main/resources/sql/sqlserver/createTables.sql +++ b/platform/platform-resources/src/main/resources/sql/sqlserver/createTables.sql @@ -1005,6 +1005,8 @@ CREATE TABLE platform ( version NVARCHAR(50) NOT NULL, initial_bonita_version NVARCHAR(50) NOT NULL, application_version NVARCHAR(50) NOT NULL, + maintenance_message NVARCHAR(MAX), + maintenance_message_active BIT NOT NULL, created NUMERIC(19, 0) NOT NULL, created_by NVARCHAR(50) NOT NULL, information NVARCHAR(MAX), diff --git a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/PlatformService.java b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/PlatformService.java index 28d357813aa..a9b8a65f220 100644 --- a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/PlatformService.java +++ b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/PlatformService.java @@ -26,6 +26,7 @@ */ public interface PlatformService { + String PLATFORM = "PLATFORM"; String TENANT = "TENANT"; /** @@ -131,4 +132,6 @@ public interface PlatformService { * @since 6.1 */ SPlatformProperties getSPlatformProperties(); + + void updatePlatform(EntityUpdateDescriptor descriptor) throws SPlatformUpdateException; } diff --git a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/impl/PlatformServiceImpl.java b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/impl/PlatformServiceImpl.java index 34ffc6f5e7f..2f6a749a750 100644 --- a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/impl/PlatformServiceImpl.java +++ b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/impl/PlatformServiceImpl.java @@ -14,8 +14,6 @@ package org.bonitasoft.engine.platform.impl; import lombok.extern.slf4j.Slf4j; -import org.bonitasoft.engine.cache.CacheService; -import org.bonitasoft.engine.cache.SCacheException; import org.bonitasoft.engine.persistence.SBonitaReadException; import org.bonitasoft.engine.persistence.SelectByIdDescriptor; import org.bonitasoft.engine.persistence.SelectOneDescriptor; @@ -42,10 +40,8 @@ public class PlatformServiceImpl implements PlatformService { private static final String TENANT = "TENANT"; private static final String QUERY_GET_DEFAULT_TENANT = "getDefaultTenant"; - private static final String CACHE_KEY = "PLATFORM"; private final PersistenceService platformPersistenceService; - private final CacheService cacheService; private final SPlatformProperties sPlatformProperties; private final Recorder recorder; private final PlatformRetriever platformRetriever; @@ -53,10 +49,9 @@ public class PlatformServiceImpl implements PlatformService { private static Long defaultTenantId = null; public PlatformServiceImpl(final PersistenceService platformPersistenceService, PlatformRetriever platformRetriever, - final Recorder recorder, CacheService cacheService, + final Recorder recorder, final SPlatformProperties sPlatformProperties) { this.platformPersistenceService = platformPersistenceService; - this.cacheService = cacheService; this.sPlatformProperties = sPlatformProperties; this.recorder = recorder; this.platformRetriever = platformRetriever; @@ -64,36 +59,6 @@ public PlatformServiceImpl(final PersistenceService platformPersistenceService, @Override public SPlatform getPlatform() throws SPlatformNotFoundException { - try { - SPlatform sPlatform = (SPlatform) cacheService.get(CACHE_KEY, CACHE_KEY); - if (sPlatform == null) { - // try to read it from database - sPlatform = readPlatform(); - cachePlatform(sPlatform); - } - return sPlatform; - } catch (final SCacheException e) { - throw new SPlatformNotFoundException("Platform not present in cache.", e); - } - } - - /* - * ************************* - * The Platform is stored 1 time for each cache - * We do this because the cache service handle - * multi tenancy - * ************************* - */ - private void cachePlatform(final SPlatform platform) { - try { - cacheService.store(CACHE_KEY, CACHE_KEY, platform); - } catch (final SCacheException e) { - log.warn("Can't cache the platform, maybe the platform cache service is not started yet: {}", - e.getMessage()); - } - } - - private SPlatform readPlatform() throws SPlatformNotFoundException { try { return platformRetriever.getPlatform(); } catch (SPlatformNotFoundException e) { @@ -208,4 +173,13 @@ public SPlatformProperties getSPlatformProperties() { return sPlatformProperties; } + @Override + public void updatePlatform(final EntityUpdateDescriptor descriptor) throws SPlatformUpdateException { + try { + recorder.recordUpdate(UpdateRecord.buildSetFields(getPlatform(), descriptor), PLATFORM); + } catch (final SRecorderException | SPlatformNotFoundException e) { + throw new SPlatformUpdateException("Problem while updating platform: ", e); + } + } + } diff --git a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/SPlatform.java b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/SPlatform.java index 59082e9443d..469738c6ba3 100644 --- a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/SPlatform.java +++ b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/SPlatform.java @@ -40,6 +40,9 @@ public class SPlatform implements PlatformPersistentObject { public static final String PREVIOUS_VERSION = "previousVersion"; public static final String VERSION = "version"; public static final String INFORMATION = "information"; + public static final String MAINTENANCE_MESSAGE = "maintenance_message"; + public static final String MAINTENANCE_MESSAGE_ACTIVE = "maintenance_message_active"; + @Id private long id; private long created; @@ -53,14 +56,21 @@ public class SPlatform implements PlatformPersistentObject { private String information; @Column(name = "application_version") private String applicationVersion; + @Column(name = "maintenance_message") + private String maintenanceMessage; + @Column(name = "maintenance_message_active") + private boolean maintenanceMessageActive; - public SPlatform(final String dbSchemaVersion, final String initialBonitaVersion, - final String createdBy, final long created, final String applicationVersion) { + public SPlatform(final String dbSchemaVersion, final String initialBonitaVersion, final String applicationVersion, + final String maintenanceMessage, final boolean maintenanceMessageActive, + final String createdBy, final long created) { this.dbSchemaVersion = dbSchemaVersion; this.initialBonitaVersion = initialBonitaVersion; + this.applicationVersion = applicationVersion; + this.maintenanceMessage = maintenanceMessage; + this.maintenanceMessageActive = maintenanceMessageActive; this.createdBy = createdBy; this.created = created; - this.applicationVersion = applicationVersion; } @Override diff --git a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/SPlatformUpdateBuilder.java b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/SPlatformUpdateBuilder.java new file mode 100644 index 00000000000..6efbf469520 --- /dev/null +++ b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/SPlatformUpdateBuilder.java @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2023 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.platform.model.builder; + +import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor; + +/** + * @author Haroun EL ALAMI + */ +public interface SPlatformUpdateBuilder { + + String MAINTENANCE_MESSAGE = "maintenance_message"; + + String MAINTENANCE_MESSAGE_ACTIVE = "is_maintenance_message_active"; + + SPlatformUpdateBuilder setMaintenanceMessageActive(boolean state); + + SPlatformUpdateBuilder setMaintenanceMessage(String name); + + EntityUpdateDescriptor done(); + +} diff --git a/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/impl/SPlatformUpdateBuilderImpl.java b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/impl/SPlatformUpdateBuilderImpl.java new file mode 100644 index 00000000000..bef7a5c0e5b --- /dev/null +++ b/services/bonita-platform/src/main/java/org/bonitasoft/engine/platform/model/builder/impl/SPlatformUpdateBuilderImpl.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2023 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.platform.model.builder.impl; + +import lombok.Builder; +import org.bonitasoft.engine.platform.model.builder.SPlatformUpdateBuilder; +import org.bonitasoft.engine.recorder.model.EntityUpdateDescriptor; + +/** + * @author Haroun EL ALAMI + */ +@Builder +public class SPlatformUpdateBuilderImpl implements SPlatformUpdateBuilder { + + protected final EntityUpdateDescriptor descriptor; + + public SPlatformUpdateBuilderImpl(final EntityUpdateDescriptor descriptor) { + this.descriptor = descriptor; + } + + @Override + public SPlatformUpdateBuilder setMaintenanceMessage(final String name) { + descriptor.addField(MAINTENANCE_MESSAGE, name); + return this; + } + + @Override + public SPlatformUpdateBuilder setMaintenanceMessageActive(final boolean state) { + descriptor.addField(MAINTENANCE_MESSAGE_ACTIVE, state); + return this; + } + + @Override + public EntityUpdateDescriptor done() { + return descriptor; + } + +} diff --git a/services/bonita-platform/src/test/java/org/bonitasoft/engine/platform/PlatformServiceImplTest.java b/services/bonita-platform/src/test/java/org/bonitasoft/engine/platform/PlatformServiceImplTest.java index fc66bcd428b..814eee2bc79 100644 --- a/services/bonita-platform/src/test/java/org/bonitasoft/engine/platform/PlatformServiceImplTest.java +++ b/services/bonita-platform/src/test/java/org/bonitasoft/engine/platform/PlatformServiceImplTest.java @@ -24,8 +24,6 @@ import javax.sql.DataSource; -import org.bonitasoft.engine.cache.CacheService; -import org.bonitasoft.engine.cache.SCacheException; import org.bonitasoft.engine.commons.exceptions.SBonitaException; import org.bonitasoft.engine.persistence.SBonitaReadException; import org.bonitasoft.engine.persistence.SelectOneDescriptor; @@ -59,9 +57,6 @@ public class PlatformServiceImplTest { @Mock private PlatformRetriever platformRetriever; - @Mock - private CacheService platformCacheService; - @Mock private Recorder recorder; @@ -102,15 +97,6 @@ public final void getDefaultTenantThrowException() throws SBonitaException { platformServiceImpl.getDefaultTenant(); } - @Test - public final void getPlatform_should_return_platform_from_cache_if_available() throws SBonitaException { - final SPlatform sPlatform = buildPlatform(); - when(platformCacheService.get(anyString(), anyString())).thenReturn(sPlatform); - - assertEquals(sPlatform, platformServiceImpl.getPlatform()); - verifyNoInteractions(platformRetriever); - } - @Test public final void getPlatform_should_throw_SPlatformNotFoundException_when_platformRetriever_throws_SPlatformNotFoundException() throws SBonitaException { @@ -126,51 +112,14 @@ public final void getPlatform_should_throw_SPlatformNotFoundException_when_platf platformServiceImpl.getPlatform(); } - @Test(expected = SPlatformNotFoundException.class) - public final void getPlatform_should_throw_SPlatformNotFoundExcpetion_when_cacheSercie_throws_Exception() - throws SBonitaException { - when(platformCacheService.get(anyString(), anyString())).thenThrow(new SCacheException("")); - - platformServiceImpl.getPlatform(); - } - - @Test - public final void isPlatformCreated_already_in_cache() throws SBonitaException { - final SPlatform sPlatform = buildPlatform(); - when(platformCacheService.get(anyString(), anyString())).thenReturn(sPlatform); - - assertTrue(platformServiceImpl.isPlatformCreated()); - } - - @Test - public final void isPlatformCreated_should_return_false_when_platform_is_not_in_cache_neither_in_db() - throws SBonitaException { - // given - when(platformCacheService.get(anyString(), anyString())).thenReturn(null); - given(platformRetriever.getPlatform()).willThrow(new SPlatformNotFoundException("not found")); - - // when then - assertFalse(platformServiceImpl.isPlatformCreated()); - verify(platformRetriever, times(1)).getPlatform(); - } - @Test public final void isPlatformCreated() throws SBonitaException { final SPlatform sPlatform = buildPlatform(); - when(platformCacheService.get(anyString(), anyString())).thenReturn(sPlatform); + when(platformServiceImpl.getPlatform()).thenReturn(sPlatform); assertTrue(platformServiceImpl.isPlatformCreated()); } - @Test - public final void isPlatformCreated_false_when_cache_exception() throws SBonitaException { - // given - when(platformCacheService.get(anyString(), anyString())).thenThrow(new SCacheException("")); - - // whne then - assertFalse(platformServiceImpl.isPlatformCreated()); - } - @Test public void updateTheTenantUsingTheSameName() throws SBonitaException { // Given @@ -235,7 +184,7 @@ private STenant buildTenant(final long id, final String name) { } private SPlatform buildPlatform() { - return new SPlatform("1.0", "0.5", "me", 654687344687645L, "0.0.0"); + return new SPlatform("1.0", "0.5", "0.0.0", null, false, "me", 654687344687645L); } }