Skip to content

Commit

Permalink
Fix and improve code
Browse files Browse the repository at this point in the history
  • Loading branch information
mxavierx committed Oct 16, 2019
1 parent e0be74d commit 189286d
Show file tree
Hide file tree
Showing 9 changed files with 667 additions and 148 deletions.
617 changes: 548 additions & 69 deletions .idea/workspace.xml

Large diffs are not rendered by default.

11 changes: 3 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,13 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- <dependency>-->
<!-- <groupId>com.h2database</groupId>-->
<!-- <artifactId>h2</artifactId>-->
<!-- <scope>runtime</scope>-->
<!-- </dependency>-->

<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>


<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.crealytics.reports.model.Report;
import com.crealytics.reports.service.ReportService;
import com.crealytics.reports.service.ReportServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
Expand All @@ -25,9 +26,12 @@ public ReportController(ReportServiceImpl reportService) {
public ResponseEntity<List<Report>> findBySiteAndMonth(@RequestParam String site, @RequestParam String month) {
List<Report> reports = null;
try {
if(StringUtils.isBlank(site) || StringUtils.isBlank(month)){
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
reports = reportService.findBySiteAndMonth(site, month);
} catch (Exception e) {
new ResponseEntity(HttpStatus.NOT_FOUND);
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<List<Report>>(reports, HttpStatus.OK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.crealytics.reports.model.Report;
import com.crealytics.reports.model.builder.ReportBuider;
import com.crealytics.reports.repository.ReportRepository;
import com.crealytics.reports.service.ReportServiceImpl;
import com.crealytics.reports.util.Month;
import com.opencsv.CSVReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -13,11 +13,9 @@
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;

@Component
public class OnStartupListener implements ApplicationListener<ContextRefreshedEvent> {
Expand All @@ -33,18 +31,19 @@ public class OnStartupListener implements ApplicationListener<ContextRefreshedEv
@Override
@Transactional
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
readCsvFileAndStoreRecords(JANUARY_REPORTS_CSV_FILE_PATH);
readCsvFileAndStoreRecords(FEBRUARY_REPORTS_CSV_FILE_PATH);
String januaryFilePath = OnStartupListener.class.getClassLoader().getResource(JANUARY_REPORTS_CSV_FILE_PATH).getPath();
String februaryFilePath = OnStartupListener.class.getClassLoader().getResource(FEBRUARY_REPORTS_CSV_FILE_PATH).getPath();
readCsvFileAndStoreRecords(januaryFilePath, Month.JANUARY.getValue());
readCsvFileAndStoreRecords(februaryFilePath, Month.FEBRUARY.getValue());
}

private void readCsvFileAndStoreRecords(String filePath) {
try(CSVReader reader = new CSVReader(new FileReader(JANUARY_REPORTS_CSV_FILE_PATH))) {
private void readCsvFileAndStoreRecords(String filePath, String month) {
try(CSVReader reader = new CSVReader(new FileReader(filePath))) {
String[] line;
while ((line = reader.readNext()) != null) {
if(!"site".equals(line[0])) {
Report report = ReportBuider.build(line[0], line[1], Integer.parseInt(line[2]), Integer.parseInt(line[3]),
Integer.parseInt(line[4]), Integer.parseInt(line[5]),
new BigDecimal(line[6]));
Report report = ReportBuider.build(month, line[0].trim(), Integer.parseInt(line[1].trim()), Integer.parseInt(line[2].trim()), Integer.parseInt(line[3].trim()),
Integer.parseInt(line[4].trim()), new BigDecimal(line[5].trim()));
Report resp = reportRepository.save(report);
log.info("Storing Report from csv file = {}", resp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
import com.crealytics.reports.model.Report;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class ReportBuider {

public static Report build(String month, String site, Integer requests, Integer impressions, Integer clicks, Integer conversions,
BigDecimal revenue) {
BigDecimal ctr = new BigDecimal((clicks / impressions) * 100);
BigDecimal cr = new BigDecimal((conversions / impressions) * 100);
BigDecimal filLRate = new BigDecimal((impressions / requests) * 100);
BigDecimal eCpm = revenue.multiply(new BigDecimal(1000)).divide(new BigDecimal(impressions));
double clicksFloat = (double) clicks;
double impressionsFloat = (double) impressions;
double conversionsFloat = (double) conversions;
double requestsFloat = (double) requests;

BigDecimal ctr = new BigDecimal((clicksFloat/ impressionsFloat) * 100).setScale(3, RoundingMode.valueOf(1));
BigDecimal cr = new BigDecimal((conversionsFloat / impressionsFloat) * 100).setScale(3, RoundingMode.valueOf(1));
BigDecimal filLRate = new BigDecimal((impressionsFloat / requestsFloat) * 100).setScale(3, RoundingMode.valueOf(1));
BigDecimal eCpm = revenue.multiply(new BigDecimal(1000)).divide(new BigDecimal(impressions), 3, RoundingMode.valueOf(1));
return new Report(null, month, site, requests, impressions, clicks, conversions, revenue, ctr, cr, filLRate, eCpm);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.crealytics.reports.model.Report;
import com.crealytics.reports.repository.ReportRepository;
import com.crealytics.reports.util.Month;
import javassist.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -27,12 +28,12 @@ public class ReportServiceImpl implements ReportService {
public ReportServiceImpl(ReportRepository reportRepository) {
this.reportRepository = reportRepository;
this.monthsMap = new HashMap<>(); // TODO make a property file and Object
monthsMap.put("1", "January");
monthsMap.put("2", "February");
monthsMap.put("JAN", "January");
monthsMap.put("FEB", "February");
monthsMap.put("JANUARY", "January");
monthsMap.put("FEBRUARY", "February");
monthsMap.put("1", Month.JANUARY.getValue());
monthsMap.put("2", Month.FEBRUARY.getValue());
monthsMap.put("JAN", Month.JANUARY.getValue());
monthsMap.put("FEB", Month.FEBRUARY.getValue());
monthsMap.put("JANUARY", Month.JANUARY.getValue());
monthsMap.put("FEBRUARY", Month.FEBRUARY.getValue());
}

@Override
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/com/crealytics/reports/util/Month.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.crealytics.reports.util;

public enum Month {
JANUARY("January"),
FEBRUARY("February");

Month(String value) {
this.value = value;
}

private String value;

public String getValue() {
return value;
}
}
16 changes: 16 additions & 0 deletions src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
DROP TABLE IF EXISTS report;

CREATE TABLE report (
id INT AUTO_INCREMENT PRIMARY KEY,
month VARCHAR(20) NOT NULL,
site VARCHAR(50) NOT NULL,
requests INT NOT NULL,
impressions INT NOT NULL,
clicks INT NOT NULL,
conversions INT NOT NULL,
revenue DECIMAL NOT NULL,
CTR DECIMAL NOT NULL,
CR DECIMAL NOT NULL,
fill_rate DECIMAL NOT NULL,
eCPM DECIMAL NOT NULL
);
102 changes: 53 additions & 49 deletions src/test/java/com/crealytics/reports/ReportsApplicationTests.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.crealytics.reports;

import com.crealytics.reports.util.Month;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

Expand All @@ -18,16 +21,15 @@

@RunWith(SpringRunner.class)
@SpringBootTest
@ComponentScan(basePackages = {"com.crealytics.reports.service", "com.crealytics.reports.controller",
"com.crealytics.reports.listener"})
public class ReportsApplicationTests {

public static final String SITE_DESKTOP_WEB = "desktop web";
public static final String SITE_MOBILE_WEB = "mobile web";
public static final String SITE_ANDROID = "android";
public static final String SITE_IOS = "iOS";

public static final String JANUARY = "January";
public static final String FEBRUARY = "February";

@Autowired
private WebApplicationContext context;

Expand All @@ -41,50 +43,51 @@ public void setUp() {
@Test
public void testMonthFullName() throws Exception{
String site = "iOS";
String month = "January";
String month = Month.JANUARY.getValue();
this.mockMvc.perform(get("/reports")
.requestAttr("site", site)
.requestAttr("month", month)
.param("site", site)
.param("month", month)
.accept(MediaType.APPLICATION_JSON))

.andExpect(status().isOk())
.andExpect(jsonPath("site", equalTo(SITE_IOS)))
.andExpect(jsonPath("month", equalTo("January")))
.andExpect(jsonPath("request", equalTo(2550165)))
.andExpect(jsonPath("impressions", equalTo(2419733)))
.andExpect(jsonPath("clicks", equalTo(6331)))
.andExpect(jsonPath("conversions", equalTo(1564)))
.andExpect(jsonPath("revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("ctr", closeTo(0.26, 0.02))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("cr", closeTo(0.064, 0.02))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("fill_rate", closeTo(94.88, 0.02))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("eCPM", closeTo(1.939, 0.02))) // (revenue × 1000) ÷ impressions
;
.andExpect(jsonPath("$.length()", equalTo(1)))
.andExpect(jsonPath("$[0].site", equalTo(SITE_IOS)))
.andExpect(jsonPath("$[0].month", equalTo(Month.JANUARY.getValue())))
.andExpect(jsonPath("$[0].requests", equalTo(2550165)))
.andExpect(jsonPath("$[0].impressions", equalTo(2419733)))
.andExpect(jsonPath("$[0].clicks", equalTo(6331)))
.andExpect(jsonPath("$[0].conversions", equalTo(1564)))
.andExpect(jsonPath("$[0].revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("$[0].ctr", closeTo(0.261, 0.002))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("$[0].cr", closeTo(0.064, 0.002))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("$[0].fill_rate", closeTo(94.885, 0.002))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("$[0].eCPM", closeTo(1.939, 0.002))); // (revenue × 1000); ÷ impressions
}

@Test
public void testMonthThreeLetters() throws Exception{
String site = "iOS";
String month = "Jan";
this.mockMvc.perform(get("/reports")
.requestAttr("site", site)
.requestAttr("month", month)
.param("site", site)
.param("month", month)
.accept(MediaType.APPLICATION_JSON))

.andExpect(status().isOk())
.andExpect(jsonPath("site", equalTo(SITE_IOS)))
.andExpect(jsonPath("month", equalTo("January")))
.andExpect(jsonPath("request", equalTo(2550165)))
.andExpect(jsonPath("impressions", equalTo(2419733)))
.andExpect(jsonPath("clicks", equalTo(6331)))
.andExpect(jsonPath("conversions", equalTo(1564)))
.andExpect(jsonPath("revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("ctr", closeTo(0.26, 0.02))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("cr", closeTo(0.064, 0.02))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("fill_rate", closeTo(94.88, 0.02))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("eCPM", closeTo(1.939, 0.02))) // (revenue × 1000) ÷ impressions
.andExpect(jsonPath("$.length()", equalTo(1)))
.andExpect(jsonPath("$[0].site", equalTo(SITE_IOS)))
.andExpect(jsonPath("$[0].month", equalTo(Month.JANUARY.getValue())))
.andExpect(jsonPath("$[0].requests", equalTo(2550165)))
.andExpect(jsonPath("$[0].impressions", equalTo(2419733)))
.andExpect(jsonPath("$[0].clicks", equalTo(6331)))
.andExpect(jsonPath("$[0].conversions", equalTo(1564)))
.andExpect(jsonPath("$[0].revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("$[0].ctr", closeTo(0.261, 0.002))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("$[0].cr", closeTo(0.064, 0.002))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("$[0].fill_rate", closeTo(94.885, 0.002))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("$[0].eCPM", closeTo(1.939, 0.002))); // (revenue × 1000); ÷ impressions
;
}

Expand All @@ -93,23 +96,24 @@ public void testMonthNumber() throws Exception{
String site = "iOS";
String month = "1";
this.mockMvc.perform(get("/reports")
.requestAttr("site", site)
.requestAttr("month", month)
.param("site", site)
.param("month", month)
.accept(MediaType.APPLICATION_JSON))

.andExpect(status().isOk())
.andExpect(jsonPath("site", equalTo(SITE_IOS)))
.andExpect(jsonPath("month", equalTo("January")))
.andExpect(jsonPath("request", equalTo(2550165)))
.andExpect(jsonPath("impressions", equalTo(2419733)))
.andExpect(jsonPath("clicks", equalTo(6331)))
.andExpect(jsonPath("conversions", equalTo(1564)))
.andExpect(jsonPath("revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("ctr", closeTo(0.26, 0.02))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("cr", closeTo(0.064, 0.02))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("fill_rate", closeTo(94.88, 0.02))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("eCPM", closeTo(1.939, 0.02))) // (revenue × 1000) ÷ impressions
.andExpect(jsonPath("$.length()", equalTo(1)))
.andExpect(jsonPath("$[0].site", equalTo(SITE_IOS)))
.andExpect(jsonPath("$[0].month", equalTo(Month.JANUARY.getValue())))
.andExpect(jsonPath("$[0].requests", equalTo(2550165)))
.andExpect(jsonPath("$[0].impressions", equalTo(2419733)))
.andExpect(jsonPath("$[0].clicks", equalTo(6331)))
.andExpect(jsonPath("$[0].conversions", equalTo(1564)))
.andExpect(jsonPath("$[0].revenue", closeTo(4692.28, 0.02)))

.andExpect(jsonPath("$[0].ctr", closeTo(0.261, 0.002))) // (clicks ÷ impressions) × 100%
.andExpect(jsonPath("$[0].cr", closeTo(0.064, 0.002))) // (conversions ÷ impressions) × 100%
.andExpect(jsonPath("$[0].fill_rate", closeTo(94.885, 0.002))) // (impressions ÷ requests) × 100%
.andExpect(jsonPath("$[0].eCPM", closeTo(1.939, 0.002))); // (revenue × 1000); ÷ impressions
;
}

Expand All @@ -118,8 +122,8 @@ public void testEmptyParams() throws Exception {
String site = "";
String month = "";
this.mockMvc.perform(get("/reports")
.requestAttr("site", site)
.requestAttr("month", month)
.param("site", site)
.param("month", month)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound());
}
Expand Down

0 comments on commit 189286d

Please sign in to comment.