Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0cdd9fe
Include db changelog v3
SelahattinSert Dec 8, 2024
cc2ab2d
Add sensor_metadata liquibase changelog
SelahattinSert Dec 8, 2024
920ae1b
Add sensor entities
SelahattinSert Dec 8, 2024
e91bb23
Add SensorType enum
SelahattinSert Dec 8, 2024
a4f0f67
Add sensor exceptions
SelahattinSert Dec 8, 2024
25acda8
Add sensor repositories
SelahattinSert Dec 8, 2024
80e105d
Add sensor service
SelahattinSert Dec 8, 2024
167dd8b
Add sensor service implementations
SelahattinSert Dec 8, 2024
8e23d30
Add sensor dto
SelahattinSert Dec 8, 2024
2ee497a
Add sensor response
SelahattinSert Dec 8, 2024
9f3e26b
Add sensor dto converter
SelahattinSert Dec 8, 2024
ecc1cda
Add sensor exception handler methods
SelahattinSert Dec 8, 2024
3ae6b1a
Add sensor REST controllers
SelahattinSert Dec 8, 2024
ae5d91b
Include changelog v3
SelahattinSert Dec 14, 2024
0b2c00d
Remove redundant exception handling
SelahattinSert Dec 14, 2024
5012b03
Refactor service methods
SelahattinSert Dec 14, 2024
37e3f5a
Refactor repository
SelahattinSert Dec 14, 2024
ed39154
Add enum explanation
SelahattinSert Dec 14, 2024
973954c
Add sensors list to camera entity
SelahattinSert Dec 14, 2024
0a42b37
Add toString annotation
SelahattinSert Dec 14, 2024
7298ae8
Add toString annotation
SelahattinSert Dec 14, 2024
15483c0
Refactor conversion methods
SelahattinSert Dec 14, 2024
71eceac
Remove redundant path variable
SelahattinSert Dec 14, 2024
6531381
Merge branch 'master' into 'task/add-sensor-metadata' to include CI w…
SelahattinSert Dec 19, 2024
961d86c
Include db changelog v3
SelahattinSert Dec 8, 2024
beb2aa8
Merge branch 'master' into 'task/add-sensor-metadata' to include CI w…
SelahattinSert Dec 19, 2024
3debae9
Fix test case issue
SelahattinSert Dec 19, 2024
d13a3cc
Utilize path variable camera id
SelahattinSert Dec 20, 2024
37aa546
Add list of sensors to camera response
SelahattinSert Dec 20, 2024
058b0f5
Refactor sensor methods
SelahattinSert Dec 20, 2024
9f013e5
Refactor sensor receive method
SelahattinSert Dec 23, 2024
38f15be
Add sensor dto converter unit test
SelahattinSert Dec 27, 2024
8bff631
Add light sensor unit and integration tests
SelahattinSert Dec 27, 2024
33d39d6
Add sensor dto validation method
SelahattinSert Dec 29, 2024
402a178
Add test cases for invalid data
SelahattinSert Dec 29, 2024
914a5c1
Fix sensor test methods
SelahattinSert Dec 29, 2024
e9dd43a
Remove unused import
SelahattinSert Jan 1, 2025
fe79fcf
Add new test cases
SelahattinSert Jan 1, 2025
7529618
Fix test methods
SelahattinSert Jan 1, 2025
01d7d73
Add motion and temperature sensor controller tests
SelahattinSert Jan 3, 2025
131ee0d
Add motion and temperature sensor repository tests
SelahattinSert Jan 4, 2025
f297971
Add motion and temperature sensor service tests
SelahattinSert Jan 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
import com.onboarding.camera.cameraonboarding.exception.ImageNotFoundException;
import com.onboarding.camera.cameraonboarding.exception.ImageNotUploadedException;
import com.onboarding.camera.cameraonboarding.exception.LocationNotAddedException;
import com.onboarding.camera.cameraonboarding.exception.SensorMismatchException;
import com.onboarding.camera.cameraonboarding.exception.SensorNotCreatedException;
import com.onboarding.camera.cameraonboarding.exception.SensorNotFoundException;
import com.onboarding.camera.cameraonboarding.exception.SensorNotUpdatedException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
Expand Down Expand Up @@ -166,5 +170,53 @@ public ResponseEntity<ErrorResponse> handleLocationNotAddedException(LocationNot

return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(SensorNotCreatedException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResponseEntity<ErrorResponse> handleSensorNotCreatedException(SensorNotCreatedException ex) {
ErrorResponse errorResponse = new ErrorResponse();

errorResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());

return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(SensorNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ResponseEntity<ErrorResponse> handleSensorNotFoundException(SensorNotFoundException ex) {
ErrorResponse errorResponse = new ErrorResponse();

errorResponse.setStatusCode(HttpStatus.NOT_FOUND.value());
errorResponse.setMessage(ex.getMessage());

return new ResponseEntity<>(errorResponse, HttpStatus.NOT_FOUND);
}

@ExceptionHandler(SensorNotUpdatedException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ResponseEntity<ErrorResponse> handleSensorNotUpdatedException(SensorNotUpdatedException ex) {
ErrorResponse errorResponse = new ErrorResponse();

errorResponse.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
errorResponse.setMessage(ex.getMessage());

return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
}

@ExceptionHandler(SensorMismatchException.class)
@ResponseStatus(HttpStatus.CONFLICT)
@ResponseBody
public ResponseEntity<ErrorResponse> handleSensorMismatchException(SensorMismatchException ex) {
ErrorResponse errorResponse = new ErrorResponse();

errorResponse.setStatusCode(HttpStatus.CONFLICT.value());
errorResponse.setMessage(ex.getMessage());

return new ResponseEntity<>(errorResponse, HttpStatus.CONFLICT);
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.onboarding.camera.cameraonboarding.controller;

import com.onboarding.camera.cameraonboarding.converter.SensorDtoConverter;
import com.onboarding.camera.cameraonboarding.dto.SensorDto;
import com.onboarding.camera.cameraonboarding.dto.SensorResponse;
import com.onboarding.camera.cameraonboarding.entity.LightSensor;
import com.onboarding.camera.cameraonboarding.service.impl.LightSensorService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("${api.version}/camera/{cameraId}/sensor/light")
@RequiredArgsConstructor
public class LightSensorController {

private final LightSensorService lightSensorService;

private final SensorDtoConverter sensorDtoConverter;

@PostMapping
public ResponseEntity<SensorResponse> addLightSensor(
@PathVariable UUID cameraId,
@Valid @RequestBody SensorDto sensorDto) {

LightSensor sensorMetadata = sensorDtoConverter.toLightEntity(sensorDto);
LightSensor savedSensor = lightSensorService.handleCreateSensor(cameraId, sensorMetadata);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(savedSensor);

return new ResponseEntity<>(sensorResponse, HttpStatus.CREATED);
}

@GetMapping
public ResponseEntity<List<LightSensor>> getLightSensors(
@PathVariable UUID cameraId) {

List<LightSensor> sensors = lightSensorService.handleGetSensorsByCameraId(cameraId);
return ResponseEntity.ok(sensors);
}

@PutMapping("/{sensorId}")
public ResponseEntity<SensorResponse> updateLightSensor(
@PathVariable UUID sensorId,
@Valid @RequestBody SensorDto sensorDto, @PathVariable UUID cameraId) {

LightSensor sensorMetadata = sensorDtoConverter.toLightEntity(sensorDto);
LightSensor updatedSensor = lightSensorService.handleUpdateSensor(cameraId, sensorId, sensorMetadata);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(updatedSensor);
return ResponseEntity.ok(sensorResponse);
}

@DeleteMapping("/{sensorId}")
public ResponseEntity<Void> deleteLightSensor(
@PathVariable UUID sensorId, @PathVariable UUID cameraId) {

lightSensorService.handleDeleteSensor(cameraId, sensorId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.onboarding.camera.cameraonboarding.controller;

import com.onboarding.camera.cameraonboarding.converter.SensorDtoConverter;
import com.onboarding.camera.cameraonboarding.dto.SensorDto;
import com.onboarding.camera.cameraonboarding.dto.SensorResponse;
import com.onboarding.camera.cameraonboarding.entity.MotionSensor;
import com.onboarding.camera.cameraonboarding.service.impl.MotionSensorService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("${api.version}/camera/{cameraId}/sensor/motion")
@RequiredArgsConstructor
public class MotionSensorController {

private final MotionSensorService motionSensorService;

private final SensorDtoConverter sensorDtoConverter;

@PostMapping
public ResponseEntity<SensorResponse> addMotionSensor(
@PathVariable UUID cameraId,
@Valid @RequestBody SensorDto sensorDto) {

MotionSensor motionSensor = sensorDtoConverter.toMotionEntity(sensorDto);
MotionSensor savedSensor = motionSensorService.handleCreateSensor(cameraId, motionSensor);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(savedSensor);

return new ResponseEntity<>(sensorResponse, HttpStatus.CREATED);
}

@GetMapping
public ResponseEntity<List<MotionSensor>> getMotionSensors(
@PathVariable UUID cameraId) {

List<MotionSensor> sensors = motionSensorService.handleGetSensorsByCameraId(cameraId);
return ResponseEntity.ok(sensors);
}

@PutMapping("/{sensorId}")
public ResponseEntity<SensorResponse> updateMotionSensor(
@PathVariable UUID sensorId,
@Valid @RequestBody SensorDto sensorDto, @PathVariable UUID cameraId) {

MotionSensor motionSensor = sensorDtoConverter.toMotionEntity(sensorDto);
MotionSensor updatedSensor = motionSensorService.handleUpdateSensor(cameraId, sensorId, motionSensor);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(updatedSensor);
return ResponseEntity.ok(sensorResponse);
}

@DeleteMapping("/{sensorId}")
public ResponseEntity<Void> deleteMotionSensor(
@PathVariable UUID sensorId, @PathVariable UUID cameraId) {

motionSensorService.handleDeleteSensor(cameraId, sensorId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.onboarding.camera.cameraonboarding.controller;

import com.onboarding.camera.cameraonboarding.converter.SensorDtoConverter;
import com.onboarding.camera.cameraonboarding.dto.SensorDto;
import com.onboarding.camera.cameraonboarding.dto.SensorResponse;
import com.onboarding.camera.cameraonboarding.entity.TemperatureSensor;
import com.onboarding.camera.cameraonboarding.service.impl.TemperatureSensorService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("${api.version}/camera/{cameraId}/sensor/temperature")
@RequiredArgsConstructor
public class TemperatureSensorController {

private final TemperatureSensorService temperatureSensorService;

private final SensorDtoConverter sensorDtoConverter;

@PostMapping
public ResponseEntity<SensorResponse> addTemperatureSensor(
@PathVariable UUID cameraId,
@Valid @RequestBody SensorDto sensorDto) {

TemperatureSensor sensorMetadata = sensorDtoConverter.toTemperatureEntity(sensorDto);
TemperatureSensor savedSensor = temperatureSensorService.handleCreateSensor(cameraId, sensorMetadata);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(savedSensor);
return new ResponseEntity<>(sensorResponse, HttpStatus.CREATED);
}

@GetMapping
public ResponseEntity<List<TemperatureSensor>> getTemperatureSensors(
@PathVariable UUID cameraId) {

List<TemperatureSensor> sensors = temperatureSensorService.handleGetSensorsByCameraId(cameraId);
return ResponseEntity.ok(sensors);
}

@PutMapping("/{sensorId}")
public ResponseEntity<SensorResponse> updateTemperatureSensor(
@PathVariable UUID sensorId,
@Valid @RequestBody SensorDto sensorDto, @PathVariable UUID cameraId) {

TemperatureSensor sensorMetadata = sensorDtoConverter.toTemperatureEntity(sensorDto);
TemperatureSensor updatedSensor = temperatureSensorService.handleUpdateSensor(cameraId, sensorId, sensorMetadata);
SensorResponse sensorResponse = sensorDtoConverter.toSensorResponse(updatedSensor);
return ResponseEntity.ok(sensorResponse);
}

@DeleteMapping("/{sensorId}")
public ResponseEntity<Void> deleteTemperatureSensor(
@PathVariable UUID sensorId, @PathVariable UUID cameraId) {

temperatureSensorService.handleDeleteSensor(cameraId, sensorId);
return ResponseEntity.noContent().build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import com.onboarding.camera.cameraonboarding.dto.CameraDto;
import com.onboarding.camera.cameraonboarding.dto.CameraResponse;
import com.onboarding.camera.cameraonboarding.dto.SensorResponse;
import com.onboarding.camera.cameraonboarding.entity.Camera;
import org.springframework.stereotype.Component;

import java.util.stream.Collectors;

@Component
public class CameraDtoConverter {

Expand All @@ -20,6 +23,18 @@ public CameraResponse toCameraResponse(Camera camera) {
response.setCameraId(camera.getCamId());
response.setCameraName(camera.getCameraName());
response.setFirmwareVersion(camera.getFirmwareVersion());
response.setSensors(camera.getSensors()
.stream()
.map(sensor -> {
SensorResponse sensorResponse = new SensorResponse();
sensorResponse.setId(sensor.getId());
sensorResponse.setName(sensor.getName());
sensorResponse.setVersion(sensor.getVersion());
sensorResponse.setSensorType(sensor.getSensorType());
sensorResponse.setData(sensor.getData());
return sensorResponse;
})
.collect(Collectors.toList()));
return response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.onboarding.camera.cameraonboarding.converter;

import com.onboarding.camera.cameraonboarding.dto.SensorDto;
import com.onboarding.camera.cameraonboarding.dto.SensorResponse;
import com.onboarding.camera.cameraonboarding.entity.LightSensor;
import com.onboarding.camera.cameraonboarding.entity.MotionSensor;
import com.onboarding.camera.cameraonboarding.entity.Sensor;
import com.onboarding.camera.cameraonboarding.entity.TemperatureSensor;
import com.onboarding.camera.cameraonboarding.enums.SensorType;
import com.onboarding.camera.cameraonboarding.exception.SensorMismatchException;
import org.springframework.stereotype.Component;

@Component
public class SensorDtoConverter {

public MotionSensor toMotionEntity(SensorDto sensorDto) {
if (sensorDto.getSensorType() != SensorType.MOTION) {
throw new SensorMismatchException("Invalid sensor type for MotionSensor");
}

MotionSensor sensorMetadata = new MotionSensor();
sensorMetadata.setName(sensorDto.getName());
sensorMetadata.setVersion(sensorDto.getVersion());
sensorMetadata.setSensorType(sensorDto.getSensorType());
sensorMetadata.setData(sensorDto.getData());
return sensorMetadata;
}

public LightSensor toLightEntity(SensorDto sensorDto) {
if (sensorDto.getSensorType() != SensorType.LIGHT) {
throw new SensorMismatchException("Invalid sensor type for LightSensor");
}

LightSensor sensorMetadata = new LightSensor();
sensorMetadata.setName(sensorDto.getName());
sensorMetadata.setVersion(sensorDto.getVersion());
sensorMetadata.setSensorType(sensorDto.getSensorType());
sensorMetadata.setData(sensorDto.getData());
return sensorMetadata;
}

public TemperatureSensor toTemperatureEntity(SensorDto sensorDto) {
if (sensorDto.getSensorType() != SensorType.TEMPERATURE) {
throw new SensorMismatchException("Invalid sensor type for TemperatureSensor");
}

TemperatureSensor sensorMetadata = new TemperatureSensor();
sensorMetadata.setName(sensorDto.getName());
sensorMetadata.setVersion(sensorDto.getVersion());
sensorMetadata.setSensorType(sensorDto.getSensorType());
sensorMetadata.setData(sensorDto.getData());
return sensorMetadata;
}

public SensorResponse toSensorResponse(Sensor sensor) {
SensorResponse response = new SensorResponse();
response.setId(sensor.getId());
response.setName(sensor.getName());
response.setVersion(sensor.getVersion());
response.setSensorType(sensor.getSensorType());
response.setData(sensor.getData());
return response;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package com.onboarding.camera.cameraonboarding.dto;

import lombok.Data;

import java.util.List;
import java.util.UUID;

@Data
public class CameraResponse {
private UUID cameraId;
private String cameraName;
private String firmwareVersion;
private List<SensorResponse> sensors;
}
Loading
Loading