工作流的例子
- 目录
- 概述
- 需求:
- 设计思路
- 实现思路分析
- 1.配置bean
- 2.examples
- 3.no bean
- 4.activiti-api-basic-process-example
- 5.task
- spring
- web
- 参考资料和推荐阅读
Survive by day and develop by night.
talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,challenge Survive.
happy for hardess to solve denpendies.
目录
概述
工作流的是一个非常常见的需求。
需求:
设计思路
实现思路分析
1.配置bean
@Bean
public UserDetailsService myUserDetailsService() {
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
String[][] usersGroupsAndRoles = {
{"system", "password", "ROLE_ACTIVITI_USER"},
{"reviewer", "password", "ROLE_ACTIVITI_USER"},
{"admin", "password", "ROLE_ACTIVITI_ADMIN"},
};
for (String[] user : usersGroupsAndRoles) {
List<String> authoritiesStrings = asList(Arrays.copyOfRange(user, 2, user.length));
logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
}
return inMemoryUserDetailsManager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
2.examples
public class Content {
private String body;
private boolean approved;
private List<String> tags;
@JsonCreator
public Content(@JsonProperty("body")String body, @JsonProperty("approved")boolean approved, @JsonProperty("tags")List<String> tags){
this.body = body;
this.approved = approved;
this.tags = tags;
if(this.tags == null){
this.tags = new ArrayList<>();
}
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public boolean isApproved() {
return approved;
}
public void setApproved(boolean approved) {
this.approved = approved;
}
public List<String> getTags() {
return tags;
}
public void setTags(List<String> tags) {
this.tags = tags;
}
@Override
public String toString() {
return "Content{" +
"body='" + body + '\'' +
", approved=" + approved +
", tags=" + tags +
'}';
}
}
3.no bean
@Bean
public UserDetailsService myUserDetailsService() {
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
String[][] usersGroupsAndRoles = {
{"bob", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"john", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"hannah", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"},
{"system", "password", "ROLE_ACTIVITI_USER"},
{"admin", "password", "ROLE_ACTIVITI_ADMIN"},
};
for (String[] user : usersGroupsAndRoles) {
List<String> authoritiesStrings = asList(Arrays.copyOfRange(user, 2, user.length));
logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
}
return inMemoryUserDetailsManager;
}
4.activiti-api-basic-process-example
@Scheduled(initialDelay = 1000, fixedDelay = 1000)
public void processText() {
securityUtil.logInAs("system");
String content = pickRandomString();
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
logger.info("> Processing content: " + content + " at " + formatter.format(new Date()));
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey("categorizeProcess")
.withName("Processing Content: " + content)
.withVariable("content", content)
.build());
logger.info(">>> Created Process Instance: " + processInstance);
}
@Bean
public Connector processTextConnector() {
return integrationContext -> {
Map<String, Object> inBoundVariables = integrationContext.getInBoundVariables();
String contentToProcess = (String) inBoundVariables.get("content");
// Logic Here to decide if content is approved or not
if (contentToProcess.contains("activiti")) {
logger.info("> Approving content: " + contentToProcess);
integrationContext.addOutBoundVariable("approved",
true);
} else {
logger.info("> Discarding content: " + contentToProcess);
integrationContext.addOutBoundVariable("approved",
false);
}
return integrationContext;
};
}
5.task
@Override
public void run(String... args) {
// Using Security Util to simulate a logged in user
securityUtil.logInAs("bob");
// Let's create a Group Task (not assigned, all the members of the group can claim it)
// Here 'bob' is the owner of the created task
logger.info("> Creating a Group Task for 'activitiTeam'");
taskRuntime.create(TaskPayloadBuilder.create()
.withName("First Team Task")
.withDescription("This is something really important")
.withCandidateGroup("activitiTeam")
.withPriority(10)
.build());
// Let's log in as 'other' user that doesn't belong to the 'activitiTeam' group
securityUtil.logInAs("other");
// Let's get all my tasks (as 'other' user)
logger.info("> Getting all the tasks");
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10));
// No tasks are returned
logger.info("> Other cannot see the task: " + tasks.getTotalItems());
// Now let's switch to a user that belongs to the activitiTeam
securityUtil.logInAs("john");
// Let's get 'john' tasks
logger.info("> Getting all the tasks");
tasks = taskRuntime.tasks(Pageable.of(0, 10));
// 'john' can see and claim the task
logger.info("> john can see the task: " + tasks.getTotalItems());
String availableTaskId = tasks.getContent().get(0).getId();
// Let's claim the task, after the claim, nobody else can see the task and 'john' becomes the assignee
logger.info("> Claiming the task");
taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(availableTaskId).build());
// Let's complete the task
logger.info("> Completing the task");
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(availableTaskId).build());
}
spring
@Override
public void run(String... args) {
securityUtil.logInAs("system");
Page<ProcessDefinition> processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
logger.info("> Available Process definitions: " + processDefinitionPage.getTotalItems());
for (ProcessDefinition pd : processDefinitionPage.getContent()) {
logger.info("\t > Process definition: " + pd);
}
}
@Bean
public MessageChannel fileChannel() {
return new DirectChannel();
}
@Bean
@InboundChannelAdapter(value = "fileChannel", poller = @Poller(fixedDelay = "1000"))
public MessageSource<File> fileReadingMessageSource() {
FileReadingMessageSource sourceReader = new FileReadingMessageSource();
sourceReader.setDirectory(new File(INPUT_DIR));
sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN));
return sourceReader;
}
@ServiceActivator(inputChannel = "fileChannel")
public void processFile(Message<File> message) throws IOException {
securityUtil.logInAs("system");
File payload = message.getPayload();
logger.info(">>> Processing file: " + payload.getName());
String content = FileUtils.readFileToString(payload, "UTF-8");
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");
logger.info("> Processing content: " + content + " at " + formatter.format(new Date()));
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey("categorizeProcess")
.withName("Processing Content: " + content)
.withVariable("content", content)
.build());
logger.info(">>> Created Process Instance: " + processInstance);
logger.info(">>> Deleting processed file: " + payload.getName());
payload.delete();
}
@Bean
public Connector processTextConnector() {
return integrationContext -> {
Map<String, Object> inBoundVariables = integrationContext.getInBoundVariables();
String contentToProcess = (String) inBoundVariables.get("content");
// Logic Here to decide if content is approved or not
if (contentToProcess.contains("activiti")) {
logger.info("> Approving content: " + contentToProcess);
integrationContext.addOutBoundVariable("approved",
true);
} else {
logger.info("> Discarding content: " + contentToProcess);
integrationContext.addOutBoundVariable("approved",
false);
}
return integrationContext;
};
}
@Bean
public Connector tagTextConnector() {
return integrationContext -> {
String contentToTag = (String) integrationContext.getInBoundVariables().get("content");
contentToTag += " :) ";
integrationContext.addOutBoundVariable("content",
contentToTag);
logger.info("Final Content: " + contentToTag);
return integrationContext;
};
}
web
public class DemoApplication implements CommandLineRunner {
private ProcessRuntime processRuntime;
public DemoApplication(ProcessRuntime processRuntime) {
this.processRuntime = processRuntime;
}
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@PostMapping("/documents")
public String processFile(@RequestBody String content) {
ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey("categorizeProcess")
.withVariable("fileContent",
content)
.build());
String message = ">>> Created Process Instance: " + processInstance;
System.out.println(message);
return message;
}
@GetMapping("/process-definitions")
public List<ProcessDefinition> getProcessDefinition(){
return processRuntime.processDefinitions(Pageable.of(0, 100)).getContent();
}
@Override
public void run(String... args) {
}
@Bean
public Connector processTextConnector() {
return integrationContext -> {
Map<String, Object> inBoundVariables = integrationContext.getInBoundVariables();
String contentToProcess = (String) inBoundVariables.get("fileContent");
// Logic Here to decide if content is approved or not
if (contentToProcess.contains("activiti")) {
integrationContext.addOutBoundVariable("approved",
true);
} else {
integrationContext.addOutBoundVariable("approved",
false);
}
return integrationContext;
};
}
@Bean
public Connector tagTextConnector() {
return integrationContext -> {
String contentToTag = (String) integrationContext.getInBoundVariables().get("fileContent");
contentToTag += " :) ";
integrationContext.addOutBoundVariable("fileContent",
contentToTag);
System.out.println("Final Content: " + contentToTag);
return integrationContext;
};
}
@Bean
public Connector discardTextConnector() {
return integrationContext -> {
String contentToDiscard = (String) integrationContext.getInBoundVariables().get("fileContent");
contentToDiscard += " :( ";
integrationContext.addOutBoundVariable("fileContent",
contentToDiscard);
System.out.println("Final Content: " + contentToDiscard);
return integrationContext;
};
}
}
参考资料和推荐阅读
[1]. https://github.com/Activiti/Activiti
欢迎阅读,各位老铁,如果对你有帮助,点个赞加个关注呗!~