diff --git a/README.md b/README.md index e2d11e304..7156d2579 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # uPresent +uPresent is a smart, contactless attendance tracking system designed for academic institutions. It relies on facial recognition and geo-fencing. + **Build Status** - Components: [![TravisCI](https://api.travis-ci.com/rajan123456/uPresent.svg?branch=master)](https://api.travis-ci.com/rajan123456/uPresent.svg?branch=master) - Mobile App: [![BitRise](https://app.bitrise.io/app/94539fb2e1e99188/status.svg?token=UdpO7BVErEwwgVQ-IR-PRQ&branch=master)](https://app.bitrise.io/app/94539fb2e1e99188/status.svg?token=UdpO7BVErEwwgVQ-IR-PRQ&branch=master) diff --git a/attendance/config.py b/attendance/config.py index 61fffe7dd..d12492de8 100644 --- a/attendance/config.py +++ b/attendance/config.py @@ -16,7 +16,7 @@ class Config(object): VAULT_PORT = 8200 VAULT_LOGIN_URL = "/v1/auth/cert/login" VAULT_DATA_URL = "/v1/aws/data" - # KAFKA_ADDRESS = "localhost:29092" + # KAFKA_ADDRESS = "localhost:9092" KAFKA_ADDRESS = "broker:29092" KAFKA_PUBLISH_TOPIC = "attendanceEvents" SAGA_ENABLED = 1 @@ -28,8 +28,12 @@ class Config(object): FACENET_RECOGNITION_API = "http://facenet:5000/api/face/" # MODULE_API_FETCH_DETAILS = 'https://dev.upresent.ga/management/manage/module?moduleCode=' MODULE_API_FETCH_DETAILS = "http://management:8080/manage/module?moduleCode=" - # MANAGEMENT_API_GEO_FENCE = "http://localhost:8081/manage/geo-fence?universityName=" - MANAGEMENT_API_GEO_FENCE = "http://management:8080/manage/geo-fence?universityName=" + # MANAGEMENT_API_GEO_FENCE = ( + # "http://localhost:8081/manage/school/geo-fence?schoolCode=" + # ) + MANAGEMENT_API_GEO_FENCE = ( + "http://management:8080/manage/school/geo-fence?schoolCode=" + ) # USER_API_FETCH_USER = "http://localhost:8084/user?username=" USER_API_FETCH_USER = "http://user:8080/user?username=" AZURE_FACE_ENDPOINT = "https://eastus.api.cognitive.microsoft.com/" diff --git a/management/src/main/java/com/upresent/management/controller/AdminModuleController.java b/management/src/main/java/com/upresent/management/controller/AdminModuleController.java index 625f58b55..ee0aff707 100644 --- a/management/src/main/java/com/upresent/management/controller/AdminModuleController.java +++ b/management/src/main/java/com/upresent/management/controller/AdminModuleController.java @@ -32,7 +32,7 @@ public ResponseEntity> createModule( @RequestBody ModuleData moduleInfo) { return RestUtils.successResponse(adminModuleService.createModule(moduleInfo)); } - + @PutMapping public ResponseEntity> updateModule( @RequestBody ModuleData moduleInfo) { diff --git a/management/src/main/java/com/upresent/management/controller/GeoFenceController.java b/management/src/main/java/com/upresent/management/controller/GeoFenceController.java deleted file mode 100644 index 09b74f0ef..000000000 --- a/management/src/main/java/com/upresent/management/controller/GeoFenceController.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.upresent.management.controller; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import com.upresent.management.entity.GeoFenceData; -import com.upresent.management.requestdto.GeoFenceReq; -import com.upresent.management.service.GeoFenceService; -import com.upresent.management.utils.RestResponse; -import com.upresent.management.utils.RestUtils; - -@RestController -@RequestMapping("/manage/geo-fence") -public class GeoFenceController { - - @Autowired - private GeoFenceService geoFenceService; - - @PostMapping - public ResponseEntity> addGeoFence(@RequestBody GeoFenceReq geoFenceReq) { - return RestUtils.successResponse(geoFenceService.addGeoFence(geoFenceReq)); - } - - @GetMapping - public ResponseEntity> fetchGeoFence( - @RequestParam("universityName") String universityName) { - return RestUtils.successResponse(geoFenceService.fetchGeoFence(universityName)); - } - - @GetMapping("/all") - public ResponseEntity>> fetchAllGeoFences() { - return RestUtils.successResponse(geoFenceService.fetchAllGeoFences()); - } - -} \ No newline at end of file diff --git a/management/src/main/java/com/upresent/management/controller/SchoolController.java b/management/src/main/java/com/upresent/management/controller/SchoolController.java new file mode 100644 index 000000000..00f03c688 --- /dev/null +++ b/management/src/main/java/com/upresent/management/controller/SchoolController.java @@ -0,0 +1,55 @@ +package com.upresent.management.controller; + +import com.upresent.management.entity.GeoFenceData; +import com.upresent.management.entity.SchoolData; +import com.upresent.management.service.SchoolService; +import com.upresent.management.utils.RestResponse; +import com.upresent.management.utils.RestUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +@RestController +@RequestMapping("/manage/school") +public class SchoolController { + + @Autowired + private SchoolService schoolService; + + @PostMapping + public ResponseEntity> createSchool( + @RequestBody SchoolData schoolInfo) { + return RestUtils.successResponse(schoolService.createSchool(schoolInfo)); + } + + @PutMapping + public ResponseEntity> updateSchool( + @RequestBody SchoolData schoolInfo) { + return RestUtils.successResponse(schoolService.updateSchool(schoolInfo)); + } + + @DeleteMapping + public ResponseEntity> deleteSchool( + @RequestParam String schoolCode, HttpServletRequest request) { + return RestUtils.successResponse(schoolService.deleteSchool(request, schoolCode)); + } + + @GetMapping + public ResponseEntity> getSchool( + @RequestParam String schoolCode) { + return RestUtils.successResponse(schoolService.getSchool(schoolCode)); + } + + @GetMapping(path="/all") + public ResponseEntity>> getAllSchools() { + return RestUtils.successResponse(schoolService.getAllSchools()); + } + + @GetMapping(path="/geo-fence") + public ResponseEntity> getGeoFence(@RequestParam String schoolCode) { + return RestUtils.successResponse(schoolService.fetchGeoFence(schoolCode)); + } +} diff --git a/management/src/main/java/com/upresent/management/entity/GeoFenceData.java b/management/src/main/java/com/upresent/management/entity/GeoFenceData.java index 38db29e69..65dc43229 100644 --- a/management/src/main/java/com/upresent/management/entity/GeoFenceData.java +++ b/management/src/main/java/com/upresent/management/entity/GeoFenceData.java @@ -17,7 +17,6 @@ public class GeoFenceData { private String id; @JsonIgnore private String username; - private String universityName; private Float latitude; private Float longitude; private Float radiusInMeter; diff --git a/management/src/main/java/com/upresent/management/entity/LectureData.java b/management/src/main/java/com/upresent/management/entity/LectureData.java new file mode 100644 index 000000000..4c971c8d9 --- /dev/null +++ b/management/src/main/java/com/upresent/management/entity/LectureData.java @@ -0,0 +1,22 @@ +package com.upresent.management.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedDate; + +import java.util.Date; + +@Data +public class LectureData { + @Id + @JsonIgnore + private String id; + private String date; //pattern = "MM/dd/yyyy" + private String startTime; //pattern = "13:59" + private String endTime; //pattern = "17:59" + private String createdBy; + @JsonIgnore + @LastModifiedDate + private Date updatedOn; +} diff --git a/management/src/main/java/com/upresent/management/entity/ModuleData.java b/management/src/main/java/com/upresent/management/entity/ModuleData.java index af216958b..dbf55a623 100644 --- a/management/src/main/java/com/upresent/management/entity/ModuleData.java +++ b/management/src/main/java/com/upresent/management/entity/ModuleData.java @@ -3,6 +3,7 @@ import java.util.Date; import java.util.List; +import com.fasterxml.jackson.annotation.JsonIgnore; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.LastModifiedDate; @@ -13,14 +14,13 @@ public class ModuleData { @Id private String moduleCode; + private String schoolCode; private String moduleName; -// pattern = "MM/dd/yyyy" - private String startDate; -// pattern = "MM/dd/yyyy" - private String endDate; - // Mon, Tue, Wed, Thur, Fri, Sat, Sun - private List scheduledDays; + private String startDate; //pattern = "MM/dd/yyyy" + private String endDate; //pattern = "MM/dd/yyyy" + private List schedule; private String createdBy; + @JsonIgnore @LastModifiedDate private Date updatedOn; private List studentUsernames; diff --git a/management/src/main/java/com/upresent/management/entity/MetricsData.java b/management/src/main/java/com/upresent/management/entity/ReportsData.java similarity index 87% rename from management/src/main/java/com/upresent/management/entity/MetricsData.java rename to management/src/main/java/com/upresent/management/entity/ReportsData.java index 4528dc253..23e26fb9d 100644 --- a/management/src/main/java/com/upresent/management/entity/MetricsData.java +++ b/management/src/main/java/com/upresent/management/entity/ReportsData.java @@ -3,7 +3,7 @@ import lombok.Data; @Data -public class MetricsData { +public class ReportsData { private String eventType; private String eventData; diff --git a/management/src/main/java/com/upresent/management/entity/SchoolData.java b/management/src/main/java/com/upresent/management/entity/SchoolData.java new file mode 100644 index 000000000..3d9364047 --- /dev/null +++ b/management/src/main/java/com/upresent/management/entity/SchoolData.java @@ -0,0 +1,23 @@ +package com.upresent.management.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.LastModifiedDate; + +import java.util.Date; +import java.util.List; + +@Data +public class SchoolData { + @Id + private String schoolCode; + private String schoolName; + private List holidays; + private String timeZone; + private GeoFenceData geoFenceData; + private String createdBy; + @JsonIgnore + @LastModifiedDate + private Date updatedOn; +} diff --git a/management/src/main/java/com/upresent/management/exception/ExceptionResponseCode.java b/management/src/main/java/com/upresent/management/exception/ExceptionResponseCode.java index 994ca3456..b1b8439fa 100644 --- a/management/src/main/java/com/upresent/management/exception/ExceptionResponseCode.java +++ b/management/src/main/java/com/upresent/management/exception/ExceptionResponseCode.java @@ -12,11 +12,12 @@ public enum ExceptionResponseCode { UPLOADING_FILE_FAILED(4013, "Your request could not be served by the system. Please try again."), DATA_NOT_FOUND(4014, "Required data not found."), UNKNOWN_USER_TYPE_FOUND(4015, "'Unknown' type user found in request."), - MODULE_ALREADY_EXISTS(4016, "Module already exists."), - MODULE_DOES_NOT_EXIST(4017, "Module doesn't exist."), - USER_TYPES_NOT_FOUND(4018, "User types could not be fetched."), - ALL_USERS_NOT_STUDENTS(4019, "Check the provided users. Either users do not exist or they do not have correct permissions."); - + MODULE_ALREADY_EXISTS(4016, "Module already exists"), + MODULE_DOES_NOT_EXIST(4017, "Module does not exist"), + USER_TYPES_NOT_FOUND(4018, "User types could not be fetched"), + ALL_USERS_NOT_STUDENTS(4019, "Check the provided users. Either users do not exist or they do not have correct permissions."), + SCHOOL_ALREADY_EXISTS(4020, "School already exists"), + SCHOOL_DOES_NOT_EXIST(4021, "School does not exist"); private int code; private String description; diff --git a/management/src/main/java/com/upresent/management/exception/RestExceptionHandler.java b/management/src/main/java/com/upresent/management/exception/RestExceptionHandler.java index 94d5d38f6..24bed4f7d 100644 --- a/management/src/main/java/com/upresent/management/exception/RestExceptionHandler.java +++ b/management/src/main/java/com/upresent/management/exception/RestExceptionHandler.java @@ -26,7 +26,7 @@ protected ResponseEntity handleUnknownException(Exception ex, WebRequest requ } @ExceptionHandler(value = {ManagementException.class}) - protected ResponseEntity handleknownException(ManagementException ex, WebRequest request) { + protected ResponseEntity handleKnownException(ManagementException ex, WebRequest request) { if(!CommonUtility.isNullObject(ex.getResponseCode())){ log.error("Custom Exception:: Error Code :: {} Custom Exception:: Error Description {}",ex.getResponseCode().getCode(), ex.getResponseCode().getDescription()); }else{ diff --git a/management/src/main/java/com/upresent/management/producer/RestMessageProducer.java b/management/src/main/java/com/upresent/management/producer/RestMessageProducer.java index 60626de05..c04fc408c 100644 --- a/management/src/main/java/com/upresent/management/producer/RestMessageProducer.java +++ b/management/src/main/java/com/upresent/management/producer/RestMessageProducer.java @@ -13,7 +13,7 @@ import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; -import com.upresent.management.entity.MetricsData; +import com.upresent.management.entity.ReportsData; import com.upresent.management.exception.ExceptionResponseCode; import com.upresent.management.exception.ManagementException; @@ -27,25 +27,25 @@ public class RestMessageProducer { private RestTemplate restTemplate; public String send(String message) { - String url = env.getProperty("metrics.publisher.api"); + String url = env.getProperty("reporting.publisher.api"); HttpHeaders headers = new HttpHeaders(); headers.set("Accept", MediaType.APPLICATION_JSON_VALUE); - HttpEntity entity = new HttpEntity<>(constructMetricsData(message), headers); + HttpEntity entity = new HttpEntity<>(constructReportingData(message), headers); ResponseEntity response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class); return response.getBody(); } - private MetricsData constructMetricsData(String eventString) { + private ReportsData constructReportingData(String eventString) { try { List eventList = Arrays.asList(eventString.split(";")); - MetricsData metricsData = new MetricsData(); - metricsData.setEventType(eventList.get(1)); - metricsData.setEventData(eventList.get(0)); - metricsData.setSourceId(eventList.get(4)); - metricsData.setTimeStamp(eventList.get(2)); - return metricsData; + ReportsData reportsData = new ReportsData(); + reportsData.setEventType(eventList.get(1)); + reportsData.setEventData(eventList.get(0)); + reportsData.setSourceId(eventList.get(4)); + reportsData.setTimeStamp(eventList.get(2)); + return reportsData; } catch (Exception e) { throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); } diff --git a/management/src/main/java/com/upresent/management/repository/GeoFenceRepository.java b/management/src/main/java/com/upresent/management/repository/GeoFenceRepository.java deleted file mode 100644 index 6999c609b..000000000 --- a/management/src/main/java/com/upresent/management/repository/GeoFenceRepository.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.upresent.management.repository; - -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.stereotype.Repository; - -import com.upresent.management.entity.GeoFenceData; - -import java.util.List; - -@Repository -public interface GeoFenceRepository extends MongoRepository { - - GeoFenceData findByUniversityName(String universityName); - - List findAll(); -} \ No newline at end of file diff --git a/management/src/main/java/com/upresent/management/repository/SchoolRepository.java b/management/src/main/java/com/upresent/management/repository/SchoolRepository.java new file mode 100644 index 000000000..52db2f366 --- /dev/null +++ b/management/src/main/java/com/upresent/management/repository/SchoolRepository.java @@ -0,0 +1,12 @@ +package com.upresent.management.repository; + +import com.upresent.management.entity.SchoolData; +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface SchoolRepository extends MongoRepository { + public Optional findById(String schoolCode); +} diff --git a/management/src/main/java/com/upresent/management/requestdto/GeoFenceReq.java b/management/src/main/java/com/upresent/management/requestdto/GeoFenceReq.java deleted file mode 100644 index 70a96822d..000000000 --- a/management/src/main/java/com/upresent/management/requestdto/GeoFenceReq.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.upresent.management.requestdto; - -import com.upresent.management.utils.Constant; - -import lombok.Data; - -@Data -public class GeoFenceReq { - - public String username; - public String universityName = Constant.UNIVERSITY_NAME; - public Float latitude; - public Float longitude; - public Float radiusInMeter; - -} diff --git a/management/src/main/java/com/upresent/management/service/AdminModuleService.java b/management/src/main/java/com/upresent/management/service/AdminModuleService.java index 364319fac..559837856 100644 --- a/management/src/main/java/com/upresent/management/service/AdminModuleService.java +++ b/management/src/main/java/com/upresent/management/service/AdminModuleService.java @@ -6,7 +6,9 @@ import com.upresent.management.entity.ModuleData; import com.upresent.management.exception.ManagementException; +import org.springframework.stereotype.Service; +@Service public interface AdminModuleService { String createModule(ModuleData moduleData) throws ManagementException; @@ -17,5 +19,5 @@ public interface AdminModuleService { ModuleData getModule(String moduleCode) throws ManagementException; - List getAllModules() throws ManagementException; + List getAllModules(); } \ No newline at end of file diff --git a/management/src/main/java/com/upresent/management/service/AdminModuleServiceImpl.java b/management/src/main/java/com/upresent/management/service/AdminModuleServiceImpl.java index 0a8073c04..1886e843f 100644 --- a/management/src/main/java/com/upresent/management/service/AdminModuleServiceImpl.java +++ b/management/src/main/java/com/upresent/management/service/AdminModuleServiceImpl.java @@ -13,17 +13,18 @@ import com.google.gson.Gson; import com.upresent.management.entity.ModuleData; +import com.upresent.management.entity.SchoolData; import com.upresent.management.exception.ExceptionResponseCode; import com.upresent.management.exception.ManagementException; import com.upresent.management.producer.KafkaMessageProducer; import com.upresent.management.producer.RestMessageProducer; import com.upresent.management.repository.ModuleRepository; +import com.upresent.management.repository.SchoolRepository; import com.upresent.management.utils.CommonUtility; import com.upresent.management.utils.Constant; import com.upresent.management.utils.UserModuleUtil; @Service -@SuppressWarnings("unchecked") public class AdminModuleServiceImpl implements AdminModuleService { @Autowired @@ -35,6 +36,9 @@ public class AdminModuleServiceImpl implements AdminModuleService { @Autowired private ModuleRepository moduleRepository; + @Autowired + private SchoolRepository schoolRepository; + @Autowired UserModuleUtil userModuleUtil; @@ -50,10 +54,15 @@ public String createModule(ModuleData moduleData) throws ManagementException { if (optionalExistingModule.isPresent()) { throw new ManagementException(ExceptionResponseCode.MODULE_ALREADY_EXISTS); } else { + Optional optionalExistingSchool = schoolRepository.findById(moduleData.getSchoolCode()); + if(!optionalExistingSchool.isPresent()) { + throw new ManagementException((ExceptionResponseCode.DATA_NOT_FOUND)); + } int idealNumberOfStudents = moduleData.getStudentUsernames().size(); if (idealNumberOfStudents > 0) { Map userTypes = userModuleUtil .getUserTypesFromUsernames(moduleData.getStudentUsernames()); + //noinspection unchecked List students = (List) userTypes.get("student"); if (students.size() != idealNumberOfStudents) { throw new ManagementException(ExceptionResponseCode.ALL_USERS_NOT_STUDENTS); @@ -77,6 +86,7 @@ public String updateModule(ModuleData moduleData) throws ManagementException { if (idealNumberOfStudents > 0) { Map userTypes = userModuleUtil .getUserTypesFromUsernames(moduleData.getStudentUsernames()); + //noinspection unchecked List students = (List) userTypes.get("student"); if (students.size() != idealNumberOfStudents) { throw new ManagementException(ExceptionResponseCode.ALL_USERS_NOT_STUDENTS); @@ -103,7 +113,7 @@ public ModuleData getModule(String moduleCode) throws ManagementException { } @Override - public List getAllModules() throws ManagementException { + public List getAllModules() { return moduleRepository.findAll(); } diff --git a/management/src/main/java/com/upresent/management/service/GeoFenceService.java b/management/src/main/java/com/upresent/management/service/GeoFenceService.java deleted file mode 100644 index d519bb74f..000000000 --- a/management/src/main/java/com/upresent/management/service/GeoFenceService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.upresent.management.service; - -import com.upresent.management.entity.GeoFenceData; -import com.upresent.management.exception.ManagementException; -import com.upresent.management.requestdto.GeoFenceReq; - -public interface GeoFenceService { - - String addGeoFence(GeoFenceReq geoFence) throws ManagementException; - - GeoFenceData fetchGeoFence(String universityName) throws ManagementException; - - Iterable fetchAllGeoFences() throws ManagementException; -} \ No newline at end of file diff --git a/management/src/main/java/com/upresent/management/service/GeoFenceServiceImpl.java b/management/src/main/java/com/upresent/management/service/GeoFenceServiceImpl.java deleted file mode 100644 index 64453ff12..000000000 --- a/management/src/main/java/com/upresent/management/service/GeoFenceServiceImpl.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.upresent.management.service; - -import java.util.Calendar; - -import org.springframework.beans.BeanUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.core.env.Environment; -import org.springframework.stereotype.Service; - -import com.google.gson.Gson; -import com.upresent.management.entity.GeoFenceData; -import com.upresent.management.exception.ExceptionResponseCode; -import com.upresent.management.exception.ManagementException; -import com.upresent.management.producer.KafkaMessageProducer; -import com.upresent.management.producer.RestMessageProducer; -import com.upresent.management.repository.GeoFenceRepository; -import com.upresent.management.requestdto.GeoFenceReq; -import com.upresent.management.utils.CommonUtility; -import com.upresent.management.utils.Constant; -import com.upresent.management.utils.UserModuleUtil; - -@Service -public class GeoFenceServiceImpl implements GeoFenceService { - - @Autowired - private KafkaMessageProducer kafkaMessageProducer; - - @Autowired - private RestMessageProducer restMessageProducer; - - @Autowired - private GeoFenceRepository geoFenceRepository; - - @Autowired - Environment env; - - Gson gson = new Gson(); - - @Autowired - UserModuleUtil userModuleUtil; - - @Override - public String addGeoFence(GeoFenceReq geoFenceReq) throws ManagementException { - if (userModuleUtil.isAdmin(geoFenceReq.getUsername())) { - if (!(CommonUtility.isValidLatitude(geoFenceReq.getLatitude()) - && CommonUtility.isValidLongitude(geoFenceReq.getLongitude()) - && geoFenceReq.getRadiusInMeter() > 0)) { - throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); - } - GeoFenceData geoFenceInfo; - GeoFenceData existingRecord = geoFenceRepository.findByUniversityName(geoFenceReq.getUniversityName()); - if (existingRecord != null) { - geoFenceInfo = existingRecord; - } else { - geoFenceInfo = new GeoFenceData(); - } - BeanUtils.copyProperties(geoFenceReq, geoFenceInfo); - GeoFenceData geoFenceObj = geoFenceRepository.save(geoFenceInfo); - publishGeoUpdates(geoFenceObj, Constant.GEO_FENCE_CREATED_OR_UPDATED_EVENT); - } else { - throw new ManagementException(ExceptionResponseCode.UNAUTHORISED); - } - return "Geo details have been successfully saved."; - } - - @Override - public GeoFenceData fetchGeoFence(String universityName) throws ManagementException { - GeoFenceData geoFenceInfo; - GeoFenceData existingRecord = geoFenceRepository.findByUniversityName(universityName); - if (existingRecord != null) { - geoFenceInfo = existingRecord; - } else { - throw new ManagementException(ExceptionResponseCode.DATA_NOT_FOUND); - } - return geoFenceInfo; - } - - @Override - public Iterable fetchAllGeoFences() { - return geoFenceRepository.findAll(); - } - - private void publishGeoUpdates(GeoFenceData geo, String eventType) { - String message = CommonUtility.stringifyEventForPublish(gson.toJson(geo), eventType, - Calendar.getInstance().getTime().toString(), "", Constant.MANAGEMENT_SOURCE_ID); - String useMessagePublisher = System.getenv(Constant.SAGA_ENABLED_ENV_VARIABLE) == null - ? env.getProperty(Constant.SAGA_ENABLED_ENV_VARIABLE) - : System.getenv(Constant.SAGA_ENABLED_ENV_VARIABLE); - if (null == useMessagePublisher || 1 == Integer.parseInt(useMessagePublisher)) { - kafkaMessageProducer.send(message); - } else { - restMessageProducer.send(message); - } - } - -} \ No newline at end of file diff --git a/management/src/main/java/com/upresent/management/service/SchoolService.java b/management/src/main/java/com/upresent/management/service/SchoolService.java new file mode 100644 index 000000000..d8ff3b8ab --- /dev/null +++ b/management/src/main/java/com/upresent/management/service/SchoolService.java @@ -0,0 +1,24 @@ +package com.upresent.management.service; + +import com.upresent.management.entity.GeoFenceData; +import com.upresent.management.entity.SchoolData; +import com.upresent.management.exception.ManagementException; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +@Service +public interface SchoolService { + String createSchool(SchoolData schoolData) throws ManagementException; + + String updateSchool(SchoolData schoolData) throws ManagementException; + + String deleteSchool(HttpServletRequest request, String schoolCode) throws ManagementException; + + SchoolData getSchool(String schoolCode) throws ManagementException; + + List getAllSchools() throws ManagementException; + + GeoFenceData fetchGeoFence(String schoolCode) throws ManagementException; +} diff --git a/management/src/main/java/com/upresent/management/service/SchoolServiceImpl.java b/management/src/main/java/com/upresent/management/service/SchoolServiceImpl.java new file mode 100644 index 000000000..27675bb74 --- /dev/null +++ b/management/src/main/java/com/upresent/management/service/SchoolServiceImpl.java @@ -0,0 +1,148 @@ +package com.upresent.management.service; + +import com.google.gson.Gson; +import com.upresent.management.entity.GeoFenceData; +import com.upresent.management.entity.SchoolData; +import com.upresent.management.exception.ExceptionResponseCode; +import com.upresent.management.exception.ManagementException; +import com.upresent.management.producer.KafkaMessageProducer; +import com.upresent.management.producer.RestMessageProducer; +import com.upresent.management.repository.SchoolRepository; +import com.upresent.management.utils.CommonUtility; +import com.upresent.management.utils.Constant; +import com.upresent.management.utils.UserModuleUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import java.util.Calendar; +import java.util.List; +import java.util.Optional; + +@Service +public class SchoolServiceImpl implements SchoolService { + + @Autowired + private KafkaMessageProducer kafkaMessageProducer; + + @Autowired + private RestMessageProducer restMessageProducer; + + @Autowired + private SchoolRepository schoolRepository; + + @Autowired + UserModuleUtil userModuleUtil; + + @Autowired + Environment env; + + Gson gson = new Gson(); + + @Override + public String createSchool(SchoolData schoolData) throws ManagementException { + if (userModuleUtil.isAdmin(schoolData.getCreatedBy())) { + Optional optionalExistingSchool = schoolRepository.findById(schoolData.getSchoolCode()); + if (optionalExistingSchool.isPresent()) { + throw new ManagementException(ExceptionResponseCode.SCHOOL_ALREADY_EXISTS); + } else { + if (!(CommonUtility.isValidLatitude(schoolData.getGeoFenceData().getLatitude()) + && CommonUtility.isValidLongitude(schoolData.getGeoFenceData().getLongitude()) + && schoolData.getGeoFenceData().getRadiusInMeter() > 0)) { + throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); + } + if(!(CommonUtility.isValidTimeZone(schoolData.getTimeZone()))) { + throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); + } + SchoolData school = schoolRepository.save(schoolData); + publishAdminSchoolUpdates(school, Constant.SCHOOL_CREATED_EVENT); + } + } else { + throw new ManagementException(ExceptionResponseCode.UNAUTHORISED); + } + return "A new school has been successfully created."; + } + + @Override + public String updateSchool(SchoolData schoolData) throws ManagementException { + if (userModuleUtil.isAdmin(schoolData.getCreatedBy())) { + Optional optionalExistingSchool = schoolRepository.findById(schoolData.getSchoolCode()); + if (optionalExistingSchool.isPresent()) { + if (!(CommonUtility.isValidLatitude(schoolData.getGeoFenceData().getLatitude()) + && CommonUtility.isValidLongitude(schoolData.getGeoFenceData().getLongitude()) + && schoolData.getGeoFenceData().getRadiusInMeter() > 0)) { + throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); + } + if(!(CommonUtility.isValidTimeZone(schoolData.getTimeZone()))) { + throw new ManagementException(ExceptionResponseCode.INVALID_REQUEST); + } + SchoolData school = schoolRepository.save(schoolData); + publishAdminSchoolUpdates(school, Constant.SCHOOL_UPDATED_EVENT); + } else { + throw new ManagementException(ExceptionResponseCode.SCHOOL_DOES_NOT_EXIST); + } + } else { + throw new ManagementException(ExceptionResponseCode.UNAUTHORISED); + } + return "School has been successfully updated."; + } + + @Override + public String deleteSchool(HttpServletRequest request, String schoolCode) throws ManagementException { + String username = request.getHeader("Username"); + if (username == null) { + throw new ManagementException(ExceptionResponseCode.MISSING_HEADER_KEY); + } + if (userModuleUtil.isAdmin(username)) { + Optional optionalSchoolInfo = schoolRepository.findById(schoolCode); + if (optionalSchoolInfo.isPresent()) { + schoolRepository.deleteById(schoolCode); + publishAdminSchoolUpdates(optionalSchoolInfo.get(), Constant.SCHOOL_DELETED_EVENT); + return "School successfully deleted."; + } else { + throw new ManagementException(ExceptionResponseCode.SCHOOL_DOES_NOT_EXIST); + } + } else { + throw new ManagementException(ExceptionResponseCode.UNAUTHORISED); + } + } + + @Override + public SchoolData getSchool(String schoolCode) throws ManagementException { + Optional optionalSchoolData = schoolRepository.findById(schoolCode); + if (optionalSchoolData.isPresent()) { + return optionalSchoolData.get(); + } + throw new ManagementException(ExceptionResponseCode.SCHOOL_DOES_NOT_EXIST); + } + + @Override + public List getAllSchools() throws ManagementException { + return schoolRepository.findAll(); + } + + @Override + public GeoFenceData fetchGeoFence(String schoolCode) throws ManagementException { + Optional optionalSchoolData = schoolRepository.findById(schoolCode); + if(optionalSchoolData.isPresent()) { + return optionalSchoolData.get().getGeoFenceData(); + } else { + throw new ManagementException(ExceptionResponseCode.DATA_NOT_FOUND); + } + } + + private void publishAdminSchoolUpdates(SchoolData school, String eventType) { + String message = CommonUtility.stringifyEventForPublish(gson.toJson(school), eventType, + Calendar.getInstance().getTime().toString(), "", Constant.MANAGEMENT_SOURCE_ID); + String useMessagePublisher = System.getenv(Constant.SAGA_ENABLED_ENV_VARIABLE) == null + ? env.getProperty(Constant.SAGA_ENABLED_ENV_VARIABLE) + : System.getenv(Constant.SAGA_ENABLED_ENV_VARIABLE); + if (null == useMessagePublisher || 1 == Integer.parseInt(useMessagePublisher)) { + kafkaMessageProducer.send(message); + } else { + restMessageProducer.send(message); + } + } + +} diff --git a/management/src/main/java/com/upresent/management/utils/CommonUtility.java b/management/src/main/java/com/upresent/management/utils/CommonUtility.java index fcfc15d23..3db9b26c9 100644 --- a/management/src/main/java/com/upresent/management/utils/CommonUtility.java +++ b/management/src/main/java/com/upresent/management/utils/CommonUtility.java @@ -1,8 +1,6 @@ package com.upresent.management.utils; -import java.util.Collection; -import java.util.List; -import java.util.Map; +import java.util.*; public class CommonUtility { @@ -57,6 +55,16 @@ public static boolean isValidLatitude(Float latitude) { public static boolean isValidLongitude(Float longitude) { return (longitude >= -180 && longitude <= 180); } + + public static boolean isValidTimeZone(String timezone) { + String[] validIDs = TimeZone.getAvailableIDs(); + for (String str : validIDs) { + if (str != null && str.equals(timezone)) { + return true; + } + } + return false; + } public static String stringifyEventForPublish(String param1, String param2, String param3, String param4, String param5) { StringBuilder builder = new StringBuilder(); diff --git a/management/src/main/java/com/upresent/management/utils/Constant.java b/management/src/main/java/com/upresent/management/utils/Constant.java index 43432bb86..7230abc19 100644 --- a/management/src/main/java/com/upresent/management/utils/Constant.java +++ b/management/src/main/java/com/upresent/management/utils/Constant.java @@ -6,14 +6,12 @@ public interface Constant { String MANAGEMENT_PUBLISHER_TOPIC = "management.publisher.topic"; String KAFKA_BOOTSTRAP_ADDRESS = "kafka.bootstrap.address"; String MANAGEMENT_SOURCE_ID = "2"; - String USER_CREATED_EVENT = "userCreated"; - String USER_UPDATED_EVENT = "userUpdated"; - String USER_DELETED_EVENT = "userDeleted"; - String GEO_FENCE_CREATED_OR_UPDATED_EVENT = "geoFenceCreatedOrUpdated"; + String SCHOOL_CREATED_EVENT = "schoolCreated"; + String SCHOOL_UPDATED_EVENT = "schoolUpdated"; + String SCHOOL_DELETED_EVENT = "schoolDeleted"; String MODULE_CREATED_EVENT = "moduleCreated"; String MODULE_UPDATED_EVENT = "moduleUpdated"; String MODULE_DELETED_EVENT = "moduleDeleted"; - String UNIVERSITY_NAME = "NUS"; String FETCH_USER_API_URL = "/user?username="; String FETCH_USER_TYPES_API_URL = "/user/get-type"; String USER_MS_HOSTNAME_ENV_VARIABLE = "userms.hostname"; diff --git a/management/src/main/resources/application.properties b/management/src/main/resources/application.properties index 98f71bde7..c599a1344 100644 --- a/management/src/main/resources/application.properties +++ b/management/src/main/resources/application.properties @@ -1,11 +1,12 @@ +#spring.data.mongodb.uri=mongodb://root:example@localhost:27017/admin spring.data.mongodb.uri=mongodb://root:example@mongo:27017/admin -#spring.data.mongodb.uri=mongodb://localhost:27017/admin management.publisher.topic=managementEvents +#kafka.bootstrap.address=localhost:9092 kafka.bootstrap.address=broker:29092 sagaEnabled=1 -metrics.publisher.api=http://metrics/metrics -userms.hostname=http://user -userms.port=8080 +#reporting.publisher.api=http://localhost:8083/reporting +reporting.publisher.api=http://reporting:8080/reporting #userms.hostname=http://localhost -#userms.port=8083 -#server.port=8081 \ No newline at end of file +userms.hostname=http://user +#userms.port=8084 +userms.port=8080 \ No newline at end of file diff --git a/scripts/dev/docker-compose.yml b/scripts/dev/docker-compose.yml index 5827ffb27..497c7bd55 100644 --- a/scripts/dev/docker-compose.yml +++ b/scripts/dev/docker-compose.yml @@ -30,6 +30,7 @@ services: - apm-server - broker - mongo + - reporting - user reporting: image: rajagupt/reporting:latest @@ -104,8 +105,8 @@ services: image: mongo:latest container_name: mongo restart: always - # ports: - # - "27017:27017" + ports: + - "27017:27017" volumes: - mongo-data-vol:/data/db environment: