diff --git a/bonita-engine/build.gradle b/bonita-engine/build.gradle index e92b599a1e9..290aeb514ed 100644 --- a/bonita-engine/build.gradle +++ b/bonita-engine/build.gradle @@ -82,6 +82,8 @@ dependencyManagement { dependency "com.bonitasoft.engine:bonita-client-sp:${project.version}" // Web extensions dependencies: + dependency "org.bonitasoft.console:bonita-web-server:${project.version}" + dependency "org.bonitasoft.console:bonita-web-server-sp:${project.version}" dependency "org.bonitasoft.web:bonita-web-extensions:${project.version}" dependency "com.bonitasoft.web:bonita-web-extensions-sp:${project.version}" diff --git a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/ProcessManagementAPI.java b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/ProcessManagementAPI.java index 80fea60ac3d..f6a68814d95 100644 --- a/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/ProcessManagementAPI.java +++ b/bpm/bonita-common/src/main/java/org/bonitasoft/engine/api/ProcessManagementAPI.java @@ -277,7 +277,9 @@ ProcessDefinition deployAndEnableProcess(BusinessArchive businessArchive) * @throws UpdateException * If an exception occurs when updating the process deployment information. * @since 6.0 + * @deprecated as of 9.0.0, Process should be updated at startup. */ + @Deprecated(since = "9.0.0") void updateProcessDeploymentInfo(long processDefinitionId, ProcessDeploymentInfoUpdater processDeploymentInfoUpdater) throws ProcessDefinitionNotFoundException, UpdateException; @@ -423,7 +425,9 @@ List getProcessDeploymentInfos(int startIndex, int maxRes * @throws UpdateException * If an exception occurs when updating the actor. * @since 6.0 + * @deprecated as of 9.0.0, Actor should be updated at startup. */ + @Deprecated(since = "9.0.0") ActorInstance updateActor(long actorId, ActorUpdater actorUpdater) throws ActorNotFoundException, UpdateException; /** diff --git a/bpm/bonita-core/bonita-home-server/src/main/java/org/bonitasoft/engine/home/BonitaHomeServer.java b/bpm/bonita-core/bonita-home-server/src/main/java/org/bonitasoft/engine/home/BonitaHomeServer.java index 421f5c78e04..dd26f37d1c2 100644 --- a/bpm/bonita-core/bonita-home-server/src/main/java/org/bonitasoft/engine/home/BonitaHomeServer.java +++ b/bpm/bonita-core/bonita-home-server/src/main/java/org/bonitasoft/engine/home/BonitaHomeServer.java @@ -215,10 +215,10 @@ public void modifyTechnicalUser(long tenantId, String userName, String password) Properties properties = new Properties(); properties.load(new ByteArrayInputStream(bonitaConfiguration.getResourceContent())); if (userName != null) { - properties.setProperty("userName", userName); + properties.setProperty("bonita.runtime.admin.username", userName); } if (password != null) { - properties.setProperty("userPassword", password); + properties.setProperty("bonita.runtime.admin.password", password); } ByteArrayOutputStream out = new ByteArrayOutputStream(); properties.store(out, ""); diff --git a/bpm/bonita-core/bonita-login/build.gradle b/bpm/bonita-core/bonita-login/build.gradle index 26d42c87258..7f7af18840f 100644 --- a/bpm/bonita-core/bonita-login/build.gradle +++ b/bpm/bonita-core/bonita-login/build.gradle @@ -10,4 +10,7 @@ dependencies { testImplementation "org.mockito:mockito-core:${Deps.mockitoVersion}" testImplementation "org.assertj:assertj-core:${Deps.assertjVersion}" testImplementation "ch.qos.logback:logback-classic:${Deps.logbackVersion}" + + compileOnly "org.projectlombok:lombok:${Deps.lombokVersion}" + annotationProcessor "org.projectlombok:lombok:${Deps.lombokVersion}" } diff --git a/bpm/bonita-core/bonita-login/src/main/java/org/bonitasoft/engine/core/login/TechnicalUser.java b/bpm/bonita-core/bonita-login/src/main/java/org/bonitasoft/engine/core/login/TechnicalUser.java index 8edab900568..78e94d54159 100644 --- a/bpm/bonita-core/bonita-login/src/main/java/org/bonitasoft/engine/core/login/TechnicalUser.java +++ b/bpm/bonita-core/bonita-login/src/main/java/org/bonitasoft/engine/core/login/TechnicalUser.java @@ -13,34 +13,25 @@ **/ package org.bonitasoft.engine.core.login; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + /** * @author Matthieu Chaffotte */ +@lombok.Data +@Component public class TechnicalUser { private String userName; private String password; - public TechnicalUser(final String userName, final String password) { + public TechnicalUser( + @Value("${bonita.runtime.admin.username}") final String userName, + @Value("${bonita.runtime.admin.password}") final String password) { super(); this.userName = userName; this.password = password; } - - public String getUserName() { - return userName; - } - - public String getPassword() { - return password; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public void setPassword(String password) { - this.password = password; - } } diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ProcessAPIImpl.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ProcessAPIImpl.java index 84ca1fb8317..60349e7cd7c 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ProcessAPIImpl.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/api/impl/ProcessAPIImpl.java @@ -764,7 +764,11 @@ public long getNumberOfMembershipsOfActor(final long actorId) { return getNumber.getResult(); } + /** + * {@inheritDoc} + */ @Override + @Deprecated(since = "9.0.0") public ActorInstance updateActor(final long actorId, final ActorUpdater descriptor) throws ActorNotFoundException, UpdateException { if (descriptor == null || descriptor.getFields().isEmpty()) { @@ -2748,7 +2752,11 @@ public void releaseUserTask(final long userTaskId) throws ActivityInstanceNotFou } } + /** + * {@inheritDoc} + */ @Override + @Deprecated(since = "9.0.0") public void updateProcessDeploymentInfo(final long processDefinitionId, final ProcessDeploymentInfoUpdater processDeploymentInfoUpdater) throws ProcessDefinitionNotFoundException, UpdateException { diff --git a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringBeanAccessor.java b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringBeanAccessor.java index e2aa4db4fa4..7d7e8a882cb 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringBeanAccessor.java +++ b/bpm/bonita-core/bonita-process-engine/src/main/java/org/bonitasoft/engine/service/impl/SpringBeanAccessor.java @@ -29,6 +29,7 @@ import org.springframework.context.ApplicationContext; import org.springframework.core.env.MutablePropertySources; import org.springframework.core.env.PropertiesPropertySource; +import org.springframework.core.env.StandardEnvironment; /** * Spring bean accessor that get its configuration from configuration file in classpath and in database @@ -89,7 +90,20 @@ private void configureContext(BonitaSpringContext context) throws IOException { } MutablePropertySources propertySources = context.getEnvironment().getPropertySources(); - propertySources.addFirst(new PropertiesPropertySource("contextProperties", getProperties())); + final boolean legacyMode = context.getEnvironment().getProperty("bonita.runtime.properties.order.legacy-mode", + boolean.class, false); + if (legacyMode) { + // continue to have properties files from database with the higher priority order. + propertySources.addFirst(new PropertiesPropertySource("contextProperties", getProperties())); + } else { + // Make values from database be easily overridable with default Spring mechanism. + // This is achieved by adding Bonita properties from database with a priority just AFTER + // OS environment variables and Java System properties. + // For default Spring property order, see + // https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.external-config + propertySources.addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, + new PropertiesPropertySource("contextProperties", getProperties())); + } } protected BonitaSpringContext createContext() { diff --git a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-community.xml b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-community.xml index 53abd580bd2..ec9bc5fc502 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-community.xml +++ b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-community.xml @@ -1954,11 +1954,6 @@ - - - - - diff --git a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-tenant-community.properties b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-tenant-community.properties index db8ea00ca59..7404bc21985 100644 --- a/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-tenant-community.properties +++ b/bpm/bonita-core/bonita-process-engine/src/main/resources/bonita-tenant-community.properties @@ -1,6 +1,6 @@ # Bonita Tenant server core configuration -userName=install -userPassword=install +bonita.runtime.admin.username=install +bonita.runtime.admin.password=install # Business data configuration bdm.db.vendor=${sysprop.bonita.bdm.db.vendor:h2} diff --git a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/service/impl/SpringBeanAccessorTest.java b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/service/impl/SpringBeanAccessorTest.java index 1f96055a289..31035fcb01c 100644 --- a/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/service/impl/SpringBeanAccessorTest.java +++ b/bpm/bonita-core/bonita-process-engine/src/test/java/org/bonitasoft/engine/service/impl/SpringBeanAccessorTest.java @@ -122,20 +122,44 @@ public void should_populate_environment_with_properties() { } @Test - public void should_create_context_with_properties_from_database_that_override_env() { + public void should_create_context_with_properties_from_env_that_override_database() { contextProperties.setProperty("myProperty", "databaseValue"); envVar.set("myProperty", "envValue"); createSpringContext(); ApplicationContext context = springBeanAccessor.getContext(); + assertThat(context.getEnvironment().getProperty("myProperty")).isEqualTo("envValue"); + } + + @Test + public void should_create_context_with_properties_from_system_properties_that_override_database() { + contextProperties.setProperty("myProperty", "databaseValue"); + System.setProperty("myProperty", "sysPropValue"); + createSpringContext(); + + ApplicationContext context = springBeanAccessor.getContext(); + + assertThat(context.getEnvironment().getProperty("myProperty")).isEqualTo("sysPropValue"); + } + + @Test + public void should_property_from_database_take_precedence_on_env_if_legacy_mode() { + contextProperties.setProperty("myProperty", "databaseValue"); + envVar.set("myProperty", "envValue"); + envVar.set("BONITA_RUNTIME_PROPERTIES_ORDER_LEGACY_MODE", "true"); + createSpringContext(); + + ApplicationContext context = springBeanAccessor.getContext(); + assertThat(context.getEnvironment().getProperty("myProperty")).isEqualTo("databaseValue"); } @Test - public void should_create_context_with_properties_from_database_that_override_system_properties() { + public void should_property_from_database_take_precedence_on_sysProp_if_legacy_mode() { contextProperties.setProperty("myProperty", "databaseValue"); System.setProperty("myProperty", "sysPropValue"); + System.setProperty("bonita.runtime.properties.order.legacy-mode", "true"); createSpringContext(); ApplicationContext context = springBeanAccessor.getContext(); diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/bdm/BusinessDataModelResource.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/bdm/BusinessDataModelResource.java index 733d5b910f1..37bfcb6d3b7 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/bdm/BusinessDataModelResource.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/bdm/BusinessDataModelResource.java @@ -50,6 +50,9 @@ public BusinessDataModelResource(final TenantAdministrationAPI tenantAdministrat this.tenantAdministrationAPI = tenantAdministrationAPI; } + /** + * @deprecated as of 9.0.0. The BDM should only be updated at startup. + */ @Post("json") @Deprecated(since = "9.0.0") public TenantResourceItem addBDM(final BusinessDataModelItem businessDataModelItem) { diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/page/APIPage.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/page/APIPage.java index 29d86344e6b..d49a892d03f 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/page/APIPage.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/page/APIPage.java @@ -59,12 +59,20 @@ public PageItem get(final APIID id) { return getPageDatastore().get(id); } + /** + * @deprecated as of 9.0.0, a page should be created at startup. + */ @Override + @Deprecated(since = "9.0.0") public PageItem add(final PageItem item) { return getPageDatastore().add(item); } + /** + * @deprecated as of 9.0.0, a page should be updated at startup. + */ @Override + @Deprecated(since = "9.0.0") public PageItem update(final APIID id, final Map attributes) { return getPageDatastore().update(id, attributes); } diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/resource/CommonResource.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/resource/CommonResource.java index da2ab1da1e8..265719fc25f 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/resource/CommonResource.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/api/resource/CommonResource.java @@ -29,6 +29,7 @@ import org.bonitasoft.console.common.server.utils.SessionUtil; import org.bonitasoft.engine.bpm.contract.ContractViolationException; import org.bonitasoft.engine.exception.NotFoundException; +import org.bonitasoft.engine.exception.TenantStatusException; import org.bonitasoft.engine.search.SearchOptions; import org.bonitasoft.engine.search.SearchResult; import org.bonitasoft.engine.session.APISession; @@ -195,6 +196,9 @@ protected void doCatch(final Throwable throwable) { } else if (t instanceof InvalidSessionException) { status = Status.CLIENT_ERROR_UNAUTHORIZED; SessionUtil.sessionLogout(getHttpSession()); + } else if (t instanceof TenantStatusException) { + status = Status.SERVER_ERROR_SERVICE_UNAVAILABLE; + errorMessage.setMessage("Platform is under maintenance"); } else { super.doCatch(t); status = getStatus(); diff --git a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/datastore/page/PageDatastore.java b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/datastore/page/PageDatastore.java index 699ea829615..3fd4d64b145 100644 --- a/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/datastore/page/PageDatastore.java +++ b/bpm/bonita-web-server/src/main/java/org/bonitasoft/web/rest/server/datastore/page/PageDatastore.java @@ -100,6 +100,9 @@ public PageDatastore(final APISession engineSession, final WebBonitaConstantsUti this.pageContentValidator = new CustomPageContentValidator(); } + /** + * @deprecated as of 9.0.0, a page should be created at startup. + */ @Override @Deprecated(since = "9.0.0") public PageItem add(final PageItem pageItem) { @@ -290,6 +293,9 @@ protected SearchResult runSearch(final SearchOptionsCreator creator) return pageAPI.searchPages(creator.create()); } + /** + * @deprecated as of 9.0.0, a page should be updated at startup. + */ @Override @Deprecated(since = "9.0.0") public PageItem update(final APIID id, final Map attributes) { diff --git a/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/resource/CommonResourceTest.java b/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/resource/CommonResourceTest.java index cfad975f2b1..509d681a591 100644 --- a/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/resource/CommonResourceTest.java +++ b/bpm/bonita-web-server/src/test/java/org/bonitasoft/web/rest/server/api/resource/CommonResourceTest.java @@ -27,6 +27,7 @@ import javax.servlet.http.HttpSession; +import org.bonitasoft.engine.exception.TenantStatusException; import org.bonitasoft.engine.session.InvalidSessionException; import org.bonitasoft.web.rest.server.framework.APIServletCall; import org.bonitasoft.web.rest.server.utils.FakeResource; @@ -292,6 +293,17 @@ public void should_respond_400_bad_request_if_IllegalArgumentException_occurs() "{\"exception\":\"class java.lang.IllegalArgumentException\",\"message\":\"an error message\"}'"); } + @Test + public void should_respond_503_service_unavailable_if_TenantStatusException_occurs() throws Exception { + when(fakeService.saySomething()).thenThrow(new TenantStatusException("an error message")); + + final Response response = request("/test").get(); + + assertThat(response).hasStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE); + assertThat(response).hasJsonEntityEqualTo( + "{\"exception\":\"class org.bonitasoft.engine.exception.TenantStatusException\",\"message\":\"Platform is under maintenance\"}'"); + } + @Test public void should_respond_401_unauthorized_if_InvalidSessionException_occurs() throws Exception { when(fakeService.saySomething()).thenThrow(new InvalidSessionException("an error message"));