diff --git a/api/pom.xml b/api/pom.xml index 635a41200..1980968b2 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -25,6 +25,12 @@ ${motech.version} + + com.github.vladimir-bukhtoyarov + org.motechproject.com.github.vladimir-bukhtoyarov + 4.1.1-${external.dependency.release.tag.new} + + org.motechproject.nms region diff --git a/api/src/main/resources/META-INF/motech/applicationContext.xml b/api/src/main/resources/META-INF/motech/applicationContext.xml index 678ced6d7..fe0ddbc53 100644 --- a/api/src/main/resources/META-INF/motech/applicationContext.xml +++ b/api/src/main/resources/META-INF/motech/applicationContext.xml @@ -11,6 +11,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/imi/pom.xml b/imi/pom.xml index c75c8d9d8..709363b94 100644 --- a/imi/pom.xml +++ b/imi/pom.xml @@ -27,6 +27,12 @@ ${motech.version} + + com.github.vladimir-bukhtoyarov + org.motechproject.com.github.vladimir-bukhtoyarov + 4.1.1-${external.dependency.release.tag.new} + + @@ -55,6 +61,7 @@ 3.1.0 provided + @@ -97,6 +104,7 @@ net.sf.cglib.reflect, org.springframework.transaction, org.motechproject.nms.kilkari.repository, + org.motechproject.nms.kilkari.service, org.motechproject.nms.region.service, org.motechproject.nms.region.utils, org.datanucleus.enhancement, diff --git a/imi/src/main/java/org/motechproject/nms/imi/web/ImiController.java b/imi/src/main/java/org/motechproject/nms/imi/web/ImiController.java index 8c8d1da28..45066154a 100644 --- a/imi/src/main/java/org/motechproject/nms/imi/web/ImiController.java +++ b/imi/src/main/java/org/motechproject/nms/imi/web/ImiController.java @@ -212,7 +212,7 @@ public void notifyNewCdrFile(@RequestBody CdrFileNotificationRequest request) { null )); alertService.create(fileName, "scpCdrFromRemote", error, AlertType.CRITICAL, AlertStatus.NEW, 0, null); - throw new IllegalArgumentException(e.getMessage(), e); + throw new IllegalArgumentException("Error copying CDR file", e); } // Copy the summary file from the IMI share (imi.remote_cdr_dir) into local cdr dir (imi.local_cdr_dir) @@ -231,7 +231,7 @@ public void notifyNewCdrFile(@RequestBody CdrFileNotificationRequest request) { null )); alertService.create(fileName, "scpCdrFromRemote", error, AlertType.CRITICAL, AlertStatus.NEW, 0, null); - throw new IllegalArgumentException(e.getMessage(), e); + throw new IllegalArgumentException("Error copying CSR file", e); } // Checks the CSR/CDR checksum, record count & csv, then sends an event to proceed to phase 2 of the diff --git a/imi/src/main/resources/META-INF/motech/applicationContext.xml b/imi/src/main/resources/META-INF/motech/applicationContext.xml index bd11d1aa2..cf2938cb3 100644 --- a/imi/src/main/resources/META-INF/motech/applicationContext.xml +++ b/imi/src/main/resources/META-INF/motech/applicationContext.xml @@ -10,7 +10,22 @@ - + + + + + + + + + + + + + + + + diff --git a/kilkari/pom.xml b/kilkari/pom.xml index 6938a454d..a21cbf7bd 100644 --- a/kilkari/pom.xml +++ b/kilkari/pom.xml @@ -60,6 +60,10 @@ rejection-handler ${project.version} + + com.github.vladimir-bukhtoyarov + org.motechproject.com.github.vladimir-bukhtoyarov + diff --git a/kilkari/src/main/java/org/motechproject/nms/kilkari/service/RateLimitInterceptor.java b/kilkari/src/main/java/org/motechproject/nms/kilkari/service/RateLimitInterceptor.java new file mode 100644 index 000000000..dd1a33355 --- /dev/null +++ b/kilkari/src/main/java/org/motechproject/nms/kilkari/service/RateLimitInterceptor.java @@ -0,0 +1,87 @@ +package org.motechproject.nms.kilkari.service; + +import io.github.bucket4j.*; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.HttpURLConnection; +import java.net.URL; +import java.time.Duration; +import java.util.concurrent.TimeUnit; + +public class RateLimitInterceptor implements HandlerInterceptor { + // + private final Bucket bucket; + private final String url = "http://192.168.200.4:8080/NMSReportingSuite/nms/mail/emailAlert"; + private final String api; + private final String USER_AGENT = "Mozilla/5.0"; + private final int capacity; + private final String email = "motech-support@beehyv.in"; + + public RateLimitInterceptor(int capacity, String api) { + this.capacity = capacity; + Refill refill = Refill.intervally(capacity, Duration.ofMinutes(1)); + Bandwidth limit = Bandwidth.classic(capacity, refill); + this.bucket = Bucket4j.builder().addLimit(limit).build(); + this.api = api; + } + + @Override + public boolean preHandle(HttpServletRequest request, + HttpServletResponse response, Object handler) throws Exception { + System.out.println("Inside pre handle"); + ConsumptionProbe probe = this.bucket.tryConsumeAndReturnRemaining(1); + + if (probe.isConsumed()) { + long remTokens = probe.getRemainingTokens(); + response.addHeader("X-Rate-Limit-Remaining", + Long.toString(remTokens)); + System.out.println("remaning tokens for this api for this min "+remTokens); + if(remTokens==(0.4*capacity)){ + sendEmailAlert(remTokens, "warning", 60); + System.out.println("sendEmailAlert "+api + remTokens); + } + if(remTokens==(0.2*capacity)){ + sendEmailAlert(remTokens, "critical", 80); + } + return true; + } + + response.setStatus(429); // 429 + response.addHeader("X-Rate-Limit-Retry-After-Milliseconds", + Long.toString(TimeUnit.NANOSECONDS.toMillis(probe.getNanosToWaitForRefill()))); + + return false; + } + + @Override + public void postHandle(HttpServletRequest req, HttpServletResponse res, + Object handler, ModelAndView model) throws Exception { + } + + // Called after rendering the view + @Override + public void afterCompletion(HttpServletRequest req, HttpServletResponse res, + Object handler, Exception ex) throws Exception { + } + + public void sendEmailAlert(long remTokens, String status, long perc) throws Exception { + String finalUrl = url + "?api=" + api + "&capacity=" + remTokens + "&email=" + email + "&status=" + status + + "&perc=" + perc; + URL obj = new URL(finalUrl); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // optional default is GET + con.setRequestMethod("GET"); + + //add request header + con.setRequestProperty("User-Agent", USER_AGENT); + + int responseCode = con.getResponseCode(); + System.out.println("\nSending 'GET' request to URL : " + finalUrl); + System.out.println("Response Code : " + responseCode); + } + +} diff --git a/pom.xml b/pom.xml index db4edf6c1..d9c81781d 100644 --- a/pom.xml +++ b/pom.xml @@ -661,6 +661,11 @@ + + com.github.vladimir-bukhtoyarov + org.motechproject.com.github.vladimir-bukhtoyarov + 4.1.1-${external.dependency.release.tag.new} + org.motechproject motech-platform-osgi-extender-fragment