Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce history level auto, fixes #CAM-3444 #165

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ public abstract class ProcessEngineConfiguration {
*/
public static final String HISTORY_FULL = "full";

/**
* Value for {@link #setHistory(String)}. Choosing auto causes the configuration to choose the level
* already present on the database. If none can be found, "audit" is taken.
*/
public static final String HISTORY_AUTO = "auto";

protected String processEngineName = ProcessEngines.NAME_DEFAULT;
protected int idBlockSize = 100;
protected String history = HISTORY_AUDIT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,14 @@
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.ManagementService;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.ProcessEngines;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.TransactionContextFactory;
import org.camunda.bpm.engine.impl.cmd.OverwriteHistoryLevelCmd;
import org.camunda.bpm.engine.impl.el.ExpressionManager;
import org.camunda.bpm.engine.impl.history.HistoryLevel;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor;
Expand Down Expand Up @@ -66,7 +68,13 @@ public class ProcessEngineImpl implements ProcessEngine {



public ProcessEngineImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
public ProcessEngineImpl(final ProcessEngineConfigurationImpl processEngineConfiguration) {

if (ProcessEngineConfiguration.HISTORY_AUTO.equals(processEngineConfiguration.getHistory())) {
processEngineConfiguration.getCommandExecutorSchemaOperations().execute(new OverwriteHistoryLevelCmd(processEngineConfiguration));
}


this.processEngineConfiguration = processEngineConfiguration;
this.name = processEngineConfiguration.getProcessEngineName();
this.repositoryService = processEngineConfiguration.getRepositoryService();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
*/
package org.camunda.bpm.engine.impl;

import java.util.logging.Logger;

import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
Expand All @@ -25,6 +23,8 @@
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.persistence.entity.PropertyEntity;

import java.util.logging.Logger;

/**
* @author Tom Baeyens
* @author Roman Smirnov
Expand Down Expand Up @@ -72,14 +72,31 @@ public static void dbCreateHistoryLevel(DbEntityManager entityManager) {
log.info("Creating historyLevel property in database with value: " + processEngineConfiguration.getHistory());
}

/**
*
* @param entityManager entoty manager for db query
* @return Integer value representing the history level or <code>null</code> if none found
*/
public static Integer databaseHistoryLevel(DbEntityManager entityManager) {

try {
PropertyEntity historyLevelProperty = entityManager.selectById(PropertyEntity.class, "historyLevel");
return historyLevelProperty != null ? new Integer(historyLevelProperty.getValue()) : null;
} catch (Exception e) {
log.warning("could not select property historyLevel: " + e.getMessage());
return null;
}

}

public void checkHistoryLevel(DbEntityManager entityManager) {
HistoryLevel configuredHistoryLevel = Context.getProcessEngineConfiguration().getHistoryLevel();
PropertyEntity historyLevelProperty = entityManager.selectById(PropertyEntity.class, "historyLevel");
if (historyLevelProperty == null) {

Integer databaseHistoryLevel = databaseHistoryLevel(entityManager);
if (databaseHistoryLevel == null) {
log.info("No historyLevel property found in database.");
dbCreateHistoryLevel(entityManager);
} else {
Integer databaseHistoryLevel = new Integer(historyLevelProperty.getValue());
if (!((Integer) configuredHistoryLevel.getId()).equals(databaseHistoryLevel)) {
throw new ProcessEngineException("historyLevel mismatch: configuration says " + configuredHistoryLevel + " and database says " + databaseHistoryLevel);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.camunda.bpm.engine.impl.ProcessEngineImpl;
import org.camunda.bpm.engine.impl.RepositoryServiceImpl;
import org.camunda.bpm.engine.impl.RuntimeServiceImpl;
import org.camunda.bpm.engine.impl.SchemaOperationsProcessEngineBuild;
import org.camunda.bpm.engine.impl.ServiceImpl;
import org.camunda.bpm.engine.impl.TaskServiceImpl;
import org.camunda.bpm.engine.impl.application.ProcessApplicationManager;
Expand Down Expand Up @@ -140,6 +141,8 @@
import org.camunda.bpm.engine.impl.identity.db.DbIdentityServiceProvider;
import org.camunda.bpm.engine.impl.incident.FailedJobIncidentHandler;
import org.camunda.bpm.engine.impl.incident.IncidentHandler;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.interceptor.CommandContextFactory;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutor;
import org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl;
Expand Down Expand Up @@ -1019,7 +1022,7 @@ protected BpmnDeployer getBpmnDeployer() {

protected List<BpmnParseListener> getDefaultBPMNParseListeners() {
List<BpmnParseListener> defaultListeners = new ArrayList<BpmnParseListener>();
if (!historyLevel.equals(HistoryLevel.HISTORY_LEVEL_NONE)) {
if (!HistoryLevel.HISTORY_LEVEL_NONE.equals(historyLevel)) {
defaultListeners.add(new HistoryParseListener(historyLevel, historyEventProducer));
}
if(isMetricsEnabled) {
Expand Down Expand Up @@ -1058,7 +1061,7 @@ protected CmmnDeployer getCmmnDeployer() {

protected List<CmmnTransformListener> getDefaultCmmnTransformListeners() {
List<CmmnTransformListener> defaultListener = new ArrayList<CmmnTransformListener>();
if (!historyLevel.equals(HistoryLevel.HISTORY_LEVEL_NONE)) {
if (!HistoryLevel.HISTORY_LEVEL_NONE.equals(historyLevel)) {
defaultListener.add(new CmmnHistoryTransformListener(historyLevel, cmmnHistoryEventProducer));
}
if(isMetricsEnabled) {
Expand Down Expand Up @@ -1158,10 +1161,11 @@ public void initHistoryLevel() {
this.historyLevel = historyLevel;
}
}

}

if(historyLevel == null) {

// do allow null for history level in case of "auto"
if(historyLevel == null && !ProcessEngineConfiguration.HISTORY_AUTO.equals(history)) {
throw new ProcessEngineException("invalid history level: "+history);
}
}
Expand Down Expand Up @@ -2594,6 +2598,10 @@ public ProcessEngineConfigurationImpl setCustomHistoryLevels(List<HistoryLevel>
return this;
}

public List<HistoryLevel> getHistoryLevels() {
return historyLevels;
}

public List<HistoryLevel> getCustomHistoryLevels() {
return customHistoryLevels;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.camunda.bpm.engine.impl.cmd;

import org.camunda.bpm.engine.impl.SchemaOperationsProcessEngineBuild;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager;
import org.camunda.bpm.engine.impl.history.HistoryLevel;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;


public class OverwriteHistoryLevelCmd implements Command<Void> {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a good night sleep, I believe calling this "DetermineHistoryLevelCmd" and letting it return a history level would be more intuitive. We would still have to pass the list of available historyLevels, in case the use defined custom ones.


private final ProcessEngineConfigurationImpl processEngineConfiguration;

public OverwriteHistoryLevelCmd(ProcessEngineConfigurationImpl processEngineConfiguration) {
this.processEngineConfiguration = processEngineConfiguration;
}

@Override
public Void execute(CommandContext commandContext) {
final Integer databaseHistoryLevel = SchemaOperationsProcessEngineBuild.databaseHistoryLevel(commandContext.getSession(DbEntityManager.class));


if (databaseHistoryLevel != null) {
for (HistoryLevel historyLevel : processEngineConfiguration.getHistoryLevels()) {
if (historyLevel.getId() == databaseHistoryLevel) {
processEngineConfiguration.setHistoryLevel(historyLevel);
processEngineConfiguration.setHistory(historyLevel.getName());
break;
}
}
}

if (processEngineConfiguration.getHistoryLevel() == null) {
processEngineConfiguration.setHistoryLevel(HistoryLevel.HISTORY_LEVEL_AUDIT);
processEngineConfiguration.setHistory(HistoryLevel.HISTORY_LEVEL_AUDIT.getName());
}

return null;
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,8 @@ public boolean equals(Object obj) {
return true;
}

@Override
public String toString() {
return String.format("%s(name=%s, id=%d)", getClass().getSimpleName(), getName(), getId());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.camunda.bpm.engine.impl.cmd;

import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.impl.ProcessEngineImpl;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration;
import org.camunda.bpm.engine.impl.history.HistoryLevel;
import org.camunda.bpm.engine.impl.test.TestHelper;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.ExternalResource;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;

import static org.junit.Assert.assertThat;

public class OverwriteHistoryLevelCmdTest {


private final ProcessEngineConfigurationImpl config = config("true", ProcessEngineConfiguration.HISTORY_FULL);
private ProcessEngineImpl processEngineImpl;


@Rule
public final ExpectedException thrown = ExpectedException.none();

private static ProcessEngineConfigurationImpl config(final String historyLevel) {

return config("false", historyLevel);
}

private static ProcessEngineConfigurationImpl config(final String schemaUpdate, final String historyLevel) {
final StandaloneInMemProcessEngineConfiguration engineConfiguration = new StandaloneInMemProcessEngineConfiguration();
engineConfiguration.setProcessEngineName(UUID.randomUUID().toString());
engineConfiguration.setDatabaseSchemaUpdate(schemaUpdate);
engineConfiguration.setHistory(historyLevel);
engineConfiguration.setJdbcUrl("jdbc:h2:mem:DatabaseHistoryPropertyAutoTest");

return engineConfiguration;
}


@Test
public void update_history_level_in_configuration() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

processEngineImpl = (ProcessEngineImpl) config.buildProcessEngine();

// we have to invoke init(), or several NPE occur.
ProcessEngineConfigurationImpl secondConfig = config(ProcessEngineConfiguration.HISTORY_AUTO);
final Method init = ProcessEngineConfigurationImpl.class.getDeclaredMethod("init");
init.setAccessible(true);
init.invoke(secondConfig);

config.getCommandExecutorSchemaOperations().execute(new OverwriteHistoryLevelCmd(secondConfig));

assertThat(secondConfig.getHistoryLevel(), CoreMatchers.equalTo(HistoryLevel.HISTORY_LEVEL_FULL));
}



@After
public void after() {
TestHelper.dropSchema(processEngineImpl.getProcessEngineConfiguration());
processEngineImpl.close();
processEngineImpl = null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.camunda.bpm.engine.impl.history;

import org.camunda.bpm.engine.impl.history.event.HistoryEventType;
import org.hamcrest.CoreMatchers;
import org.junit.Assert;
import org.junit.Test;

public class AbstractHistoryLevelTest {


public static class MyHistoryLevel extends AbstractHistoryLevel {

@Override
public int getId() {
return 4711;
}

@Override
public String getName() {
return "myName";
}

@Override
public boolean isHistoryEventProduced(HistoryEventType eventType, Object entity) {
return false;
}
}

@Test
public void ensure_correct_toString() {
Assert.assertThat(new MyHistoryLevel().toString(), CoreMatchers.is("MyHistoryLevel(name=myName, id=4711)"));
}
}