Skip to content

Commit d2b8341

Browse files
committed
Adding Maestro code examples
1 parent 2a8102f commit d2b8341

24 files changed

+1435
-30
lines changed

src/main/java/com/docusign/common/ApiIndex.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public enum ApiIndex {
1010
NAVIGATOR("/pages/navigator/index", "/restapi", "/nav001", "/nav"),
1111
NOTARY("/pages/notary/index", "/restapi", "/n004", "/n"),
1212
WEBFORMS("/pages/webforms/index", "/restapi", "/web001", "/web"),
13+
MAESTRO("/pages/maestro/index", "/restapi", "/mae001", "/mae"),
1314
CONNECTEDFIELDS("/pages/connectedfields/index", "/restapi", "/cf001", "/cf");
1415

1516
private final String indexPath;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.docusign.controller.maestro.examples;
2+
3+
import com.docusign.DSConfiguration;
4+
import com.docusign.core.controller.AbstractController;
5+
import com.docusign.core.model.Session;
6+
import com.docusign.core.model.User;
7+
import com.docusign.iam.sdk.IamClient;
8+
import com.fasterxml.jackson.databind.ObjectMapper;
9+
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
10+
import org.springframework.stereotype.Controller;
11+
12+
/**
13+
* Abstract base class for all Maestro fields controllers.
14+
*/
15+
@Controller
16+
public abstract class AbstractMaestroController extends AbstractController {
17+
18+
private static final String EXAMPLE_PAGES_PATH = "pages/maestro/examples/";
19+
20+
protected final User user;
21+
22+
protected final Session session;
23+
24+
public AbstractMaestroController(DSConfiguration config, String exampleName, User user, Session session) {
25+
super(config, exampleName);
26+
this.user = user;
27+
this.session = session;
28+
}
29+
30+
protected IamClient createAuthenticatedClient(String accessToken) {
31+
return IamClient.builder()
32+
.accessToken(accessToken)
33+
.build();
34+
}
35+
36+
protected String serializeObjectToJson(Object data) throws Exception {
37+
ObjectMapper mapper = new ObjectMapper();
38+
mapper.registerModule(new Jdk8Module());
39+
40+
return mapper.writeValueAsString(data);
41+
}
42+
43+
protected String getExamplePagesPath() {
44+
return AbstractMaestroController.EXAMPLE_PAGES_PATH;
45+
}
46+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.docusign.controller.maestro.examples;
2+
3+
import com.docusign.DSConfiguration;
4+
import com.docusign.common.WorkArguments;
5+
import com.docusign.controller.maestro.services.TriggerWorkflowService;
6+
import com.docusign.core.model.Session;
7+
import com.docusign.core.model.User;
8+
import org.springframework.stereotype.Controller;
9+
import org.springframework.ui.ModelMap;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
12+
import javax.servlet.http.HttpServletResponse;
13+
import java.util.Optional;
14+
15+
/**
16+
* This example demonstrates how to trigger maestro workflow.
17+
*/
18+
@Controller
19+
@RequestMapping("/mae001")
20+
public class Mae001TriggerWorkflowController extends AbstractMaestroController {
21+
public static final String EMBED = "pages/maestro/examples/embed";
22+
23+
private static final String MAESTRO_WORKFLOW_CONFIG = "maestro-workflow-definition.json";
24+
25+
public static final String URL = "url";
26+
27+
private static final String TEMPLATE_ID = "templateId";
28+
29+
private static final String WORKFLOW_ID = "workflowId";
30+
31+
private static final String PUBLISH_LINK = "publishLink";
32+
33+
public static final String WORKFLOW_NAME = "Example workflow - send invite to signer";
34+
35+
public static final String STATUS = "active";
36+
37+
public Mae001TriggerWorkflowController(DSConfiguration config, Session session, User user) {
38+
super(config, "mae001", user, session);
39+
}
40+
41+
@Override
42+
protected void onInitModel(WorkArguments args, ModelMap model) throws Exception {
43+
super.onInitModel(args, model);
44+
45+
try {
46+
ensureWorkflowExists(model);
47+
} catch(Exception exception) {
48+
throw new Exception(getTextForCodeExampleByApiType().CustomErrorTexts.get(0).ErrorMessage);
49+
}
50+
51+
model.addAttribute(TEMPLATE_ID, session.getTemplateId());
52+
model.addAttribute(WORKFLOW_ID, session.getWorkflowId());
53+
}
54+
55+
@Override
56+
protected Object doWork(
57+
WorkArguments args,
58+
ModelMap model,
59+
HttpServletResponse response
60+
) throws Exception{
61+
var accountId = session.getAccountId();
62+
var accessToken = user.getAccessToken();
63+
var client = createAuthenticatedClient(accessToken);
64+
65+
var triggerResponse = TriggerWorkflowService.triggerWorkflowInstance(
66+
client,
67+
accountId,
68+
session.getWorkflowId(),
69+
args.getSignerEmail(),
70+
args.getSignerName(),
71+
args.getCcEmail(),
72+
args.getCcName(),
73+
args.getInstanceName());
74+
75+
triggerResponse.triggerWorkflowSuccess().ifPresent(success -> {
76+
session.setInstanceId(success.instanceId().orElse(null));
77+
model.addAttribute(URL, success.instanceUrl().orElse(""));
78+
});
79+
80+
model.addAttribute(LAUNCHER_TEXTS, config.getCodeExamplesText().SupportingTexts);
81+
model.addAttribute("example", this.getTextForCodeExample());
82+
83+
return EMBED;
84+
}
85+
86+
private void ensureWorkflowExists(ModelMap model) throws Exception {
87+
var accountId = session.getAccountId();
88+
var accessToken = user.getAccessToken();
89+
var templateId = session.getTemplateId();
90+
91+
if (session.getWorkflowId() == null) {
92+
findActiveWorkflow(accessToken, accountId)
93+
.ifPresent(workflowId -> session.setWorkflowId(workflowId));
94+
}
95+
96+
if (session.getIsWorkflowPublished()) {
97+
publishAndSetLink(model, accessToken, accountId, session.getWorkflowId());
98+
}
99+
100+
if (session.getWorkflowId() == null && templateId != null) {
101+
var workflowId = TriggerWorkflowService.createWorkflow(accessToken, accountId, templateId, MAESTRO_WORKFLOW_CONFIG);
102+
103+
session.setWorkflowId(workflowId);
104+
session.setIsWorkflowPublished(true);
105+
106+
publishAndSetLink(model, accessToken, accountId, workflowId);
107+
}
108+
}
109+
110+
private Optional<String> findActiveWorkflow(String accessToken, String accountId) throws Exception {
111+
var client = createAuthenticatedClient(accessToken);
112+
var workflowsResponse = TriggerWorkflowService.getMaestroWorkflow(client, accountId);
113+
114+
return workflowsResponse.workflowsListSuccess().stream()
115+
.filter(w -> w.data().isPresent())
116+
.flatMap(w -> w.data().orElseThrow().stream())
117+
.filter(workflow -> workflow.name().orElseThrow().equals(WORKFLOW_NAME))
118+
.map(workflow -> workflow.id().orElse(null))
119+
.findFirst();
120+
}
121+
122+
private void publishAndSetLink(ModelMap model, String accessToken, String accountId, String workflowId) throws Exception {
123+
String publishLink = TriggerWorkflowService.publishWorkflow(accessToken, accountId, workflowId);
124+
125+
if (!publishLink.isEmpty()) {
126+
String linkText = getTextForCodeExampleByApiType()
127+
.getAdditionalPage()
128+
.get(0)
129+
.getResultsPageText()
130+
.replaceFirst("\\{0}", publishLink);
131+
132+
model.addAttribute(PUBLISH_LINK, linkText);
133+
} else {
134+
session.setIsWorkflowPublished(false);
135+
}
136+
}
137+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.docusign.controller.maestro.examples;
2+
3+
import com.docusign.DSConfiguration;
4+
import com.docusign.common.WorkArguments;
5+
import com.docusign.controller.maestro.services.PauseWorkflowService;
6+
import com.docusign.core.model.DoneExample;
7+
import com.docusign.core.model.Session;
8+
import com.docusign.core.model.User;
9+
import org.springframework.stereotype.Controller;
10+
import org.springframework.ui.ModelMap;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
13+
import javax.servlet.http.HttpServletResponse;
14+
15+
/**
16+
* This example demonstrates how to pause workflow.
17+
*/
18+
@Controller
19+
@RequestMapping("/mae002")
20+
public class Mae002PauseWorkflowController extends AbstractMaestroController {
21+
22+
private static final String MODEL_IS_WORKFLOW_ID_PRESENT = "isWorkflowIdPresent";
23+
24+
public static final String NO_WORKFLOW_AVAILABLE_TO_PAUSE = "No workflow available to pause.";
25+
26+
public Mae002PauseWorkflowController(DSConfiguration config, Session session, User user) {
27+
super(config, "mae002", user, session);
28+
}
29+
30+
@Override
31+
protected void onInitModel(WorkArguments args, ModelMap model) throws Exception {
32+
super.onInitModel(args, model);
33+
model.addAttribute(MODEL_IS_WORKFLOW_ID_PRESENT, session.getWorkflowId() != null );
34+
}
35+
36+
@Override
37+
protected Object doWork(
38+
WorkArguments args,
39+
ModelMap model,
40+
HttpServletResponse response
41+
) throws Exception{
42+
var accountId = session.getAccountId();
43+
var accessToken = user.getAccessToken();
44+
var workflowId = session.getWorkflowId();
45+
var client = createAuthenticatedClient(accessToken);
46+
47+
if (workflowId == null) {
48+
throw new IllegalStateException(NO_WORKFLOW_AVAILABLE_TO_PAUSE);
49+
}
50+
51+
var paused = PauseWorkflowService.PauseMaestroWorkflow(
52+
client,
53+
accountId,
54+
workflowId);
55+
var jsonResponse = serializeObjectToJson(paused.pauseNewWorkflowInstancesSuccess().orElseThrow());
56+
57+
DoneExample.createDefault(getTextForCodeExampleByApiType().ExampleName)
58+
.withMessage(getTextForCodeExampleByApiType().ResultsPageText)
59+
.withJsonObject(jsonResponse)
60+
.addToModel(model, config);
61+
62+
return DONE_EXAMPLE_PAGE;
63+
}
64+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.docusign.controller.maestro.examples;
2+
3+
import com.docusign.DSConfiguration;
4+
import com.docusign.common.WorkArguments;
5+
import com.docusign.controller.maestro.services.ResumeWorkflowService;
6+
import com.docusign.core.model.DoneExample;
7+
import com.docusign.core.model.Session;
8+
import com.docusign.core.model.User;
9+
import org.springframework.stereotype.Controller;
10+
import org.springframework.ui.ModelMap;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
13+
import javax.servlet.http.HttpServletResponse;
14+
15+
/**
16+
* This example demonstrates how to resume workflow.
17+
*/
18+
@Controller
19+
@RequestMapping("/mae003")
20+
public class Mae003ResumeWorkflowController extends AbstractMaestroController {
21+
private static final String MODEL_IS_WORKFLOW_ID_PRESENT = "isWorkflowIdPresent";
22+
23+
public static final String NO_WORKFLOW_AVAILABLE_TO_RESUME = "No workflow available to resume.";
24+
25+
public Mae003ResumeWorkflowController(DSConfiguration config, Session session, User user) {
26+
super(config, "mae003", user, session);
27+
}
28+
29+
@Override
30+
protected void onInitModel(WorkArguments args, ModelMap model) throws Exception {
31+
super.onInitModel(args, model);
32+
model.addAttribute(MODEL_IS_WORKFLOW_ID_PRESENT, session.getWorkflowId() != null );
33+
}
34+
35+
@Override
36+
protected Object doWork(
37+
WorkArguments args,
38+
ModelMap model,
39+
HttpServletResponse response
40+
) throws Exception{
41+
var accountId = session.getAccountId();
42+
var accessToken = user.getAccessToken();
43+
var workflowId = session.getWorkflowId();
44+
var client = createAuthenticatedClient(accessToken);
45+
46+
if (workflowId == null) {
47+
throw new IllegalStateException(NO_WORKFLOW_AVAILABLE_TO_RESUME);
48+
}
49+
50+
var paused = ResumeWorkflowService.ResumeMaestroWorkflow(
51+
client,
52+
accountId,
53+
workflowId);
54+
var jsonResponse = serializeObjectToJson(paused.resumeNewWorkflowInstancesSuccess().orElseThrow());
55+
56+
DoneExample.createDefault(getTextForCodeExampleByApiType().ExampleName)
57+
.withMessage(getTextForCodeExampleByApiType().ResultsPageText)
58+
.withJsonObject(jsonResponse)
59+
.addToModel(model, config);
60+
61+
return DONE_EXAMPLE_PAGE;
62+
}
63+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.docusign.controller.maestro.examples;
2+
3+
import com.docusign.DSConfiguration;
4+
import com.docusign.common.WorkArguments;
5+
import com.docusign.controller.maestro.services.CancelWorkflowInstanceService;
6+
import com.docusign.core.model.DoneExample;
7+
import com.docusign.core.model.Session;
8+
import com.docusign.core.model.User;
9+
import org.springframework.stereotype.Controller;
10+
import org.springframework.ui.ModelMap;
11+
import org.springframework.web.bind.annotation.RequestMapping;
12+
13+
import javax.servlet.http.HttpServletResponse;
14+
15+
/**
16+
* This example demonstrates how to cancel workflow instance.
17+
*/
18+
@Controller
19+
@RequestMapping("/mae004")
20+
public class Mae004CancelWorkflowInstanceController extends AbstractMaestroController {
21+
private static final String MODEL_IS_WORKFLOW_ID_PRESENT = "isWorkflowIdPresent";
22+
23+
public static final String NO_WORKFLOW_INSTANCE_AVAILABLE_TO_CANCEL = "No workflow instance available to cancel.";
24+
25+
public Mae004CancelWorkflowInstanceController(DSConfiguration config, Session session, User user) {
26+
super(config, "mae004", user, session);
27+
}
28+
29+
@Override
30+
protected void onInitModel(WorkArguments args, ModelMap model) throws Exception {
31+
super.onInitModel(args, model);
32+
model.addAttribute(MODEL_IS_WORKFLOW_ID_PRESENT, session.getWorkflowId() != null && session.getInstanceId() != null );
33+
}
34+
35+
@Override
36+
protected Object doWork(
37+
WorkArguments args,
38+
ModelMap model,
39+
HttpServletResponse response
40+
) throws Exception{
41+
var accountId = session.getAccountId();
42+
var accessToken = user.getAccessToken();
43+
var workflowId = session.getWorkflowId();
44+
var instanceId = session.getInstanceId();
45+
var client = createAuthenticatedClient(accessToken);
46+
47+
if (workflowId == null || instanceId == null) {
48+
throw new IllegalStateException(NO_WORKFLOW_INSTANCE_AVAILABLE_TO_CANCEL);
49+
}
50+
51+
var paused = CancelWorkflowInstanceService.CancelMaestroWorkflowInstance(
52+
client,
53+
accountId,
54+
workflowId,
55+
instanceId);
56+
57+
var jsonResponse = serializeObjectToJson(paused.cancelWorkflowInstanceResponse().orElseThrow());
58+
59+
DoneExample.createDefault(getTextForCodeExampleByApiType().ExampleName)
60+
.withMessage(getTextForCodeExampleByApiType().ResultsPageText)
61+
.withJsonObject(jsonResponse)
62+
.addToModel(model, config);
63+
64+
return DONE_EXAMPLE_PAGE;
65+
}
66+
}

0 commit comments

Comments
 (0)