Skip to content

Commit 60bad80

Browse files
author
Robert Moffat
committed
Second commit of chat workflow
1 parent f9b0f3f commit 60bad80

File tree

83 files changed

+5334
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+5334
-9
lines changed

NOTICE

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
Symphony Java Toolkit - FINOS
2-
Copyright 2019 - 2020 Deutsche Bank AG deutsche-[email protected]
2+
Copyright 2019 - 2020 Deutsche Bank AG symphony-practice@list.db.com
33

44
This product includes software developed at the Fintech Open Source Foundation (https://www.finos.org/) and Deutsche Bank AG.

bindings/pom.xml

-7
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,6 @@
1313
<version>4.59.1-SNAPSHOT</version>
1414
</parent>
1515

16-
<developers>
17-
<developer>
18-
<name>Rob Moffat</name>
19-
<email>[email protected]</email>
20-
</developer>
21-
</developers>
22-
2316
<properties>
2417
<maven.compiler.source>1.8</maven.compiler.source>
2518
<maven.compiler.target>1.8</maven.compiler.target>

chat-workflow/pom.xml

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
<artifactId>chat-workflow</artifactId>
5+
<name>Chat Workflow</name>
6+
<description>Build Workflows Using Enterprise Chat</description>
7+
8+
<parent>
9+
<groupId>com.github.deutschebank.symphony</groupId>
10+
<artifactId>symphony-java-client-parent</artifactId>
11+
<version>4.59.1-SNAPSHOT</version>
12+
</parent>
13+
14+
<properties>
15+
<java.version>1.8</java.version>
16+
<spring-boot.version>2.2.0.RELEASE</spring-boot.version>
17+
</properties>
18+
19+
<dependencies>
20+
<dependency>
21+
<groupId>com.github.deutschebank.symphony</groupId>
22+
<artifactId>symphony-api-spring-boot-starter</artifactId>
23+
<version>4.59.1-SNAPSHOT</version>
24+
</dependency>
25+
<dependency>
26+
<groupId>com.github.deutschebank.symphony</groupId>
27+
<artifactId>symphony-java-client-entity-json</artifactId>
28+
<version>4.59.1-SNAPSHOT</version>
29+
</dependency>
30+
<dependency>
31+
<groupId>com.github.deutschebank.symphony</groupId>
32+
<artifactId>symphony-shared-stream</artifactId>
33+
<version>4.59.1-SNAPSHOT</version>
34+
</dependency>
35+
<dependency>
36+
<groupId>org.springframework.boot</groupId>
37+
<artifactId>spring-boot-starter-web</artifactId>
38+
<version>${spring-boot.version}</version>
39+
</dependency>
40+
<dependency>
41+
<groupId>org.springframework.boot</groupId>
42+
<artifactId>spring-boot-starter-validation</artifactId>
43+
<version>${spring-boot.version}</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>javax.validation</groupId>
47+
<artifactId>validation-api</artifactId>
48+
<version>2.0.1.Final</version>
49+
</dependency>
50+
51+
<!-- allows chat workflow to send attachments -->
52+
<dependency>
53+
<groupId>org.glassfish.jersey.media</groupId>
54+
<artifactId>jersey-media-multipart</artifactId>
55+
<scope>provided</scope>
56+
<version>2.28</version>
57+
</dependency>
58+
59+
<!-- for testing -->
60+
<dependency>
61+
<groupId>org.springframework.boot</groupId>
62+
<artifactId>spring-boot-starter-test</artifactId>
63+
<scope>test</scope>
64+
<version>${spring-boot.version}</version>
65+
</dependency>
66+
67+
</dependencies>
68+
69+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.github.deutschebank.symphony.workflow;
2+
3+
public abstract class AbstractNeedsWorkflow {
4+
5+
protected Workflow wf;
6+
7+
public AbstractNeedsWorkflow(Workflow wf) {
8+
this.wf = wf;
9+
}
10+
11+
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
package com.github.deutschebank.symphony.workflow;
2+
3+
import java.time.Instant;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
import java.util.Optional;
7+
import java.util.Set;
8+
import java.util.stream.Collectors;
9+
10+
import com.github.deutschebank.symphony.workflow.content.Addressable;
11+
import com.github.deutschebank.symphony.workflow.content.Room;
12+
import com.github.deutschebank.symphony.workflow.content.User;
13+
import com.github.deutschebank.symphony.workflow.history.History;
14+
import com.github.deutschebank.symphony.workflow.room.Rooms;
15+
16+
/**
17+
* Represents workflows which can use the state of the conversation, and knows which rooms it is in.
18+
*
19+
* @author Rob Moffat
20+
*
21+
*/
22+
public abstract class AbstractWorkflow implements Workflow {
23+
24+
protected List<History> historyProviders = new ArrayList<History>();;
25+
protected List<Rooms> roomsProviders = new ArrayList<>();
26+
private String namespace;
27+
private List<User> admins;
28+
private Rooms rooms;
29+
private History history;
30+
List<Room> keyRooms;
31+
32+
public AbstractWorkflow(String namespace, List<User> admins, List<Room> keyRooms) {
33+
super();
34+
this.history = createHistoryDelegate();
35+
this.rooms = createRoomsDelegate();
36+
this.keyRooms = keyRooms;
37+
this.admins = admins;
38+
}
39+
40+
@Override
41+
public String getNamespace() {
42+
return namespace;
43+
}
44+
45+
@Override
46+
public Rooms getRoomsApi() {
47+
return rooms;
48+
}
49+
50+
@Override
51+
public History getHistoryApi() {
52+
return history;
53+
}
54+
55+
56+
private Rooms createRoomsDelegate() {
57+
return new Rooms() {
58+
59+
@Override
60+
public Set<Room> getAllRooms() {
61+
return roomsProviders.stream()
62+
.flatMap(rp -> rp.getAllRooms().stream())
63+
.collect(Collectors.toSet());
64+
}
65+
66+
@Override
67+
public Room ensureRoom(Room r) {
68+
return roomsProviders.stream()
69+
.map(rp -> rp.ensureRoom(r))
70+
.findFirst()
71+
.orElseThrow(() -> new UnsupportedOperationException("Couldn't ensure room "+r));
72+
}
73+
};
74+
}
75+
76+
private History createHistoryDelegate() {
77+
return new History() {
78+
79+
@Override
80+
public <X> Optional<X> getLastFromHistory(Class<X> type, Addressable address) {
81+
return historyProviders.stream()
82+
.map(hp -> hp.getLastFromHistory(type, address))
83+
.filter(Optional::isPresent)
84+
.map(Optional::get)
85+
.findFirst();
86+
}
87+
88+
@Override
89+
public <X> List<X> getFromHistory(Class<X> type, Addressable address, Instant since) {
90+
return historyProviders.stream()
91+
.flatMap(hp -> hp.getFromHistory(type, address, since).stream())
92+
.collect(Collectors.toList());
93+
}
94+
95+
};
96+
}
97+
98+
@Override
99+
public List<Room> getKeyRooms() {
100+
return keyRooms;
101+
}
102+
103+
@Override
104+
public List<User> getAdministrators() {
105+
return admins;
106+
}
107+
108+
@Override
109+
public void registerHistoryProvider(History h) {
110+
historyProviders.add(h);
111+
}
112+
113+
@Override
114+
public void registerRoomsProvider(Rooms r) {
115+
roomsProviders.add(r);
116+
}
117+
118+
119+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.github.deutschebank.symphony.workflow;
2+
3+
import java.util.List;
4+
import java.util.Map;
5+
6+
import com.github.deutschebank.symphony.workflow.content.Message;
7+
import com.github.deutschebank.symphony.workflow.content.Room;
8+
import com.github.deutschebank.symphony.workflow.content.User;
9+
import com.github.deutschebank.symphony.workflow.form.Button;
10+
import com.github.deutschebank.symphony.workflow.history.History;
11+
import com.github.deutschebank.symphony.workflow.response.Response;
12+
import com.github.deutschebank.symphony.workflow.room.Rooms;
13+
14+
/**
15+
* A workflow is a collection of steps, which can be triggered by messages posted in a Symphony room.
16+
*
17+
* @author Rob Moffat
18+
*
19+
*/
20+
public interface Workflow {
21+
22+
public String getNamespace();
23+
24+
public Map<String, String> getCommands(Room r);
25+
26+
public List<Response> applyCommand(User u, Room r, String commandName, Object argument, Message m);
27+
28+
List<Button> gatherButtons(Object out, Room r);
29+
30+
public Rooms getRoomsApi();
31+
32+
public History getHistoryApi();
33+
34+
/**
35+
* Important named rooms that must exist for the workflow.
36+
*/
37+
public List<Room> getKeyRooms();
38+
39+
/**
40+
* List of administrators to be set on any rooms that get created.
41+
*/
42+
public List<User> getAdministrators();
43+
44+
/**
45+
* This is the set of classes that will be sent in the "data" payload of the messages used to communicate workflow.
46+
*/
47+
public List<Class<?>> getDataTypes();
48+
49+
public void registerHistoryProvider(History h);
50+
51+
public void registerRoomsProvider(Rooms r);
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.github.deutschebank.symphony.workflow.content;
2+
3+
public interface Addressable {
4+
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.github.deutschebank.symphony.workflow.content;
2+
3+
/**
4+
* Declare this class in a workflow object, and it will get populated automatically with the
5+
* person submitting the object.
6+
*/
7+
public interface Author extends User {
8+
9+
/**
10+
* Keeps track of who is working on the workflow, so we can get the author details back.
11+
*/
12+
public static final ThreadLocal<Author> CURRENT_AUTHOR = new ThreadLocal<>();
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.github.deutschebank.symphony.workflow.content;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
import java.util.Optional;
6+
import java.util.stream.Collectors;
7+
import java.util.stream.StreamSupport;
8+
9+
import com.fasterxml.jackson.annotation.JsonIgnore;
10+
11+
public interface Content {
12+
13+
@JsonIgnore
14+
public String getText();
15+
16+
public default <X extends Content> List<X> only(Class<X> x) {
17+
if (x.isAssignableFrom(this.getClass())) {
18+
return Collections.singletonList((X) this);
19+
} else if (this instanceof Iterable<?>) {
20+
return StreamSupport.stream(((Iterable<Content>) this).spliterator(), false)
21+
.flatMap(i -> i.only(x).stream())
22+
.collect(Collectors.toList());
23+
} else {
24+
return Collections.emptyList();
25+
}
26+
}
27+
28+
public default <X extends Content> Optional<X> getNth(Class<X> x, int n) {
29+
try {
30+
return Optional.of(only(x).get(n));
31+
} catch (Exception e) {
32+
return Optional.empty();
33+
}
34+
}
35+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.github.deutschebank.symphony.workflow.content;
2+
3+
import java.util.UUID;
4+
5+
/**
6+
* This is a special class of tag which is a globally unique ID for the workflow element,
7+
* which can be used to track the evolution of a workflow.
8+
*
9+
* @author Rob Moffat
10+
*
11+
*/
12+
public class ID extends TagDef {
13+
14+
public ID() {
15+
this(UUID.randomUUID());
16+
}
17+
18+
public ID(UUID uuid) {
19+
super(uuid.toString(), uuid.toString(), Type.HASH);
20+
}
21+
}

0 commit comments

Comments
 (0)