Browse Source

完成工作流部署功能

test
smallchill 6 years ago
parent
commit
fb16c65ae5
  1. 16
      blade-service/blade-flow/pom.xml
  2. 27
      blade-service/blade-flow/src/main/java/org/springblade/flowable/FlowApplication.java
  3. 7
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/config/FlowableConfiguration.java
  4. 81
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/config/SecurityConfiguration.java
  5. 6
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/entity/FlowModel.java
  6. 7
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/mapper/FlowMapper.java
  7. 6
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/mapper/FlowMapper.xml
  8. 95
      blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/service/impl/FlowServiceImpl.java
  9. 6
      blade-service/blade-flow/src/main/resources/application.yml

16
blade-service/blade-flow/pom.xml

@ -50,22 +50,8 @@
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-rest</artifactId>
<artifactId>flowable-json-converter</artifactId>
<version>${flowable.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

27
blade-service/blade-flow/src/main/java/org/springblade/flowable/FlowApplication.java

@ -16,20 +16,10 @@
*/
package org.springblade.flowable;
import org.flowable.ui.common.conf.DevelopmentConfiguration;
import org.springblade.core.cloud.feign.EnableBladeFeign;
import org.springblade.core.launch.BladeApplication;
import org.springblade.core.launch.constant.AppConstant;
import org.springblade.flowable.engine.constant.FlowableConstant;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.cloud.client.SpringCloudApplication;
/**
* Flowable启动器
@ -37,20 +27,7 @@ import org.springframework.context.annotation.FilterType;
* @author Chill
*/
@EnableBladeFeign
@EnableDiscoveryClient
@EnableCircuitBreaker
@SpringBootApplication(
exclude = {
SecurityAutoConfiguration.class,
UserDetailsServiceAutoConfiguration.class,
LiquibaseAutoConfiguration.class,
MultipartAutoConfiguration.class
}
)
@ComponentScan(
basePackages = {AppConstant.BASE_PACKAGES, FlowableConstant.FLOWABLE_BASE_PACKAGES},
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {DevelopmentConfiguration.class})
)
@SpringCloudApplication
public class FlowApplication {
public static void main(String[] args) {

7
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/config/FlowableConfiguration.java

@ -20,9 +20,7 @@ import lombok.AllArgsConstructor;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.flowable.spring.boot.EngineConfigurationConfigurer;
import org.flowable.spring.boot.FlowableProperties;
import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
@ -36,11 +34,6 @@ import org.springframework.context.annotation.Configuration;
public class FlowableConfiguration implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
private FlowableProperties flowableProperties;
@Bean
public FlowableModelerAppProperties flowableModelerAppProperties() {
return new FlowableModelerAppProperties();
}
@Override
public void configure(SpringProcessEngineConfiguration engineConfiguration) {
engineConfiguration.setActivityFontName(flowableProperties.getActivityFontName());

81
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/config/SecurityConfiguration.java

@ -1,81 +0,0 @@
package org.springblade.flowable.engine.config;
import lombok.extern.slf4j.Slf4j;
import org.flowable.ui.common.properties.FlowableRestAppProperties;
import org.flowable.ui.common.security.ActuatorRequestMatcher;
import org.flowable.ui.common.security.DefaultPrivileges;
import org.flowable.ui.modeler.properties.FlowableModelerAppProperties;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.boot.actuate.health.HealthEndpoint;
import org.springframework.boot.actuate.info.InfoEndpoint;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
/**
* SecurityConfiguration
*
* @author Chill
*/
@Slf4j
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected final FlowableRestAppProperties restAppProperties;
protected final FlowableModelerAppProperties modelerAppProperties;
public ApiWebSecurityConfigurationAdapter(FlowableRestAppProperties restAppProperties,
FlowableModelerAppProperties modelerAppProperties) {
this.restAppProperties = restAppProperties;
this.modelerAppProperties = modelerAppProperties;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();
http.antMatcher("/**").authorizeRequests().antMatchers("/**").permitAll();
}
}
@ConditionalOnClass(EndpointRequest.class)
@Configuration
@Order(5)
public static class ActuatorWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.csrf()
.disable();
http
.requestMatcher(new ActuatorRequestMatcher())
.authorizeRequests()
.requestMatchers(EndpointRequest.to(InfoEndpoint.class, HealthEndpoint.class)).authenticated()
.requestMatchers(EndpointRequest.toAnyEndpoint()).hasAnyAuthority(DefaultPrivileges.ACCESS_ADMIN)
.and().httpBasic();
}
}
}

6
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/entity/FlowModel.java

@ -33,6 +33,12 @@ public class FlowModel implements Serializable {
private static final long serialVersionUID = 1L;
public static final int MODEL_TYPE_BPMN = 0;
public static final int MODEL_TYPE_FORM = 2;
public static final int MODEL_TYPE_APP = 3;
public static final int MODEL_TYPE_DECISION_TABLE = 4;
public static final int MODEL_TYPE_CMMN = 5;
private String id;
private String name;
private String modelKey;

7
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/mapper/FlowMapper.java

@ -36,4 +36,11 @@ public interface FlowMapper extends BaseMapper<FlowModel> {
* @return
*/
List<FlowModel> selectFlowPage(IPage page, FlowModel flowModel);
/**
* 获取模型
* @param parentModelId
* @return
*/
List<FlowModel> findByParentModelId(String parentModelId);
}

6
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/mapper/FlowMapper.xml

@ -44,4 +44,10 @@
a.created DESC
</select>
<select id="findByParentModelId" parameterType="string" resultMap="flowModelResultMap">
select model.* from ACT_DE_MODEL_RELATION modelrelation
inner join ACT_DE_MODEL model on modelrelation.model_id = model.id
where modelrelation.parent_model_id = #{parentModelId, jdbcType=VARCHAR}
</select>
</mapper>

95
blade-service/blade-flow/src/main/java/org/springblade/flowable/engine/service/impl/FlowServiceImpl.java

@ -18,13 +18,18 @@ package org.springblade.flowable.engine.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.Process;
import org.flowable.editor.language.json.converter.BpmnJsonConverter;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.ui.modeler.domain.Model;
import org.flowable.ui.modeler.serviceapi.ModelService;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.flowable.engine.constant.FlowableConstant;
@ -34,7 +39,9 @@ import org.springblade.flowable.engine.service.FlowService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 工作流服务实现类
@ -46,8 +53,10 @@ import java.util.List;
@AllArgsConstructor
public class FlowServiceImpl extends ServiceImpl<FlowMapper, FlowModel> implements FlowService {
private static BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();
private static BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
private ObjectMapper objectMapper;
private RepositoryService repositoryService;
private ModelService modelService;
@Override
public IPage<FlowModel> selectFlowPage(IPage<FlowModel> page, FlowModel flowModel) {
@ -56,8 +65,14 @@ public class FlowServiceImpl extends ServiceImpl<FlowMapper, FlowModel> implemen
@Override
public boolean deploy(String modelId, String category) {
Model model = modelService.getModel(modelId);
byte[] bytes = modelService.getBpmnXML(model);
FlowModel model = this.getById(modelId);
if (model == null) {
throw new ServiceException("No model found with the given id: " + modelId);
}
byte[] bytes = getBpmnXML(model);
String processName = model.getName();
if (!StringUtil.endsWithIgnoreCase(processName, FlowableConstant.suffix)) {
@ -67,7 +82,7 @@ public class FlowServiceImpl extends ServiceImpl<FlowMapper, FlowModel> implemen
Deployment deployment = repositoryService.createDeployment()
.addBytes(processName, bytes)
.name(model.getName())
.key(model.getKey())
.key(model.getModelKey())
.deploy();
log.debug("流程部署--------deploy:" + deployment + " 分类---------->" + category);
@ -92,4 +107,72 @@ public class FlowServiceImpl extends ServiceImpl<FlowMapper, FlowModel> implemen
return true;
}
}
private byte[] getBpmnXML(FlowModel model) {
BpmnModel bpmnModel = getBpmnModel(model);
return getBpmnXML(bpmnModel);
}
private byte[] getBpmnXML(BpmnModel bpmnModel) {
for (Process process : bpmnModel.getProcesses()) {
if (StringUtils.isNotEmpty(process.getId())) {
char firstCharacter = process.getId().charAt(0);
// no digit is allowed as first character
if (Character.isDigit(firstCharacter)) {
process.setId("a" + process.getId());
}
}
}
return bpmnXMLConverter.convertToXML(bpmnModel);
}
private BpmnModel getBpmnModel(FlowModel model) {
BpmnModel bpmnModel = null;
try {
Map<String, FlowModel> formMap = new HashMap<>(16);
Map<String, FlowModel> decisionTableMap = new HashMap<>(16);
List<FlowModel> referencedModels = baseMapper.findByParentModelId(model.getId());
for (FlowModel childModel : referencedModels) {
if (FlowModel.MODEL_TYPE_FORM == childModel.getModelType()) {
formMap.put(childModel.getId(), childModel);
} else if (FlowModel.MODEL_TYPE_DECISION_TABLE == childModel.getModelType()) {
decisionTableMap.put(childModel.getId(), childModel);
}
}
bpmnModel = getBpmnModel(model, formMap, decisionTableMap);
} catch (Exception e) {
log.error("Could not generate BPMN 2.0 model for {}", model.getId(), e);
throw new ServiceException("Could not generate BPMN 2.0 model");
}
return bpmnModel;
}
private BpmnModel getBpmnModel(FlowModel model, Map<String, FlowModel> formMap, Map<String, FlowModel> decisionTableMap) {
try {
ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(model.getModelEditorJson());
Map<String, String> formKeyMap = new HashMap<>(16);
for (FlowModel formModel : formMap.values()) {
formKeyMap.put(formModel.getId(), formModel.getModelKey());
}
Map<String, String> decisionTableKeyMap = new HashMap<>(16);
for (FlowModel decisionTableModel : decisionTableMap.values()) {
decisionTableKeyMap.put(decisionTableModel.getId(), decisionTableModel.getModelKey());
}
return bpmnJsonConverter.convertToBpmnModel(editorJsonNode, formKeyMap, decisionTableKeyMap);
} catch (Exception e) {
log.error("Could not generate BPMN 2.0 model for {}", model.getId(), e);
throw new ServiceException("Could not generate BPMN 2.0 model");
}
}
}

6
blade-service/blade-flow/src/main/resources/application.yml

@ -3,9 +3,3 @@ flowable:
label-font-name: \u5B8B\u4F53
annotation-font-name: \u5B8B\u4F53
check-process-definitions: false
common:
app:
idm-url: http://localhost:9999
idm-admin:
user: admin
password: test

Loading…
Cancel
Save