Skip to content

Commit

Permalink
feat(distro/run): Make deployChangedOnly Configurable
Browse files Browse the repository at this point in the history
Description: The feature allows camunda-run to parameterise the filtering of duplicate resources via a configurable flag.

Feature-flag: This commit introduces the new feature flag `camunda.bpm.run.deployment.deploy-changed-only`
Default-value: `true` (to be backwards compatible with the previously hardcoded behaviour)

Has-refactoring: This commit also refactors the `@CamundaBpmRunConfiguration` and all its dependencies to be simpler and conforming to spring-boot best practices.

Has-unit-tests: This commit adds three test cases for covering the enabling | Disabling | Absence of the new property.

Related-to: camunda#2652
  • Loading branch information
psavidis authored Sep 20, 2024
1 parent 7644178 commit e7941a3
Show file tree
Hide file tree
Showing 11 changed files with 228 additions and 58 deletions.
2 changes: 2 additions & 0 deletions distro/run/assembly/resources/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ camunda.bpm:
allowed-origins: "*"
rest:
disable-wadl: false
deployment:
deploy-changed-only: true
# https://docs.camunda.org/manual/latest/user-guide/camunda-bpm-run/#example-application
example:
enabled: true
Expand Down
1 change: 1 addition & 0 deletions distro/run/assembly/resources/production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ camunda.bpm:
# https://docs.camunda.org/manual/latest/user-guide/camunda-bpm-run/#authentication
auth.enabled: true
rest.disable-wadl: true
deployment.deploy-changed-only: true
# https://docs.camunda.org/manual/latest/user-guide/process-engine/identity-service/#configuration-properties-of-the-ldap-plugin
# https://docs.camunda.org/manual/latest/user-guide/camunda-bpm-run/#ldap-identity-service
# Uncomment this section to enable LDAP support for Camunda Run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,64 +16,55 @@
*/
package org.camunda.bpm.run;

import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.impl.cfg.CompositeProcessEnginePlugin;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.camunda.bpm.engine.impl.plugin.AdministratorAuthorizationPlugin;
import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
import org.camunda.bpm.identity.impl.ldap.plugin.LdapIdentityProviderPlugin;
import org.camunda.bpm.run.property.CamundaBpmRunAdministratorAuthorizationProperties;
import org.camunda.bpm.run.property.CamundaBpmRunLdapProperties;
import org.camunda.bpm.run.property.CamundaBpmRunProcessEnginePluginProperty;
import org.camunda.bpm.run.property.CamundaBpmRunProperties;
import org.camunda.bpm.run.utils.CamundaBpmRunProcessEnginePluginHelper;
import org.camunda.bpm.spring.boot.starter.CamundaBpmAutoConfiguration;
import org.camunda.bpm.spring.boot.starter.configuration.CamundaDeploymentConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@EnableConfigurationProperties(CamundaBpmRunProperties.class)
@Configuration
@AutoConfigureAfter({ CamundaBpmAutoConfiguration.class })
public class CamundaBpmRunConfiguration {

@Autowired
CamundaBpmRunProperties camundaBpmRunProperties;

@Bean
@ConditionalOnProperty(name = "enabled", havingValue = "true", prefix = CamundaBpmRunLdapProperties.PREFIX)
public LdapIdentityProviderPlugin ldapIdentityProviderPlugin() {
return camundaBpmRunProperties.getLdap();
public LdapIdentityProviderPlugin ldapIdentityProviderPlugin(CamundaBpmRunProperties properties) {
return properties.getLdap();
}

@Bean
@ConditionalOnProperty(name = "enabled", havingValue = "true", prefix = CamundaBpmRunAdministratorAuthorizationProperties.PREFIX)
public AdministratorAuthorizationPlugin administratorAuthorizationPlugin() {
return camundaBpmRunProperties.getAdminAuth();
public AdministratorAuthorizationPlugin administratorAuthorizationPlugin(CamundaBpmRunProperties properties) {
return properties.getAdminAuth();
}

@Bean
public ProcessEngineConfigurationImpl processEngineConfigurationImpl(List<ProcessEnginePlugin> processEnginePlugins) {
final SpringProcessEngineConfiguration configuration = new CamundaBpmRunProcessEngineConfiguration();

// register process engine plugins defined in yaml
List<CamundaBpmRunProcessEnginePluginProperty> yamlPluginsInfo = camundaBpmRunProperties.getProcessEnginePlugins();
CamundaBpmRunProcessEnginePluginHelper.registerYamlPlugins(processEnginePlugins, yamlPluginsInfo);
public ProcessEngineConfigurationImpl processEngineConfigurationImpl(List<ProcessEnginePlugin> processEnginePluginsFromContext,
CamundaBpmRunProperties properties,
CamundaBpmRunDeploymentConfiguration deploymentConfig) {
String normalizedDeploymentDir = deploymentConfig.getNormalizedDeploymentDir();
boolean deployChangedOnly = properties.getDeployment().isDeployChangedOnly();
var processEnginePluginsFromYaml = properties.getProcessEnginePlugins();

configuration.getProcessEnginePlugins().add(new CompositeProcessEnginePlugin(processEnginePlugins));
return configuration;
return new CamundaBpmRunProcessEngineConfiguration(normalizedDeploymentDir, deployChangedOnly,
processEnginePluginsFromContext, processEnginePluginsFromYaml);
}

@Bean
public static CamundaDeploymentConfiguration camundaDeploymentConfiguration() {
return new CamundaBpmRunDeploymentConfiguration();
public CamundaBpmRunDeploymentConfiguration camundaDeploymentConfiguration(@Value("${camunda.deploymentDir:#{null}}") String deploymentDir) {
return new CamundaBpmRunDeploymentConfiguration(deploymentDir);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
*/
package org.camunda.bpm.run;

import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultDeploymentConfiguration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand All @@ -25,23 +31,16 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.lang3.StringUtils;
import org.camunda.bpm.spring.boot.starter.configuration.impl.DefaultDeploymentConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

public class CamundaBpmRunDeploymentConfiguration extends DefaultDeploymentConfiguration {

public static final String CAMUNDA_DEPLOYMENT_DIR_PROPERTY = "camunda.deploymentDir";
private final String deploymentDir;

@Autowired
private Environment env;
public CamundaBpmRunDeploymentConfiguration(String deploymentDir) {
this.deploymentDir = deploymentDir;
}

@Override
public Set<Resource> getDeploymentResources() {
String deploymentDir = env.getProperty(CAMUNDA_DEPLOYMENT_DIR_PROPERTY);
if (!StringUtils.isEmpty(deploymentDir)) {
Path resourceDir = Paths.get(deploymentDir);

Expand All @@ -53,4 +52,13 @@ public Set<Resource> getDeploymentResources() {
}
return Collections.emptySet();
}

protected String getNormalizedDeploymentDir() {
String result = deploymentDir;

if(File.separator.equals("\\")) {
result = result.replace("\\", "/");
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,40 @@
*/
package org.camunda.bpm.run;

import jakarta.inject.Inject;
import java.io.File;
import java.io.IOException;
import java.util.Set;

import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.impl.cfg.CompositeProcessEnginePlugin;
import org.camunda.bpm.engine.impl.cfg.ProcessEnginePlugin;
import org.camunda.bpm.engine.impl.diagnostics.CamundaIntegration;
import org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration;
import org.springframework.core.env.Environment;
import org.camunda.bpm.run.property.CamundaBpmRunProcessEnginePluginProperty;
import org.camunda.bpm.run.utils.CamundaBpmRunProcessEnginePluginHelper;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.List;
import java.util.Set;

public class CamundaBpmRunProcessEngineConfiguration extends SpringProcessEngineConfiguration {

private final String normalizedDeploymentDir;

@Inject
private Environment env;
public CamundaBpmRunProcessEngineConfiguration(String normalizedDeploymentDir,
boolean deployChangedOnly,
List<ProcessEnginePlugin> processEnginePluginsFromContext,
List<CamundaBpmRunProcessEnginePluginProperty> processEnginePluginsFromYaml) {
this.normalizedDeploymentDir = normalizedDeploymentDir;

public CamundaBpmRunProcessEngineConfiguration() {
setDeployChangedOnly(true);
setDeployChangedOnly(deployChangedOnly);
configureProcessEnginePlugins(processEnginePluginsFromContext, processEnginePluginsFromYaml);
}

@Override
protected String getFileResourceName(Resource resource) {
// only path relative to the root deployment directory as identifier to
// prevent re-deployments when the path changes (e.g. distro is moved)
try {
String deploymentDir = env.getProperty(CamundaBpmRunDeploymentConfiguration.CAMUNDA_DEPLOYMENT_DIR_PROPERTY);
if(File.separator.equals("\\")) {
deploymentDir = deploymentDir.replace("\\", "/");
}
String resourceAbsolutePath = resource.getURI().toString();
int startIndex = resourceAbsolutePath.indexOf(deploymentDir) + deploymentDir.length();
int startIndex = resourceAbsolutePath.indexOf(normalizedDeploymentDir) + normalizedDeploymentDir.length();
return resourceAbsolutePath.substring(startIndex);
} catch (IOException e) {
throw new ProcessEngineException("Failed to locate resource " + resource.getFilename(), e);
Expand All @@ -60,4 +62,12 @@ protected void initTelemetryData() {
Set<String> camundaIntegration = telemetryData.getProduct().getInternals().getCamundaIntegration();
camundaIntegration.add(CamundaIntegration.CAMUNDA_BPM_RUN);
}

protected void configureProcessEnginePlugins(List<ProcessEnginePlugin> processEnginePluginsFromContext,
List<CamundaBpmRunProcessEnginePluginProperty> processEnginePluginsFromYaml) {
// register process engine plugins defined in yaml
CamundaBpmRunProcessEnginePluginHelper.registerYamlPlugins(processEnginePluginsFromContext, processEnginePluginsFromYaml);

this.processEnginePlugins.add(new CompositeProcessEnginePlugin(processEnginePluginsFromContext));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.camunda.bpm.run.property;

public class CamundaBpmRunDeploymentProperties {

public static final String PREFIX = CamundaBpmRunProperties.PREFIX + ".deployment";

protected boolean deployChangedOnly = true;

public boolean isDeployChangedOnly() {
return deployChangedOnly;
}

public void setDeployChangedOnly(boolean deployChangedOnly) {
this.deployChangedOnly = deployChangedOnly;
}

@Override
public String toString() {
return "CamundaBpmRunDeploymentProperties[" + "deployChangedOnly=" + deployChangedOnly + ']';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.camunda.bpm.run.property;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class CamundaBpmRunProcessEnginePluginProperty {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
*/
package org.camunda.bpm.run.property;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.spring.boot.starter.property.CamundaBpmProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.NestedConfigurationProperty;

import java.util.ArrayList;
import java.util.List;

@ConfigurationProperties(CamundaBpmRunProperties.PREFIX)
public class CamundaBpmRunProperties {

Expand All @@ -45,6 +43,9 @@ public class CamundaBpmRunProperties {
@NestedConfigurationProperty
protected CamundaBpmRunRestProperties rest = new CamundaBpmRunRestProperties();

@NestedConfigurationProperty
protected CamundaBpmRunDeploymentProperties deployment = new CamundaBpmRunDeploymentProperties();

protected CamundaBpmRunAdministratorAuthorizationProperties adminAuth
= new CamundaBpmRunAdministratorAuthorizationProperties();

Expand Down Expand Up @@ -96,6 +97,15 @@ public void setRest(CamundaBpmRunRestProperties rest) {
this.rest = rest;
}

public CamundaBpmRunDeploymentProperties getDeployment() {
return deployment;
}

public void setDeployment(CamundaBpmRunDeploymentProperties deployment) {
this.deployment = deployment;
}


@Override
public String toString() {
return "CamundaBpmRunProperties [" +
Expand All @@ -105,6 +115,7 @@ public String toString() {
", adminAuth=" + adminAuth +
", plugins=" + processEnginePlugins +
", rest=" + rest +
", deployment=" + deployment +
"]";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. Camunda licenses this file to you under the Apache License,
* Version 2.0; you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.camunda.bpm.run.test.config.deploy;

import org.camunda.bpm.run.CamundaBpmRunProcessEngineConfiguration;
import org.camunda.bpm.run.property.CamundaBpmRunDeploymentProperties;
import org.camunda.bpm.run.test.AbstractRestTest;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.TestPropertySource;

import static org.assertj.core.api.Assertions.assertThat;

@TestPropertySource(properties = { CamundaBpmRunDeploymentProperties.PREFIX + ".deploy-changed-only=false" })
public class DeployChangedOnlyDisabledTest extends AbstractRestTest {

@Autowired
private CamundaBpmRunProcessEngineConfiguration engineConfig;

@Test
public void shouldEnableDeployChangedOnlyOnCamundaRunProperty() {
assertThat(engineConfig.isDeployChangedOnly()).isEqualTo(false);
}
}
Loading

0 comments on commit e7941a3

Please sign in to comment.