Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 659d8d1

Browse files
committed
11_6_akka_typed
1 parent 5871203 commit 659d8d1

File tree

13 files changed

+163
-4
lines changed

13 files changed

+163
-4
lines changed

services/akka-remote/src/main/java/ru/javaops/masterjava/akka/AkkaActivator.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
package ru.javaops.masterjava.akka;
22

33
import akka.actor.ActorSystem;
4+
import akka.actor.TypedActor;
5+
import akka.actor.TypedProps;
6+
import akka.japi.Creator;
7+
import akka.util.Timeout;
48
import lombok.extern.slf4j.Slf4j;
59
import ru.javaops.masterjava.config.Configs;
10+
import scala.concurrent.ExecutionContext;
11+
import scala.concurrent.duration.Duration;
12+
13+
import java.util.concurrent.TimeUnit;
614

715
@Slf4j
816
public class AkkaActivator {
@@ -19,6 +27,21 @@ public static AkkaActivator start(String actorSystemName, String configName) {
1927
return new AkkaActivator(actorSystemName, configName);
2028
}
2129

30+
public <T> void startTypedActor(Class<T> typedClass, String name, Creator<T> creator) {
31+
log.info("Start AKKA typed actor: {}", name);
32+
TypedActor.get(system).typedActorOf(
33+
new TypedProps<T>(typedClass, creator).withTimeout(new Timeout(Duration.create(20, TimeUnit.SECONDS))), name);
34+
}
35+
36+
public <T> T getTypedRef(Class<T> typedClass, String path) {
37+
log.info("Get typed reference with path={}", path);
38+
return TypedActor.get(system).typedActorOf(new TypedProps<T>(typedClass), system.actorFor(path));
39+
}
40+
41+
public ExecutionContext getExecutionContext() {
42+
return system.dispatcher();
43+
}
44+
2245
public void shutdown() {
2346
if (system != null) {
2447
log.info("Akka system shutdown");

services/common-ws/src/main/java/ru/javaops/masterjava/web/FaultInfo.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,15 @@
77
import ru.javaops.masterjava.ExceptionType;
88

99
import javax.xml.bind.annotation.XmlType;
10+
import java.io.Serializable;
1011

1112
@Data
1213
@RequiredArgsConstructor
1314
@NoArgsConstructor
1415
@XmlType(namespace = "http://common.javaops.ru/")
15-
public class FaultInfo {
16+
public class FaultInfo implements Serializable {
17+
private static final long serialVersionUID = 1L;
18+
1619
private @NonNull ExceptionType type;
1720

1821
@Override

services/mail-api/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
<artifactId>commons-io</artifactId>
3939
<version>2.6</version>
4040
</dependency>
41+
<dependency>
42+
<groupId>${project.groupId}</groupId>
43+
<artifactId>akka-remote</artifactId>
44+
<version>${project.version}</version>
45+
</dependency>
4146
</dependencies>
4247

4348
</project>

services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/GroupResult.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66

77
import javax.xml.bind.annotation.XmlAccessType;
88
import javax.xml.bind.annotation.XmlAccessorType;
9+
import java.io.Serializable;
910
import java.util.List;
1011

1112
@AllArgsConstructor
1213
@NoArgsConstructor
1314
@XmlAccessorType(XmlAccessType.FIELD)
1415
@Getter
15-
public class GroupResult {
16+
public class GroupResult implements Serializable {
17+
private static final long serialVersionUID = 1L;
18+
1619
private int success; // number of successfully sent email
1720
private List<MailResult> failed; // failed emails with causes
1821

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ru.javaops.masterjava.service.mail;
2+
3+
import ru.javaops.masterjava.service.mail.util.MailUtils;
4+
5+
public interface MailRemoteService {
6+
7+
scala.concurrent.Future<GroupResult> sendBulk(MailUtils.MailObject mailObject);
8+
}

services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailResult.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@
99
import javax.xml.bind.annotation.XmlAccessorType;
1010
import javax.xml.bind.annotation.XmlAttribute;
1111
import javax.xml.bind.annotation.XmlValue;
12+
import java.io.Serializable;
1213

1314
@AllArgsConstructor
1415
@NoArgsConstructor
1516
@XmlAccessorType(XmlAccessType.FIELD)
1617
@Getter
17-
public class MailResult {
18+
public class MailResult implements Serializable {
19+
private static final long serialVersionUID = 1L;
20+
1821
public static final String OK = "OK";
1922

2023
@XmlAttribute

services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/util/MailUtils.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public static Set<Addressee> split(String addressees) {
2828
@Data
2929
@AllArgsConstructor
3030
public static class MailObject implements Serializable {
31+
private static final long serialVersionUID = 1L;
32+
3133
private @NotNull String users;
3234
private String subject;
3335
private @NotNull String body;

services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceExecutor.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package ru.javaops.masterjava.service.mail;
22

3+
import akka.dispatch.Futures;
34
import lombok.extern.slf4j.Slf4j;
45
import one.util.streamex.StreamEx;
56
import ru.javaops.masterjava.ExceptionType;
67
import ru.javaops.masterjava.service.mail.util.MailUtils;
78
import ru.javaops.masterjava.service.mail.util.MailUtils.MailObject;
89
import ru.javaops.masterjava.web.WebStateException;
910
import ru.javaops.masterjava.web.WsClient;
11+
import scala.concurrent.ExecutionContext;
1012

1113
import java.util.ArrayList;
1214
import java.util.List;
@@ -72,6 +74,13 @@ private void cancel(String cause, Throwable t) throws WebStateException {
7274
}.call();
7375
}
7476

77+
public static scala.concurrent.Future<GroupResult> sendAsyncWithReply(MailObject mailObject, ExecutionContext ec) {
78+
// http://doc.akka.io/docs/akka/current/java/futures.html
79+
return Futures.future(
80+
() -> sendBulk(MailUtils.split(mailObject.getUsers()), mailObject.getSubject(), mailObject.getBody(), MailUtils.getAttachments(mailObject.getAttachments())),
81+
ec);
82+
}
83+
7584
public static void sendAsync(MailObject mailObject) {
7685
Set<Addressee> addressees = MailUtils.split(mailObject.getUsers());
7786
addressees.forEach(addressee ->
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package ru.javaops.masterjava.service.mail.listeners;
2+
3+
import akka.japi.Creator;
4+
import lombok.extern.slf4j.Slf4j;
5+
import ru.javaops.masterjava.akka.AkkaActivator;
6+
import ru.javaops.masterjava.service.mail.MailRemoteService;
7+
import ru.javaops.masterjava.service.mail.MailServiceExecutor;
8+
9+
import javax.servlet.ServletContextEvent;
10+
import javax.servlet.ServletContextListener;
11+
import javax.servlet.annotation.WebListener;
12+
13+
@WebListener
14+
@Slf4j
15+
public class AkkaMailListener implements ServletContextListener {
16+
private AkkaActivator akkaActivator;
17+
18+
@Override
19+
public void contextInitialized(ServletContextEvent sce) {
20+
akkaActivator = AkkaActivator.start("MailService", "mail-service");
21+
akkaActivator.startTypedActor(MailRemoteService.class, "mail-remote-service",
22+
(Creator<MailRemoteService>) () ->
23+
mailObject -> MailServiceExecutor.sendAsyncWithReply(mailObject, akkaActivator.getExecutionContext()));
24+
}
25+
26+
@Override
27+
public void contextDestroyed(ServletContextEvent sce) {
28+
akkaActivator.shutdown();
29+
}
30+
}

services/mail-service/src/main/resources/logback.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
<logger name="org.hibernate.validator" level="debug"/>
4040
<logger name="org.glassfish.jersey" level="trace"/>
4141

42-
<root level="warn">
42+
<root level="info">
4343
<appender-ref ref="file"/>
4444
<appender-ref ref="console"/>
4545
</root>
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package ru.javaops.masterjava.webapp.akka;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import ru.javaops.masterjava.service.mail.GroupResult;
5+
import ru.javaops.masterjava.service.mail.MailRemoteService;
6+
import ru.javaops.masterjava.service.mail.util.MailUtils.MailObject;
7+
import scala.concurrent.Await;
8+
import scala.concurrent.duration.Duration;
9+
10+
import javax.servlet.ServletConfig;
11+
import javax.servlet.ServletException;
12+
import javax.servlet.annotation.MultipartConfig;
13+
import javax.servlet.annotation.WebServlet;
14+
import javax.servlet.http.HttpServlet;
15+
import javax.servlet.http.HttpServletRequest;
16+
import javax.servlet.http.HttpServletResponse;
17+
import java.io.IOException;
18+
19+
import static ru.javaops.masterjava.webapp.WebUtil.createMailObject;
20+
import static ru.javaops.masterjava.webapp.WebUtil.doAndWriteResponse;
21+
import static ru.javaops.masterjava.webapp.akka.AkkaWebappListener.akkaActivator;
22+
23+
@WebServlet(value = "/sendAkkaTyped", loadOnStartup = 1, asyncSupported = true)
24+
@Slf4j
25+
@MultipartConfig
26+
public class AkkaTypedSendServlet extends HttpServlet {
27+
28+
private MailRemoteService mailService;
29+
30+
@Override
31+
public void init(ServletConfig config) throws ServletException {
32+
super.init(config);
33+
mailService = akkaActivator.getTypedRef(MailRemoteService.class, "akka.tcp://[email protected]:2553/user/mail-remote-service");
34+
}
35+
36+
@Override
37+
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
38+
req.setCharacterEncoding("UTF-8");
39+
doAndWriteResponse(resp, () -> sendAkka(createMailObject(req)));
40+
}
41+
42+
private String sendAkka(MailObject mailObject) throws Exception {
43+
scala.concurrent.Future<GroupResult> future = mailService.sendBulk(mailObject);
44+
log.info("Receive future, waiting result ...");
45+
GroupResult groupResult = Await.result(future, Duration.create(10, "seconds"));
46+
return groupResult.toString();
47+
}
48+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package ru.javaops.masterjava.webapp.akka;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import ru.javaops.masterjava.akka.AkkaActivator;
5+
6+
import javax.servlet.ServletContextEvent;
7+
import javax.servlet.ServletContextListener;
8+
import javax.servlet.annotation.WebListener;
9+
10+
@WebListener
11+
@Slf4j
12+
public class AkkaWebappListener implements ServletContextListener {
13+
public static AkkaActivator akkaActivator;
14+
15+
@Override
16+
public void contextInitialized(ServletContextEvent sce) {
17+
akkaActivator = AkkaActivator.start("WebApp", "webapp");
18+
}
19+
20+
@Override
21+
public void contextDestroyed(ServletContextEvent sce) {
22+
akkaActivator.shutdown();
23+
}
24+
}

web/webapp/src/main/webapp/WEB-INF/templates/users.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
<input type="radio" name="transport" onchange="setUrl('sendSoap');" checked>SOAP<br>
4747
<input type="radio" name="transport" onchange="setUrl('/mail/rest/send');">REST<br>
4848
<input type="radio" name="transport" onchange="setUrl('sendJms');">JMS<br>
49+
<input type="radio" name="transport" onchange="setUrl('sendAkkaTyped');">AKKA Typed<br>
4950
</p>
5051
<p>
5152
<button type="button" onclick="send()">Send</button>

0 commit comments

Comments
 (0)