summaryrefslogtreecommitdiff
path: root/calamus-engine/src/main/java/io/trygvis/calamus/engine
diff options
context:
space:
mode:
Diffstat (limited to 'calamus-engine/src/main/java/io/trygvis/calamus/engine')
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusDbConfig.java123
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpm.java80
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpmConfig.java68
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/JenkinsBuildResultMessageListener.java53
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/Main.java28
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/MqClient.java44
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/NexusNewArtifactMessageListener.java111
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/RestartAppWorkItemHandler.java24
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/UpgradeAppWorkItemHandler.java24
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AbstractEntity.java19
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppInstance.java7
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppService.java15
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Artifact.java89
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Process.java40
-rw-r--r--calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/ProcessTrigger.java51
15 files changed, 776 insertions, 0 deletions
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusDbConfig.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusDbConfig.java
new file mode 100644
index 0000000..ad0e5a9
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusDbConfig.java
@@ -0,0 +1,123 @@
+package io.trygvis.calamus.engine;
+
+import bitronix.tm.BitronixTransactionManager;
+import bitronix.tm.TransactionManagerServices;
+import bitronix.tm.resource.jdbc.PoolingDataSource;
+import com.googlecode.flyway.core.Flyway;
+import com.googlecode.flyway.core.api.MigrationInfo;
+import com.googlecode.flyway.core.api.MigrationInfoService;
+import org.jbpm.process.audit.JPAAuditLogService;
+import org.slf4j.Logger;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
+import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+import org.springframework.transaction.jta.JtaTransactionManager;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+import java.util.Date;
+
+import static java.lang.String.format;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * http://planet.jboss.org/post/jbpm_6_with_spring
+ */
+@Configuration
+@EnableTransactionManagement
+public class CalamusDbConfig {
+ private final Logger log = getLogger(getClass());
+
+ @Bean
+ public PoolingDataSource innerDataSource() {
+ PoolingDataSource ds = new PoolingDataSource();
+ ds.setUniqueName("jdbc/jbpm-ds");
+ ds.setClassName(bitronix.tm.resource.jdbc.lrc.LrcXADataSource.class.getCanonicalName());
+ ds.setMaxPoolSize(10);
+ ds.setAllowLocalTransactions(true);
+ ds.getDriverProperties().put("user", "jbpm");
+ ds.getDriverProperties().put("password", "jbpm");
+ ds.getDriverProperties().put("url", "jdbc:postgresql://localhost/jbpm");
+ ds.getDriverProperties().put("driverClassName", org.postgresql.Driver.class.getCanonicalName());
+ ds.init();
+ return ds;
+ }
+
+ @Bean
+ public DataSource dataSource(PoolingDataSource ds) {
+ return new TransactionAwareDataSourceProxy(new LazyConnectionDataSourceProxy(ds));
+ }
+
+ public static class DbMigrations {
+ }
+
+ @Bean
+ public DbMigrations dbMigrations(DataSource dataSource) {
+ runFlyway(log, dataSource, "", "public");
+ return new DbMigrations();
+ }
+
+ private static void runFlyway(Logger log, DataSource dataSource, String prefix, String schema) {
+ log.info("Running migrations for {}", schema);
+
+ Flyway flyway = new Flyway();
+ flyway.setDataSource(dataSource);
+ flyway.setSchemas(schema);
+ flyway.setLocations("db/" + prefix);
+ flyway.setInitOnMigrate(true);
+ MigrationInfoService info = flyway.info();
+ log.info(format("%-15s %-10s %-19s %s", "Version", "State", "Installed on", "Description"));
+ for (MigrationInfo mi : info.all()) {
+ Date installedOn = mi.getInstalledOn();
+ log.info(format("%-15s %-10s %-19s %s",
+ mi.getVersion(),
+ trimToEmpty(mi.getState().getDisplayName()),
+ installedOn != null ? new Date(installedOn.getTime()).toString() : "",
+ trimToEmpty(mi.getDescription())));
+ }
+ flyway.migrate();
+ }
+
+ private static String trimToEmpty(String string) {
+ if (string == null) {
+ return "";
+ }
+
+ return string.trim();
+ }
+
+ @Bean(destroyMethod = "shutdown")
+ public BitronixTransactionManager bitronixTransactionManager() {
+// bitronix.tm.Configuration configuration = TransactionManagerServices.getConfiguration();
+ return TransactionManagerServices.getTransactionManager();
+ }
+
+ @Bean
+ public PlatformTransactionManager platformTransactionManager(BitronixTransactionManager transactionManager) {
+ return new JtaTransactionManager(transactionManager, transactionManager);
+ }
+
+ @Bean
+ public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager) {
+ return new TransactionTemplate(platformTransactionManager);
+ }
+
+ @Bean
+ @DependsOn("dbMigrations")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
+ LocalContainerEntityManagerFactoryBean x = new LocalContainerEntityManagerFactoryBean();
+ x.setPersistenceUnitName("org.jbpm.persistence.jpa");
+ return x;
+ }
+
+ @Bean
+ public JPAAuditLogService jpaAuditLogService(EntityManagerFactory entityManagerFactory) {
+ return new JPAAuditLogService(entityManagerFactory);
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpm.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpm.java
new file mode 100644
index 0000000..af6f489
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpm.java
@@ -0,0 +1,80 @@
+package io.trygvis.calamus.engine;
+
+import org.kie.api.runtime.KieSession;
+import org.kie.api.runtime.manager.RuntimeEngine;
+import org.kie.api.runtime.manager.RuntimeManager;
+import org.kie.api.runtime.process.ProcessInstance;
+import org.kie.internal.runtime.manager.context.ProcessInstanceIdContext;
+import org.slf4j.Logger;
+import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.persistence.EntityManagerFactory;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class CalamusJbpm {
+ private final Logger log = getLogger(getClass());
+
+ private final TransactionTemplate transactionTemplate;
+
+ private final EntityManagerFactory emf;
+
+ private final KieSession session;
+
+ public static enum CalamusProcess {
+ DEPLOY("io.trygvis.bpm.Deploy");
+
+ private String name;
+
+ CalamusProcess(String name) {
+ this.name = name;
+ }
+ }
+
+ public CalamusJbpm() {
+ AnnotationConfigApplicationContext spring = new AnnotationConfigApplicationContext(CalamusDbConfig.class, CalamusJbpmConfig.class);
+
+// emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");
+// Environment env = KnowledgeBaseFactory.newEnvironment();
+// env.set(EnvironmentName.ENTITY_MANAGER_FACTORY, emf);
+// env.set(EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager());
+
+// KieBase kieBase = new KieHelper()
+// .addResource(ResourceFactory.newClassPathResource("Deploy.bpmn2"))
+// .build();
+
+// RuntimeEnvironment runtimeEnvironment = spring.getBean(RuntimeEnvironment.class);
+//
+// KieBase kieBase = runtimeEnvironment.getKieBase();
+
+ transactionTemplate = spring.getBean(TransactionTemplate.class);
+ emf = spring.getBean(EntityManagerFactory.class);
+
+ RuntimeManager runtimeManager = spring.getBean(RuntimeManager.class);
+ RuntimeEngine engine = runtimeManager.getRuntimeEngine(ProcessInstanceIdContext.get());
+ session = engine.getKieSession();
+// session = JPAKnowledgeService.newStatefulKnowledgeSession(kieBase, null, env);
+// session.addEventListener(AuditLoggerFactory.newJPAInstance(env));
+
+// session.getWorkItemManager().registerWorkItemHandler("Service Task", new ServiceTaskHandler());
+// session.getWorkItemManager().registerWorkItemHandler("Upgrade App", new UpgradeAppWorkItemHandler());
+// session.getWorkItemManager().registerWorkItemHandler("Restart App", new RestartAppWorkItemHandler());
+ }
+
+ public TransactionTemplate getTransactionTemplate() {
+ return transactionTemplate;
+ }
+
+ public EntityManagerFactory getEntityManagerFactory() {
+ return emf;
+ }
+
+ public KieSession getSession() {
+ return session;
+ }
+
+ public void startProcess(CalamusProcess process) {
+ ProcessInstance processInstance = session.startProcess(process.name);
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpmConfig.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpmConfig.java
new file mode 100644
index 0000000..edfda28
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/CalamusJbpmConfig.java
@@ -0,0 +1,68 @@
+package io.trygvis.calamus.engine;
+
+import org.jbpm.process.audit.JPAAuditLogService;
+import org.kie.api.io.Resource;
+import org.kie.api.io.ResourceType;
+import org.kie.api.runtime.manager.RuntimeEnvironment;
+import org.kie.api.runtime.manager.RuntimeManager;
+import org.kie.internal.io.ResourceFactory;
+import org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean;
+import org.kie.spring.factorybeans.RuntimeManagerFactoryBean;
+import org.slf4j.Logger;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * http://planet.jboss.org/post/jbpm_6_with_spring
+ */
+@Configuration
+public class CalamusJbpmConfig {
+ private final Logger log = getLogger(getClass());
+
+ @Bean
+ @Lazy
+ public RuntimeEnvironmentFactoryBean runtimeEnvironment(DataSource dataSource, CalamusDbConfig.DbMigrations dbMigrations, EntityManagerFactory entityManagerFactory, PlatformTransactionManager platformTransactionManager) {
+ System.out.println("CalamusConfig.runtimeEnvironmentFactoryBean");
+ System.out.println("dataSource = " + dataSource);
+ System.out.println("dbMigrations = " + dbMigrations);
+ System.out.println("entityManagerFactory = " + entityManagerFactory);
+ System.out.println("platformTransactionManager = " + platformTransactionManager);
+ RuntimeEnvironmentFactoryBean x = new RuntimeEnvironmentFactoryBean();
+ x.setType("DEFAULT");
+
+ Map<Resource, ResourceType> assets = new HashMap<>();
+ System.out.println("getClass().getClassLoader() = " + getClass().getClassLoader());
+ assets.put(ResourceFactory.newClassPathResource("Deploy.bpmn2", getClass()), ResourceType.BPMN2);
+ x.setAssets(assets);
+// x.setClassLoader(getClass().getClassLoader());
+
+ x.setEntityManagerFactory(entityManagerFactory);
+ x.setTransactionManager(platformTransactionManager);
+
+ return x;
+ }
+
+ @Bean
+ @Lazy
+ public RuntimeManager runtimeManagerFactoryBean(RuntimeEnvironment runtimeEnvironment) throws Exception {
+ RuntimeManagerFactoryBean x = new RuntimeManagerFactoryBean();
+ x.setIdentifier("spring-rm");
+ x.setRuntimeEnvironment(runtimeEnvironment);
+ x.afterPropertiesSet();
+ return (RuntimeManager) x.getObject();
+ }
+
+ @Bean
+ public JPAAuditLogService jpaAuditLogService(EntityManagerFactory entityManagerFactory) {
+ return new JPAAuditLogService(entityManagerFactory);
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/JenkinsBuildResultMessageListener.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/JenkinsBuildResultMessageListener.java
new file mode 100644
index 0000000..39ac6e3
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/JenkinsBuildResultMessageListener.java
@@ -0,0 +1,53 @@
+package io.trygvis.calamus.engine;
+
+import org.kie.api.runtime.KieSession;
+import org.slf4j.Logger;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Properties;
+
+import static java.lang.Integer.parseInt;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class JenkinsBuildResultMessageListener implements MessageListener {
+ private final Logger log = getLogger(getClass());
+
+ private KieSession session;
+
+ public JenkinsBuildResultMessageListener(KieSession session) {
+ this.session = session;
+ }
+
+ @Override
+ public void onMessage(Message message) {
+ if (!(message instanceof TextMessage)) {
+ return;
+ }
+
+ try {
+ TextMessage m = (TextMessage) message;
+ Properties p = new Properties();
+ p.load(new StringReader(m.getText()));
+
+ String jobName = p.getProperty("jobName");
+ int buildNumber = parseInt(p.getProperty("buildNumber"));
+ String result = p.getProperty("result");
+
+ log.info("New build: jobName={}, buildNumber={}, result={}", jobName, buildNumber, result);
+
+ /*
+ String type;
+ Object event;
+ long processInstanceId;
+ jbpm.signalEvent(type, event, processInstanceId);
+ */
+ } catch (JMSException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/Main.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/Main.java
new file mode 100644
index 0000000..daa4886
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/Main.java
@@ -0,0 +1,28 @@
+package io.trygvis.calamus.engine;
+
+import org.kie.api.runtime.KieSession;
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+
+ CalamusJbpm calamus = new CalamusJbpm();
+
+ String brokerUrl = "tcp://localhost:61616";
+
+ KieSession session = calamus.getSession();
+
+// EntityManager entityManager = calamus.getEntityManagerFactory().createEntityManager();
+// EntityTransaction transaction = entityManager.getTransaction();
+// transaction.begin();
+// entityManager.createQuery("FROM Process");
+// transaction.commit();
+
+ try (MqClient buildResultClient = new MqClient(brokerUrl, "jenkins.build-result", new JenkinsBuildResultMessageListener(session));
+ MqClient newDeployClient = new MqClient(brokerUrl, "nexus.new-artifact", new NexusNewArtifactMessageListener(calamus.getTransactionTemplate(), calamus.getEntityManagerFactory(), session))) {
+
+ while (true) {
+ Thread.sleep(1000);
+ }
+ }
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/MqClient.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/MqClient.java
new file mode 100644
index 0000000..0cb33ad
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/MqClient.java
@@ -0,0 +1,44 @@
+package io.trygvis.calamus.engine;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+
+import static java.lang.Integer.parseInt;
+import static javax.jms.Session.AUTO_ACKNOWLEDGE;
+
+public class MqClient implements AutoCloseable {
+
+ private Connection connection;
+
+ public MqClient(String brokerUrl, String queueName, MessageListener messageListener) {
+ ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
+
+ try {
+ connection = connectionFactory.createConnection();
+ connection.start();
+
+ Session session = connection.createSession(false, AUTO_ACKNOWLEDGE);
+
+ Destination destination = session.createQueue(queueName);
+
+ MessageConsumer consumer = session.createConsumer(destination);
+ consumer.setMessageListener(messageListener);
+ } catch (JMSException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void close() throws Exception {
+ if (connection != null) {
+ connection.close();
+ this.connection = null;
+ }
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/NexusNewArtifactMessageListener.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/NexusNewArtifactMessageListener.java
new file mode 100644
index 0000000..ab111d7
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/NexusNewArtifactMessageListener.java
@@ -0,0 +1,111 @@
+package io.trygvis.calamus.engine;
+
+import io.trygvis.calamus.engine.domain.Artifact;
+import io.trygvis.calamus.engine.domain.Process;
+import io.trygvis.calamus.engine.domain.ProcessTrigger;
+import org.kie.api.runtime.KieSession;
+import org.slf4j.Logger;
+import org.springframework.transaction.TransactionStatus;
+import org.springframework.transaction.support.TransactionCallbackWithoutResult;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.TextMessage;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.NoResultException;
+import javax.persistence.TypedQuery;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Map;
+import java.util.Properties;
+
+import static java.util.Collections.singletonMap;
+import static org.slf4j.LoggerFactory.getLogger;
+
+public class NexusNewArtifactMessageListener implements MessageListener {
+ private final Logger log = getLogger(getClass());
+
+ private final TransactionTemplate transactionTemplate;
+ private final EntityManagerFactory entityManagerFactory;
+ private final KieSession session;
+
+ public NexusNewArtifactMessageListener(TransactionTemplate transactionTemplate, EntityManagerFactory entityManagerFactory, KieSession session) {
+ this.transactionTemplate = transactionTemplate;
+ this.entityManagerFactory = entityManagerFactory;
+ this.session = session;
+ }
+
+ @Override
+ public void onMessage(Message message) {
+ if (!(message instanceof TextMessage)) {
+ return;
+ }
+
+ try {
+ TextMessage m = (TextMessage) message;
+ Properties p = new Properties();
+ p.load(new StringReader(m.getText()));
+
+ String repository = p.getProperty("repository");
+ String groupId = p.getProperty("groupId");
+ String artifactId = p.getProperty("artifactId");
+ String version = p.getProperty("version");
+ String classifier = p.getProperty("classifier");
+ String extension = p.getProperty("extension");
+
+ log.info("Artifact event: groupId={}, artifactId={}, version={}, classifier={}, extension={}", groupId, artifactId, version, classifier, extension);
+
+ transactionTemplate.execute(new TransactionCallbackWithoutResult() {
+ @Override
+ protected void doInTransactionWithoutResult(TransactionStatus status) {
+ processMessage(groupId, artifactId, version, classifier, extension);
+ }
+ });
+ } catch (JMSException | IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ private void processMessage(String groupId, String artifactId, String version, String classifier, String extension) {
+ // Check for any processes that will be started because of this
+ EntityManager entityManager = entityManagerFactory.createEntityManager();
+
+ TypedQuery<Artifact> query = entityManager.createQuery("FROM Artifact WHERE groupId=:groupId AND artifactId=:artifactId AND version=:version AND extension=:extension", Artifact.class);
+ query.setParameter("groupId", groupId);
+ query.setParameter("artifactId", artifactId);
+ query.setParameter("version", version);
+ query.setParameter("extension", extension);
+ Artifact artifact;
+ try {
+ artifact = query.getSingleResult();
+ log.info("Existing artifact: {}", artifact);
+ } catch (NoResultException e) {
+ artifact = new Artifact(groupId, artifactId, version, classifier, extension);
+ log.info("New artifact: {}", artifact);
+ entityManager.persist(artifact);
+ }
+
+ for (Process process : entityManager.createQuery("FROM Process", Process.class).getResultList()) {
+ System.out.println("process.name = " + process.getName());
+
+ for (ProcessTrigger trigger : process.getProcessTriggers()) {
+ System.out.println("trigger.getMvel() = " + trigger.getMvel());
+ boolean match = trigger.matches(artifact);
+ System.out.println("match = " + match);
+
+ Map<String, Object> parameters = singletonMap("artifact", artifact);
+ session.startProcess(process.getJbpmProcessId(), parameters);
+ }
+ }
+
+ /*
+ String type;
+ Object event;
+ long processInstanceId;
+ jbpm.signalEvent(type, event, processInstanceId);
+ */
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/RestartAppWorkItemHandler.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/RestartAppWorkItemHandler.java
new file mode 100644
index 0000000..0706cf1
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/RestartAppWorkItemHandler.java
@@ -0,0 +1,24 @@
+package io.trygvis.calamus.engine;
+
+import org.kie.api.runtime.process.WorkItem;
+import org.kie.api.runtime.process.WorkItemHandler;
+import org.kie.api.runtime.process.WorkItemManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class RestartAppWorkItemHandler implements WorkItemHandler {
+
+ @Override
+ public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+ System.out.println("RestartAppWorkItemHandler.executeWorkItem");
+
+ Map<String, Object> results = new HashMap<>();
+ manager.completeWorkItem(workItem.getId(), results);
+ }
+
+ @Override
+ public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+ System.out.println("RestartAppWorkItemHandler.abortWorkItem");
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/UpgradeAppWorkItemHandler.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/UpgradeAppWorkItemHandler.java
new file mode 100644
index 0000000..32da945
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/UpgradeAppWorkItemHandler.java
@@ -0,0 +1,24 @@
+package io.trygvis.calamus.engine;
+
+import org.kie.api.runtime.process.WorkItem;
+import org.kie.api.runtime.process.WorkItemHandler;
+import org.kie.api.runtime.process.WorkItemManager;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class UpgradeAppWorkItemHandler implements WorkItemHandler {
+
+ @Override
+ public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
+ System.out.println("UpgradeAppWorkItemHandler.executeWorkItem");
+
+ Map<String, Object> results = new HashMap<>();
+ manager.completeWorkItem(workItem.getId(), results);
+ }
+
+ @Override
+ public void abortWorkItem(WorkItem workItem, WorkItemManager manager) {
+ System.out.println("UpgradeAppWorkItemHandler.abortWorkItem");
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AbstractEntity.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AbstractEntity.java
new file mode 100644
index 0000000..655b1cc
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AbstractEntity.java
@@ -0,0 +1,19 @@
+package io.trygvis.calamus.engine.domain;
+
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.SequenceGenerator;
+
+@MappedSuperclass
+public abstract class AbstractEntity {
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "calamusSeq")
+ @SequenceGenerator(name = "calamusSeq", sequenceName = "calamus_seq")
+ private Long id;
+
+ public Long getId() {
+ return id;
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppInstance.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppInstance.java
new file mode 100644
index 0000000..aa2ea14
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppInstance.java
@@ -0,0 +1,7 @@
+package io.trygvis.calamus.engine.domain;
+
+public class AppInstance {
+ private String name;
+ private String host;
+ private String path;
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppService.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppService.java
new file mode 100644
index 0000000..da606a4
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/AppService.java
@@ -0,0 +1,15 @@
+package io.trygvis.calamus.engine.domain;
+
+public class AppService {
+ public void installApp(AppInstance instance) {
+ System.out.println("AppService.installApp");
+ }
+
+ public void restartApp(AppInstance instance) {
+ System.out.println("AppService.restartApp");
+ }
+
+ public void waitForUp(AppInstance instance) {
+ System.out.println("AppService.waitForAppUp");
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Artifact.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Artifact.java
new file mode 100644
index 0000000..34631ab
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Artifact.java
@@ -0,0 +1,89 @@
+package io.trygvis.calamus.engine.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import java.util.Optional;
+
+import static io.trygvis.calamus.engine.domain.Artifact.Level.UNTESTED;
+import static java.util.Optional.ofNullable;
+
+@Entity
+public class Artifact extends AbstractEntity {
+ @Column(length = 100, nullable = false)
+ private String groupId;
+
+ @Column(length = 100, nullable = false)
+ private String artifactId;
+
+ @Column(length = 100, nullable = false)
+ private String version;
+
+ @Column(length = 100)
+ private String classifier;
+
+ @Column(length = 100, nullable = false)
+ private String extension;
+
+ @Column(nullable = false)
+ private Level level;
+
+ @Column(length = 40)
+ private String gitHash;
+
+ public enum Level {
+ UNTESTED
+ }
+
+ protected Artifact() {
+ }
+
+ public Artifact(String groupId, String artifactId, String version, String classifier, String extension) {
+ this.groupId = groupId;
+ this.artifactId = artifactId;
+ this.version = version;
+ this.classifier = classifier;
+ this.extension = extension;
+ this.level = UNTESTED;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public Optional<String> getClassifier() {
+ return ofNullable(classifier);
+ }
+
+ public String getExtension() {
+ return extension;
+ }
+
+ public Level getLevel() {
+ return level;
+ }
+
+ public String getGitHash() {
+ return gitHash;
+ }
+
+ @Override
+ public String toString() {
+ return "Artifact{" +
+ "groupId='" + groupId + '\'' +
+ ", artifactId='" + artifactId + '\'' +
+ ", version='" + version + '\'' +
+ ", classifier='" + classifier + '\'' +
+ ", extension='" + extension + '\'' +
+ ", level='" + level + '\'' +
+ ", gitHash='" + gitHash + '\'' +
+ "} " + super.toString();
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Process.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Process.java
new file mode 100644
index 0000000..c1f0b49
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/Process.java
@@ -0,0 +1,40 @@
+package io.trygvis.calamus.engine.domain;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.OneToMany;
+import java.util.ArrayList;
+import java.util.List;
+
+@Entity
+public class Process extends AbstractEntity {
+
+ @Column(length = 100, nullable = false)
+ private String name;
+
+ @Column(length = 100, nullable = false)
+ private String jbpmProcessId;
+
+ @OneToMany(mappedBy = "process")
+ private List<ProcessTrigger> processTriggers = new ArrayList<>();
+
+ public String getName() {
+ return name;
+ }
+
+ public String getJbpmProcessId() {
+ return jbpmProcessId;
+ }
+
+ public List<ProcessTrigger> getProcessTriggers() {
+ return processTriggers;
+ }
+
+ @Override
+ public String toString() {
+ return "Process{" +
+ "name='" + name + '\'' +
+ ", jbpmProcessId='" + jbpmProcessId + '\'' +
+ "} " + super.toString();
+ }
+}
diff --git a/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/ProcessTrigger.java b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/ProcessTrigger.java
new file mode 100644
index 0000000..b26f6ca
--- /dev/null
+++ b/calamus-engine/src/main/java/io/trygvis/calamus/engine/domain/ProcessTrigger.java
@@ -0,0 +1,51 @@
+package io.trygvis.calamus.engine.domain;
+
+import org.mvel2.MVEL;
+import org.mvel2.ParserContext;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.ManyToOne;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+@Entity
+public class ProcessTrigger extends AbstractEntity {
+
+ @ManyToOne
+ private Process process;
+
+ @Column(length = 1000)
+ private String mvel;
+
+ transient Serializable expression;
+
+ public Process getProcess() {
+ return process;
+ }
+
+ public String getMvel() {
+ return mvel;
+ }
+
+ // -----------------------------------------------------------------------
+ //
+ // -----------------------------------------------------------------------
+
+ private Serializable getExpression() {
+ if (expression != null) {
+ return expression;
+ }
+ ParserContext ctx = new ParserContext();
+ ctx.setStrongTyping(true);
+ ctx.addInput("artifact", Artifact.class);
+ return expression = MVEL.compileExpression(mvel, ctx);
+ }
+
+ public boolean matches(Artifact artifact) {
+ Map<String, Object> vars = new HashMap<>();
+ vars.put("artifact", artifact);
+ return MVEL.executeExpression(getExpression(), vars, Boolean.class);
+ }
+}