-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User should be able to start, record and end activity #18
Open
zzat
wants to merge
21
commits into
main
Choose a base branch
from
feature/start_activity
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+810
−5
Open
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
27f067d
Add route to start new activity
tarun-porter 9bfa649
Add unit test for activity controller
tarun-porter ea1b537
Add unit test for activity service implementation
tarun-porter 4a7554f
Add class name to WebMvcTest annotation for healthcheck
tarun-porter 91d75f5
Add end activity route
tarun-porter 2ae731d
Add unit test for end activity service
tarun-porter a7ee56c
Add tests for activity repository
tarun-porter 69460eb
Add unit test for end activity controller
tarun-porter 46d5508
Add start activity view
tarun-porter fe0fd9f
Add end activity view
tarun-porter 00f825c
Add route to log geolocation data
tarun-porter fd86e89
Add thymeleaf config to application properties
tarun-porter ebd71e6
Fix null created_at time issue
tarun-porter f740e4c
Add recordedAt time to geolocation dto
tarun-porter 3de5884
Add view for recording geolocation
tarun-porter 10fead7
Use getCurrentPosition instead of watchPosition for getting geolocati…
tarun-porter 90dccff
Auto generate name for new activity
tarun-porter a60bfc6
Add not null, not blank constranints on StartActivityDto
tarun-porter 3ba26d7
Add UnprocessableEntityException
tarun-porter eac2ad9
Add ControllerAdvice
tarun-porter 2a48dc7
Add flyway gradle plugin
tarun-porter File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
...-activities/src/main/java/com/nilenso/swiftactivities/controllers/ActivityController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package com.nilenso.swiftactivities.controllers; | ||
|
||
import com.nilenso.swiftactivities.models.dtos.GeolocationDto; | ||
import com.nilenso.swiftactivities.services.ActivityService; | ||
import jakarta.validation.Valid; | ||
import com.nilenso.swiftactivities.models.Activity; | ||
import com.nilenso.swiftactivities.models.dtos.StartActivityDto; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.UUID; | ||
|
||
@RestController | ||
@RequestMapping("/api/activity") | ||
public class ActivityController { | ||
private final ActivityService activityService; | ||
|
||
public ActivityController(ActivityService activityService) { | ||
this.activityService = activityService; | ||
} | ||
|
||
@PostMapping | ||
@ResponseStatus(HttpStatus.CREATED) | ||
public Map<String, UUID> createActivity(@Valid @RequestBody StartActivityDto startActivityDto) { | ||
var activity = activityService.addActivity(startActivityDto); | ||
Map<String, UUID> response = new HashMap<String, UUID>(); | ||
response.put("activityId", activity.getActivityId()); | ||
return response; | ||
} | ||
|
||
@PostMapping("/{activityId}/log") | ||
@ResponseStatus(HttpStatus.NO_CONTENT) | ||
public void logGeolocationData(@PathVariable UUID activityId, | ||
@Valid @RequestBody GeolocationDto geolocationDto) { | ||
activityService.logGeolocationData(activityId, geolocationDto); | ||
} | ||
|
||
@PostMapping("/{activityId}/end") | ||
@ResponseStatus(HttpStatus.NO_CONTENT) | ||
public void endActivity(@PathVariable UUID activityId) { | ||
activityService.endActivity(activityId); | ||
} | ||
} |
135 changes: 135 additions & 0 deletions
135
swift-activities/src/main/java/com/nilenso/swiftactivities/models/Activity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
package com.nilenso.swiftactivities.models; | ||
|
||
import jakarta.persistence.*; | ||
|
||
import java.time.Instant; | ||
import java.util.Objects; | ||
import java.util.UUID; | ||
|
||
@Entity | ||
@Table(name = "activity") | ||
public class Activity { | ||
public static enum ActivityType { | ||
Running, | ||
Swimming, | ||
Cycling | ||
} | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.UUID) | ||
@Column(name = "activity_id") | ||
private UUID activityId; | ||
@Column(name = "user_id") | ||
private UUID userId; | ||
@Column(name = "name") | ||
private String name; | ||
@Column(name = "type", columnDefinition = "activity_type") | ||
@Enumerated(EnumType.STRING) | ||
private ActivityType type; | ||
@Column(name = "start_time") | ||
private Instant startTime; | ||
@Column(name = "end_time") | ||
private Instant endTime; | ||
@Column(name = "created_at") | ||
private Instant createdAt; | ||
@Column(name = "updated_at") | ||
private Instant updatedAt; | ||
|
||
public UUID getActivityId() { | ||
return activityId; | ||
} | ||
|
||
public void setActivityId(UUID activityId) { | ||
this.activityId = activityId; | ||
} | ||
|
||
public UUID getUserId() { | ||
return userId; | ||
} | ||
|
||
public void setUserId(UUID userId) { | ||
this.userId = userId; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public void setName(String name) { | ||
this.name = name; | ||
} | ||
|
||
public ActivityType getType() { | ||
return type; | ||
} | ||
|
||
public void setType(ActivityType type) { | ||
this.type = type; | ||
} | ||
|
||
public Instant getStartTime() { | ||
return startTime; | ||
} | ||
|
||
public void setStartTime(Instant startTime) { | ||
this.startTime = startTime; | ||
} | ||
|
||
public Instant getEndTime() { | ||
return endTime; | ||
} | ||
|
||
public void setEndTime(Instant endTime) { | ||
this.endTime = endTime; | ||
} | ||
|
||
public Instant getCreatedAt() { | ||
return createdAt; | ||
} | ||
|
||
public void setCreatedAt(Instant createdAt) { | ||
this.createdAt = createdAt; | ||
} | ||
|
||
public Instant getUpdatedAt() { | ||
return updatedAt; | ||
} | ||
|
||
public void setUpdatedAt(Instant updatedAt) { | ||
this.updatedAt = updatedAt; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
Activity activity = (Activity) o; | ||
return Objects.equals(activityId, activity.activityId) | ||
&& Objects.equals(userId, activity.userId) | ||
&& Objects.equals(name, activity.name) | ||
&& type == activity.type | ||
&& Objects.equals(startTime, activity.startTime) | ||
&& Objects.equals(endTime, activity.endTime) | ||
&& Objects.equals(createdAt, activity.createdAt) | ||
&& Objects.equals(updatedAt, activity.updatedAt); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(activityId, userId, name, type, startTime, endTime, createdAt, updatedAt); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Activity{" + | ||
"activityId=" + activityId + | ||
", userId=" + userId + | ||
", name='" + name + '\'' + | ||
", type=" + type + | ||
", startTime=" + startTime + | ||
", endTime=" + endTime + | ||
", createdAt=" + createdAt + | ||
", updatedAt=" + updatedAt + | ||
'}'; | ||
} | ||
} |
93 changes: 93 additions & 0 deletions
93
...-activities/src/main/java/com/nilenso/swiftactivities/models/ActivityGeolocationData.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package com.nilenso.swiftactivities.models; | ||
|
||
import com.nilenso.swiftactivities.models.dtos.GeolocationDto; | ||
import io.hypersistence.utils.hibernate.type.json.JsonType; | ||
import jakarta.persistence.*; | ||
import org.hibernate.annotations.Type; | ||
|
||
import java.math.BigInteger; | ||
import java.time.Instant; | ||
import java.util.Objects; | ||
import java.util.UUID; | ||
|
||
@Entity | ||
@Table(name = "activity_geolocation_data") | ||
public class ActivityGeolocationData { | ||
@Id | ||
@GeneratedValue(strategy = GenerationType.UUID) | ||
@Column(name = "geolocation_data_id") | ||
private UUID geolocationDataId; | ||
@Column(name = "activity_id") | ||
private UUID activityId; | ||
@Type(JsonType.class) | ||
@Column(name = "data") | ||
private GeolocationDto data; | ||
@Column(name = "recorded_at") | ||
private Instant recordedAt; | ||
@Column(name = "created_at") | ||
private Instant createdAt; | ||
|
||
public UUID getGeolocationDataId() { | ||
return geolocationDataId; | ||
} | ||
|
||
public void setGeolocationDataId(UUID geolocationDataId) { | ||
this.geolocationDataId = geolocationDataId; | ||
} | ||
|
||
public UUID getActivityId() { | ||
return activityId; | ||
} | ||
|
||
public void setActivityId(UUID activityId) { | ||
this.activityId = activityId; | ||
} | ||
|
||
public GeolocationDto getData() { | ||
return data; | ||
} | ||
|
||
public void setData(GeolocationDto data) { | ||
this.data = data; | ||
} | ||
|
||
public Instant getRecordedAt() { | ||
return recordedAt; | ||
} | ||
|
||
public void setRecordedAt(Instant recordedAt) { | ||
this.recordedAt = recordedAt; | ||
} | ||
|
||
public Instant getCreatedAt() { | ||
return createdAt; | ||
} | ||
|
||
public void setCreatedAt(Instant createdAt) { | ||
this.createdAt = createdAt; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
ActivityGeolocationData that = (ActivityGeolocationData) o; | ||
return Objects.equals(geolocationDataId, that.geolocationDataId) && Objects.equals(activityId, that.activityId) && Objects.equals(data, that.data) && Objects.equals(recordedAt, that.recordedAt) && Objects.equals(createdAt, that.createdAt); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(geolocationDataId, activityId, data, recordedAt, createdAt); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "ActivityGeolocationData{" + | ||
"geolocationDataId=" + geolocationDataId + | ||
", activityId=" + activityId + | ||
", data=" + data + | ||
", recordedAt=" + recordedAt + | ||
", createdAt=" + createdAt + | ||
'}'; | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
swift-activities/src/main/java/com/nilenso/swiftactivities/models/dtos/GeolocationDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package com.nilenso.swiftactivities.models.dtos; | ||
|
||
public record GeolocationDto(Double latitude, | ||
Double longitude, | ||
Double accuracy) { | ||
} |
8 changes: 8 additions & 0 deletions
8
swift-activities/src/main/java/com/nilenso/swiftactivities/models/dtos/StartActivityDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.nilenso.swiftactivities.models.dtos; | ||
|
||
import com.nilenso.swiftactivities.models.Activity; | ||
import jakarta.validation.constraints.NotNull; | ||
|
||
public record StartActivityDto(String name, | ||
@NotNull(message = "Activity 'type' missing") | ||
Activity.ActivityType type) { } |
10 changes: 10 additions & 0 deletions
10
...main/java/com/nilenso/swiftactivities/repositories/ActivityGeolocationDataRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.nilenso.swiftactivities.repositories; | ||
|
||
import com.nilenso.swiftactivities.models.ActivityGeolocationData; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.math.BigInteger; | ||
import java.util.UUID; | ||
|
||
public interface ActivityGeolocationDataRepository extends JpaRepository<ActivityGeolocationData, UUID> { | ||
} |
9 changes: 9 additions & 0 deletions
9
...activities/src/main/java/com/nilenso/swiftactivities/repositories/ActivityRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.nilenso.swiftactivities.repositories; | ||
|
||
import com.nilenso.swiftactivities.models.Activity; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import java.util.UUID; | ||
|
||
public interface ActivityRepository extends JpaRepository<Activity, UUID> { | ||
} |
15 changes: 15 additions & 0 deletions
15
swift-activities/src/main/java/com/nilenso/swiftactivities/services/ActivityService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.nilenso.swiftactivities.services; | ||
|
||
import com.nilenso.swiftactivities.models.Activity; | ||
import com.nilenso.swiftactivities.models.dtos.GeolocationDto; | ||
import com.nilenso.swiftactivities.models.dtos.StartActivityDto; | ||
|
||
import java.util.UUID; | ||
|
||
public interface ActivityService { | ||
public Activity addActivity(StartActivityDto startActivityDto); | ||
|
||
public void endActivity(UUID activityId); | ||
|
||
public void logGeolocationData(UUID activityId, GeolocationDto geolocationDto); | ||
} |
50 changes: 50 additions & 0 deletions
50
swift-activities/src/main/java/com/nilenso/swiftactivities/services/ActivityServiceImpl.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.nilenso.swiftactivities.services; | ||
|
||
import com.nilenso.swiftactivities.models.Activity; | ||
import com.nilenso.swiftactivities.models.ActivityGeolocationData; | ||
import com.nilenso.swiftactivities.models.dtos.GeolocationDto; | ||
import com.nilenso.swiftactivities.models.dtos.StartActivityDto; | ||
import com.nilenso.swiftactivities.repositories.ActivityGeolocationDataRepository; | ||
import com.nilenso.swiftactivities.repositories.ActivityRepository; | ||
import jakarta.persistence.EntityNotFoundException; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.time.Instant; | ||
import java.util.UUID; | ||
|
||
@Service | ||
public class ActivityServiceImpl implements ActivityService { | ||
private final ActivityRepository activityRepository; | ||
private final ActivityGeolocationDataRepository geolocationDataRepository; | ||
|
||
public ActivityServiceImpl(ActivityRepository activityRepository, ActivityGeolocationDataRepository geolocationDataRepository) { | ||
this.activityRepository = activityRepository; | ||
this.geolocationDataRepository = geolocationDataRepository; | ||
} | ||
|
||
@Override | ||
public Activity addActivity(StartActivityDto startActivityDto) { | ||
var activity = new Activity(); | ||
Instant currentUtcTime = Instant.now(); | ||
activity.setName(startActivityDto.name()); | ||
activity.setType(startActivityDto.type()); | ||
activity.setStartTime(currentUtcTime); | ||
return activityRepository.save(activity); | ||
} | ||
|
||
@Override | ||
public void endActivity(UUID activityId) { | ||
Activity existingActivity = activityRepository.findById(activityId) | ||
.orElseThrow(() -> new EntityNotFoundException("Couldn't find the activity")); | ||
existingActivity.setEndTime(Instant.now()); | ||
activityRepository.save(existingActivity); | ||
} | ||
|
||
@Override | ||
public void logGeolocationData(UUID activityId, GeolocationDto geolocationDto) { | ||
var geolocationData = new ActivityGeolocationData(); | ||
geolocationData.setData(geolocationDto); | ||
geolocationData.setActivityId(activityId); | ||
geolocationDataRepository.save(geolocationData); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't name be
NotNull
as well?