Skip to content

Commit c93193a

Browse files
“init”
0 parents  commit c93193a

File tree

14 files changed

+526
-0
lines changed

14 files changed

+526
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.gradle
2+
/build/
3+
!gradle/wrapper/gradle-wrapper.jar
4+
5+
/out/

README.MD

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
**Тестовое задание Java**
2+
3+
Требуется реализовать REST-сервис по сбору статистики посещаемости WEB-сайта.
4+
5+
**Сборка**
6+
7+
Команда **gradle bootJar** соберет приложение Spring Boot в jar.
8+
9+
Собранный файл будет располагаться в build/libs
10+
11+
**Запуск**
12+
13+
Для запуска нужна СУБД Mongo. Для настройки подключения нужно отредактировать файл application.yml, указать хост, порт,
14+
имя базы данных в соотвествующих полях.
15+
16+
Запустить можно командой **gradle bootRun**.
17+
18+
Или можно запустить собранный jar командой java -jar digitalzone-0.0.1-SNAPSHOT.jar. Отредактированный файл application.yml расположить рядом с jar.
19+
20+
**Тестирование**
21+
22+
Приложение имеет API c двумя endpoint:
23+
24+
**POST /event :**
25+
26+
Добавляет новое посещение страницы пользователем.
27+
28+
В теле сообщения нужно передать json создаваемоего объекта:
29+
30+
```$javascript
31+
{
32+
"userUUID": "d8898714-37ad-4327-a34b-faf7b3f87461", // ид пользователя
33+
"pageUUID": "5218de4f-3f96-49d6-9ba7-d6f47c49d3e0" // ид страницы
34+
}
35+
```
36+
37+
Ответом будет статистика за день:
38+
39+
```$javascript
40+
{
41+
"amountAllVisits": 1, // количество визитов за день
42+
"amountUniqueUser": 1 // количество уникальных пользователей за день
43+
}
44+
```
45+
46+
**GET /event :**
47+
48+
Возвращает отчет за период
49+
50+
В параметрах запроса нужно передать
51+
52+
`begin` - дата в формате dd.MM.yyyy (02.10.2018), начало периода включительно
53+
54+
`end` - дата в формате dd.MM.yyyy (02.10.2018), окончание периода не включительно
55+
56+
Ответом будет статистика за день:
57+
58+
```$javascript
59+
{
60+
"amountAllVisits": 1, // количество визитов
61+
"amountUniqueUser": 1 // количество уникальных пользователей
62+
"amountRegularUser": 1 // количество постоянных пользователей
63+
}
64+
```
65+

build.gradle

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
buildscript {
2+
ext {
3+
springBootVersion = '2.0.4.RELEASE'
4+
}
5+
repositories {
6+
mavenCentral()
7+
}
8+
dependencies {
9+
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
10+
}
11+
}
12+
13+
apply plugin: 'java'
14+
apply plugin: 'eclipse'
15+
apply plugin: 'org.springframework.boot'
16+
apply plugin: 'io.spring.dependency-management'
17+
18+
group = 'space.zhdanov.testwork'
19+
version = '0.0.1-SNAPSHOT'
20+
sourceCompatibility = 1.8
21+
22+
repositories {
23+
mavenCentral()
24+
}
25+
26+
27+
dependencies {
28+
implementation('org.springframework.boot:spring-boot-starter-data-mongodb-reactive')
29+
implementation('org.springframework.boot:spring-boot-starter-webflux')
30+
testImplementation('org.springframework.boot:spring-boot-starter-test')
31+
testImplementation('io.projectreactor:reactor-test')
32+
compileOnly 'org.projectlombok:lombok:1.16.8'
33+
}
34+

settings.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rootProject.name = 'digitalzone'
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package space.zhdanov.testwork.digitalzone;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
import org.springframework.data.mongodb.config.EnableMongoAuditing;
6+
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
7+
8+
@EnableMongoAuditing
9+
@EnableReactiveMongoRepositories
10+
@SpringBootApplication
11+
public class DigitalzoneApplication {
12+
13+
public static void main(String[] args) {
14+
SpringApplication.run(DigitalzoneApplication.class, args);
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package space.zhdanov.testwork.digitalzone;
2+
3+
import com.fasterxml.jackson.core.JsonProcessingException;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import space.zhdanov.testwork.digitalzone.entity.Event;
6+
7+
import java.util.Date;
8+
import java.util.UUID;
9+
10+
public class Test {
11+
12+
public static void main(String[] args) {
13+
Event event = Event.builder().PageUUID(UUID.randomUUID()).UserUUID(UUID.randomUUID()).timestamp(new Date()).build();
14+
15+
ObjectMapper ob = new ObjectMapper();
16+
17+
try {
18+
System.out.println(ob.writeValueAsString(event));
19+
} catch (JsonProcessingException e) {
20+
e.printStackTrace();
21+
}
22+
}
23+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package space.zhdanov.testwork.digitalzone.controller;
2+
3+
import org.springframework.format.annotation.DateTimeFormat;
4+
import org.springframework.http.HttpStatus;
5+
import org.springframework.web.bind.annotation.*;
6+
import reactor.core.publisher.Mono;
7+
import space.zhdanov.testwork.digitalzone.entity.Event;
8+
import space.zhdanov.testwork.digitalzone.entity.ResponseAggregationEvents;
9+
import space.zhdanov.testwork.digitalzone.service.EventService;
10+
11+
import java.util.Date;
12+
import java.util.UUID;
13+
14+
@RestController
15+
@RequestMapping("/event")
16+
public class EventController {
17+
18+
private final EventService eventService;
19+
20+
public EventController(EventService eventService) {
21+
this.eventService = eventService;
22+
}
23+
24+
@PostMapping
25+
@ResponseStatus(HttpStatus.CREATED)
26+
public Mono<ResponseAggregationEvents> addEvent(@RequestBody Mono<Event> event) {
27+
return eventService.addEvent(
28+
event.map(it-> {
29+
it.setTimestamp(new Date());
30+
return it;
31+
}))
32+
.then(eventService.getAggregationDataForDay());
33+
}
34+
35+
@GetMapping()
36+
public Mono<ResponseAggregationEvents> getStatisticForPeriod(@RequestParam @DateTimeFormat(pattern="dd.MM.yyyy") Date begin,
37+
@RequestParam @DateTimeFormat(pattern="dd.MM.yyyy") Date end) {
38+
return eventService.getAggregationDataForPeriod(begin, end);
39+
}
40+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package space.zhdanov.testwork.digitalzone.entity;
2+
3+
import com.fasterxml.jackson.annotation.JsonFormat;
4+
import com.fasterxml.jackson.annotation.JsonInclude;
5+
import lombok.*;
6+
import org.springframework.data.annotation.Id;
7+
import org.springframework.data.mongodb.core.mapping.Document;
8+
9+
import java.io.Serializable;
10+
import java.util.Date;
11+
import java.util.UUID;
12+
13+
@Data
14+
@Builder
15+
@Document
16+
@NoArgsConstructor
17+
@AllArgsConstructor
18+
public class Event implements Serializable {
19+
20+
@Id
21+
private String _id;
22+
23+
private UUID UserUUID;
24+
private UUID PageUUID;
25+
@JsonFormat(shape = JsonFormat.Shape.STRING, timezone = "GMT+3", pattern = "dd.MM.yyyy HH:mm:ss")
26+
private Date timestamp;
27+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package space.zhdanov.testwork.digitalzone.entity;
2+
3+
import com.fasterxml.jackson.annotation.JsonInclude;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
7+
@JsonInclude(value = JsonInclude.Include.NON_NULL)
8+
@Data
9+
@Builder
10+
public class ResponseAggregationEvents {
11+
12+
private Integer amountAllVisits;
13+
private Integer amountUniqueUser;
14+
private Integer amountRegularUser;
15+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package space.zhdanov.testwork.digitalzone.repository;
2+
3+
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
4+
import org.springframework.data.repository.reactive.ReactiveCrudRepository;
5+
import space.zhdanov.testwork.digitalzone.entity.Event;
6+
7+
public interface EventRepository extends ReactiveMongoRepository<Event, String> {
8+
}

0 commit comments

Comments
 (0)