From 9d0f63b36b093c7ba26741c91ce65122a70f909c Mon Sep 17 00:00:00 2001 From: ipodskochin Date: Sun, 14 Mar 2021 18:35:47 +0300 Subject: [PATCH 1/5] HW9(base) endpoint fixed --- .../src/main/java/ru/javaops/masterjava/web/WsClient.java | 6 +++--- .../ru/javaops/masterjava/service/mail/MailWSClient.java | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java index e65de94..d7dc248 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java @@ -22,7 +22,7 @@ public class WsClient { private String endpointAddress; static { - HOSTS = Configs.getConfig("hosts.conf", "hosts"); + HOSTS = Configs.getConfig("hosts.conf", "hosts").getConfig("mail"); } public WsClient(URL wsdlUrl, QName qname, Class serviceClass) { @@ -30,8 +30,8 @@ public WsClient(URL wsdlUrl, QName qname, Class serviceClass) { this.service = Service.create(wsdlUrl, qname); } - public void init(String host, String endpointAddress) { - this.endpointAddress = HOSTS.getString(host) + endpointAddress; + public void init(String endpoint, String endpointAddress) { + this.endpointAddress = HOSTS.getString(endpoint) + endpointAddress; } // Post is not thread-safe (http://stackoverflow.com/a/10601916/548473) diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java index 1aa3496..4552b37 100644 --- a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java @@ -30,7 +30,7 @@ public class MailWSClient { new QName("http://mail.javaops.ru/", "MailServiceImplService"), MailService.class); - WS_CLIENT.init("mail", "/mail/mailService?wsdl"); + WS_CLIENT.init("endpoint", "/mail/mailService?wsdl"); } From 8a177a561d645ac2ebb2b0f043fe8dd717acb538 Mon Sep 17 00:00:00 2001 From: ipodskochin Date: Sun, 14 Mar 2021 21:37:53 +0300 Subject: [PATCH 2/5] HW9(base) Statistics/Security SOAP Handlers implemented --- .../handler/SoapServerSecurityHandler.java | 35 +++++++++++++++++++ .../web/handler/SoapStatisticsHandler.java | 20 +++++++++++ .../masterjava/service/mail/MailWSClient.java | 2 -- .../service/mail/MailServiceImpl.java | 15 -------- .../src/main/resources/mailWsHandlers.xml | 8 +++++ 5 files changed, 63 insertions(+), 17 deletions(-) create mode 100644 services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java create mode 100644 services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapStatisticsHandler.java diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java new file mode 100644 index 0000000..a92a746 --- /dev/null +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java @@ -0,0 +1,35 @@ +package ru.javaops.masterjava.web.handler; + +import com.sun.xml.ws.api.handler.MessageHandlerContext; +import lombok.extern.slf4j.Slf4j; +import ru.javaops.masterjava.web.AuthUtil; + +import javax.xml.ws.handler.MessageContext; +import java.util.List; +import java.util.Map; + +@Slf4j +public class SoapServerSecurityHandler extends SoapBaseHandler { + + private static String USERS_AUTH_HEADER = AuthUtil.encodeBasicAuthHeader("user","password"); + + @Override + public boolean handleMessage(MessageHandlerContext context) { + Map> headers = (Map>) context.get(MessageContext.HTTP_REQUEST_HEADERS); +// HttpServletRequest request = (HttpServletRequest) mCtx.get(MessageContext.SERVLET_REQUEST); +// HttpServletResponse response = (HttpServletResponse) mCtx.get(MessageContext.SERVLET_RESPONSE); + int code = AuthUtil.checkBasicAuth(headers, USERS_AUTH_HEADER); + if (code != 0) { + context.put(MessageContext.HTTP_RESPONSE_CODE, code); + throw new SecurityException(); + } + + log.info("'User' logged in successfully"); + return true; + } + + @Override + public boolean handleFault(MessageHandlerContext context) { + return true; + } +} diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapStatisticsHandler.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapStatisticsHandler.java new file mode 100644 index 0000000..59f806b --- /dev/null +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapStatisticsHandler.java @@ -0,0 +1,20 @@ +package ru.javaops.masterjava.web.handler; + +import com.sun.xml.ws.api.handler.MessageHandlerContext; +import ru.javaops.masterjava.web.Statistics; + +import java.util.Date; + +public class SoapStatisticsHandler extends SoapBaseHandler { + @Override + public boolean handleMessage(MessageHandlerContext context) { + Statistics.count(context.getMessage().getPayloadLocalPart(), new Date().getTime(), Statistics.RESULT.SUCCESS); + return true; + } + + @Override + public boolean handleFault(MessageHandlerContext context) { + Statistics.count(context.getMessage().getPayloadLocalPart(), new Date().getTime(), Statistics.RESULT.FAIL); + return true; + } +} diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java index 4552b37..b6f5bb6 100644 --- a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java @@ -23,8 +23,6 @@ public class MailWSClient { public static final String PASSWORD = "password"; private static final SoapLoggingHandlers.ClientHandler LOGGING_HANDLER = new SoapLoggingHandlers.ClientHandler(Level.DEBUG); - public static String AUTH_HEADER = AuthUtil.encodeBasicAuthHeader(USER, PASSWORD); - static { WS_CLIENT = new WsClient<>(Resources.getResource("wsdl/mailService.wsdl"), new QName("http://mail.javaops.ru/", "MailServiceImplService"), diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceImpl.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceImpl.java index ae4bab4..2991f13 100644 --- a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceImpl.java +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/MailServiceImpl.java @@ -20,22 +20,7 @@ @MTOM @HandlerChain(file = "mailWsHandlers.xml") public class MailServiceImpl implements MailService { - - @Resource - private WebServiceContext wsContext; - public String sendToGroup(Set to, Set cc, String subject, String body, List attachments) throws WebStateException { - MessageContext mCtx = wsContext.getMessageContext(); - Map> headers = (Map>) mCtx.get(MessageContext.HTTP_REQUEST_HEADERS); - -// HttpServletRequest request = (HttpServletRequest) mCtx.get(MessageContext.SERVLET_REQUEST); -// HttpServletResponse response = (HttpServletResponse) mCtx.get(MessageContext.SERVLET_RESPONSE); - - int code = AuthUtil.checkBasicAuth(headers, MailWSClient.AUTH_HEADER); - if (code != 0) { - mCtx.put(MessageContext.HTTP_RESPONSE_CODE, code); - throw new SecurityException(); - } return MailSender.sendToGroup(to, cc, subject, body, attachments); } diff --git a/services/mail-service/src/main/resources/mailWsHandlers.xml b/services/mail-service/src/main/resources/mailWsHandlers.xml index d1f3ed3..59a0178 100644 --- a/services/mail-service/src/main/resources/mailWsHandlers.xml +++ b/services/mail-service/src/main/resources/mailWsHandlers.xml @@ -4,5 +4,13 @@ SoapLoggingHandler ru.javaops.masterjava.web.handler.SoapLoggingHandlers$ServerHandler + + SoapStatisticsHandler + ru.javaops.masterjava.web.handler.SoapStatisticsHandler + + + SoapServerSecurityHandler + ru.javaops.masterjava.web.handler.SoapServerSecurityHandler + \ No newline at end of file From 6f03566fe8465ebf38d221bd53440c5d04ea91ee Mon Sep 17 00:00:00 2001 From: ipodskochin Date: Fri, 19 Mar 2021 14:47:50 +0300 Subject: [PATCH 3/5] HW9(optional) HostsConfig (configuration from host.conf) --- common/src/main/resources/hosts.conf | 14 +++++++--- .../javaops/masterjava/web/HostsConfig.java | 28 +++++++++++++++++++ .../ru/javaops/masterjava/web/WsClient.java | 8 +----- .../web/handler/SoapLoggingHandlers.java | 3 +- .../handler/SoapServerSecurityHandler.java | 3 +- .../masterjava/service/mail/MailWSClient.java | 5 ++-- 6 files changed, 45 insertions(+), 16 deletions(-) create mode 100644 services/common-ws/src/main/java/ru/javaops/masterjava/web/HostsConfig.java diff --git a/common/src/main/resources/hosts.conf b/common/src/main/resources/hosts.conf index 6b0157b..4745d13 100644 --- a/common/src/main/resources/hosts.conf +++ b/common/src/main/resources/hosts.conf @@ -1,10 +1,16 @@ hosts { mail { endpoint = "http://localhost:8080" - debug.client = DEBUG - debug.server = INFO - user = "user" - password = "password" + } + + logging { + debug.client = DEBUG + debug.server = INFO + } + + credentials { + user = "user" + password = "password" } } include file("/apps/masterjava/config/hosts.conf") diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/HostsConfig.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/HostsConfig.java new file mode 100644 index 0000000..8a47a22 --- /dev/null +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/HostsConfig.java @@ -0,0 +1,28 @@ +package ru.javaops.masterjava.web; + +import com.typesafe.config.Config; +import org.slf4j.event.Level; +import ru.javaops.masterjava.config.Configs; + + +public class HostsConfig { + + final public static Config MAIL_CONFIG; + final public static Config LOGGING_CONFIG; + final public static Config CREDENTIALS_CONFIG; + final public static String USER; + final public static String PASSWORD; + final public static Level CLIENT_LOGGING_LEVEL; + final public static Level SERVER_LOGGING_LEVEL; + + static { + Config conf = Configs.getConfig("hosts.conf", "hosts"); + MAIL_CONFIG = conf.getConfig("mail"); + LOGGING_CONFIG = conf.getConfig("logging"); + CREDENTIALS_CONFIG = conf.getConfig("credentials"); + USER = CREDENTIALS_CONFIG.getString("user"); + PASSWORD = CREDENTIALS_CONFIG.getString("password"); + CLIENT_LOGGING_LEVEL = Level.valueOf(LOGGING_CONFIG.getString("debug.client")); + SERVER_LOGGING_LEVEL = Level.valueOf(LOGGING_CONFIG.getString("debug.server")); + } +} diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java index d7dc248..57e3355 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/WsClient.java @@ -15,23 +15,17 @@ import java.util.Map; public class WsClient { - private static Config HOSTS; - private final Class serviceClass; private final Service service; private String endpointAddress; - static { - HOSTS = Configs.getConfig("hosts.conf", "hosts").getConfig("mail"); - } - public WsClient(URL wsdlUrl, QName qname, Class serviceClass) { this.serviceClass = serviceClass; this.service = Service.create(wsdlUrl, qname); } public void init(String endpoint, String endpointAddress) { - this.endpointAddress = HOSTS.getString(endpoint) + endpointAddress; + this.endpointAddress = HostsConfig.MAIL_CONFIG.getString(endpoint) + endpointAddress; } // Post is not thread-safe (http://stackoverflow.com/a/10601916/548473) diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java index 7af6cc1..038f624 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java @@ -7,6 +7,7 @@ import com.sun.xml.ws.api.streaming.XMLStreamWriterFactory; import lombok.extern.slf4j.Slf4j; import org.slf4j.event.Level; +import ru.javaops.masterjava.web.HostsConfig; import javax.xml.stream.XMLStreamWriter; import java.io.ByteArrayOutputStream; @@ -132,7 +133,7 @@ protected boolean isRequest(boolean isOutbound) { public static class ServerHandler extends SoapLoggingHandlers { public ServerHandler() { - super(Level.INFO); + super(HostsConfig.SERVER_LOGGING_LEVEL); } @Override diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java index a92a746..a958016 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java @@ -3,6 +3,7 @@ import com.sun.xml.ws.api.handler.MessageHandlerContext; import lombok.extern.slf4j.Slf4j; import ru.javaops.masterjava.web.AuthUtil; +import ru.javaops.masterjava.web.HostsConfig; import javax.xml.ws.handler.MessageContext; import java.util.List; @@ -11,7 +12,7 @@ @Slf4j public class SoapServerSecurityHandler extends SoapBaseHandler { - private static String USERS_AUTH_HEADER = AuthUtil.encodeBasicAuthHeader("user","password"); + private static String USERS_AUTH_HEADER = AuthUtil.encodeBasicAuthHeader(HostsConfig.USER,HostsConfig.PASSWORD); @Override public boolean handleMessage(MessageHandlerContext context) { diff --git a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java index b6f5bb6..41e360b 100644 --- a/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java +++ b/services/mail-api/src/main/java/ru/javaops/masterjava/service/mail/MailWSClient.java @@ -5,8 +5,7 @@ import com.google.common.collect.Iterables; import com.google.common.io.Resources; import lombok.extern.slf4j.Slf4j; -import org.slf4j.event.Level; -import ru.javaops.masterjava.web.AuthUtil; +import ru.javaops.masterjava.web.HostsConfig; import ru.javaops.masterjava.web.WebStateException; import ru.javaops.masterjava.web.WsClient; import ru.javaops.masterjava.web.handler.SoapLoggingHandlers; @@ -21,7 +20,7 @@ public class MailWSClient { private static final WsClient WS_CLIENT; public static final String USER = "user"; public static final String PASSWORD = "password"; - private static final SoapLoggingHandlers.ClientHandler LOGGING_HANDLER = new SoapLoggingHandlers.ClientHandler(Level.DEBUG); + private static final SoapLoggingHandlers.ClientHandler LOGGING_HANDLER = new SoapLoggingHandlers.ClientHandler(HostsConfig.CLIENT_LOGGING_LEVEL); static { WS_CLIENT = new WsClient<>(Resources.getResource("wsdl/mailService.wsdl"), From fe4e78d8cf7cbe757fd4e081b23462fd577aea80 Mon Sep 17 00:00:00 2001 From: ipodskochin Date: Sun, 21 Mar 2021 13:28:04 +0300 Subject: [PATCH 4/5] HW9(optional) mail service handlers --- .../masterjava/web/handler/SoapLoggingHandlers.java | 6 +++++- .../web/handler/SoapServerSecurityHandler.java | 4 +--- .../service/mail/handlers/SoapMailLoggingHandler.java | 10 ++++++++++ .../mail/handlers/SoapMailSecurityHandler.java | 11 +++++++++++ .../src/main/resources/mailWsHandlers.xml | 8 ++++---- 5 files changed, 31 insertions(+), 8 deletions(-) create mode 100644 services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailLoggingHandler.java create mode 100644 services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailSecurityHandler.java diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java index 038f624..4b75c74 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapLoggingHandlers.java @@ -133,7 +133,11 @@ protected boolean isRequest(boolean isOutbound) { public static class ServerHandler extends SoapLoggingHandlers { public ServerHandler() { - super(HostsConfig.SERVER_LOGGING_LEVEL); + super(Level.INFO); + } + + public ServerHandler(Level logLvl) { + super(logLvl); } @Override diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java index a958016..21ef988 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/handler/SoapServerSecurityHandler.java @@ -3,7 +3,6 @@ import com.sun.xml.ws.api.handler.MessageHandlerContext; import lombok.extern.slf4j.Slf4j; import ru.javaops.masterjava.web.AuthUtil; -import ru.javaops.masterjava.web.HostsConfig; import javax.xml.ws.handler.MessageContext; import java.util.List; @@ -11,8 +10,7 @@ @Slf4j public class SoapServerSecurityHandler extends SoapBaseHandler { - - private static String USERS_AUTH_HEADER = AuthUtil.encodeBasicAuthHeader(HostsConfig.USER,HostsConfig.PASSWORD); + protected static String USERS_AUTH_HEADER; @Override public boolean handleMessage(MessageHandlerContext context) { diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailLoggingHandler.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailLoggingHandler.java new file mode 100644 index 0000000..5759dca --- /dev/null +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailLoggingHandler.java @@ -0,0 +1,10 @@ +package ru.javaops.masterjava.service.mail.handlers; + +import ru.javaops.masterjava.web.HostsConfig; +import ru.javaops.masterjava.web.handler.SoapLoggingHandlers; + +public class SoapMailLoggingHandler extends SoapLoggingHandlers.ServerHandler { + public SoapMailLoggingHandler() { + super(HostsConfig.SERVER_LOGGING_LEVEL); + } +} diff --git a/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailSecurityHandler.java b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailSecurityHandler.java new file mode 100644 index 0000000..8f7cf91 --- /dev/null +++ b/services/mail-service/src/main/java/ru/javaops/masterjava/service/mail/handlers/SoapMailSecurityHandler.java @@ -0,0 +1,11 @@ +package ru.javaops.masterjava.service.mail.handlers; + +import ru.javaops.masterjava.web.AuthUtil; +import ru.javaops.masterjava.web.HostsConfig; +import ru.javaops.masterjava.web.handler.SoapServerSecurityHandler; + +public class SoapMailSecurityHandler extends SoapServerSecurityHandler { + public SoapMailSecurityHandler() { + USERS_AUTH_HEADER= AuthUtil.encodeBasicAuthHeader(HostsConfig.USER,HostsConfig.PASSWORD); + } +} diff --git a/services/mail-service/src/main/resources/mailWsHandlers.xml b/services/mail-service/src/main/resources/mailWsHandlers.xml index 59a0178..c3bdb81 100644 --- a/services/mail-service/src/main/resources/mailWsHandlers.xml +++ b/services/mail-service/src/main/resources/mailWsHandlers.xml @@ -1,16 +1,16 @@ - SoapLoggingHandler - ru.javaops.masterjava.web.handler.SoapLoggingHandlers$ServerHandler + SoapMailLoggingHandler + ru.javaops.masterjava.service.mail.handlers.SoapMailLoggingHandler SoapStatisticsHandler ru.javaops.masterjava.web.handler.SoapStatisticsHandler - SoapServerSecurityHandler - ru.javaops.masterjava.web.handler.SoapServerSecurityHandler + SoapMailSecurityHandler + ru.javaops.masterjava.service.mail.handlers.SoapMailSecurityHandler \ No newline at end of file From c56d95081d91674f64633b892d7a8b784673707e Mon Sep 17 00:00:00 2001 From: ipodskochin Date: Sun, 21 Mar 2021 15:19:16 +0300 Subject: [PATCH 5/5] HW9(base) statistics staff --- .../ru/javaops/masterjava/web/Statistics.java | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/services/common-ws/src/main/java/ru/javaops/masterjava/web/Statistics.java b/services/common-ws/src/main/java/ru/javaops/masterjava/web/Statistics.java index 32d11f9..b5fc6f5 100644 --- a/services/common-ws/src/main/java/ru/javaops/masterjava/web/Statistics.java +++ b/services/common-ws/src/main/java/ru/javaops/masterjava/web/Statistics.java @@ -2,17 +2,44 @@ import lombok.extern.slf4j.Slf4j; +import java.util.ArrayList; +import java.util.List; + @Slf4j public class Statistics { public enum RESULT { SUCCESS, FAIL } + private static List failResults = new ArrayList<>(); + public static void count(String payload, long startTime, RESULT result) { long now = System.currentTimeMillis(); int ms = (int) (now - startTime); log.info(payload + " " + result.name() + " execution time(ms): " + ms); - // place for statistics staff + if (result == RESULT.FAIL) { + countFailures(payload); + } + } + + private static void countFailures(String payload) { + failResults.add(payload); + int failsCount = failResults.size(); + if (failsCount >= 10 && failsCount % 10 == 0) { + log.warn("There is a lot of failures. Last 10: \n" + getLast10Failures()); + } + } + + private static String getLast10Failures() { + StringBuilder sb = new StringBuilder(); + int failuresCount = failResults.size(); + if (failuresCount < 10) { + return sb.toString(); + } + for (int i = failuresCount; i > (failuresCount - 10); i--) { + sb.append(failResults.get(i - 1)).append("\n"); + } + return sb.toString(); } }