Skip to content
Snippets Groups Projects
Commit f1021f93 authored by jelinjon1's avatar jelinjon1
Browse files

elastic search on Course, search by name, credits, capacity, and teacher id,...

elastic search on Course, search by name, credits, capacity, and teacher id, elastic server has to be running, find port and login in application.properties and in ElasticSearchConfig.java
parent ad3a38c8
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,16 @@
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.16.1</version>
</dependency>
<!-- new-->
<dependency>
<groupId>org.springframework.boot</groupId>
......
package ear.kos2.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.elc.ElasticsearchConfiguration;
@Configuration
public class ElasticSearchConfig extends ElasticsearchConfiguration {
@Override
public ClientConfiguration clientConfiguration() {
return ClientConfiguration.builder()
.connectedTo("localhost:9200")
.usingSsl("f6c3482e8c52691d4f0e0e976f438f4f15e83bd8e2bf6cea6d710ec59483edc0") //add the generated sha-256 fingerprint
.withBasicAuth("elastic", "Tp0-*eCdH2DPeO-jcHwd") //add your username and password
.build();
}
}
package ear.kos2.model;
import jakarta.persistence.*;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import java.util.ArrayList;
import java.util.List;
......@@ -8,6 +11,7 @@ import java.util.stream.Collectors;
@Entity
@Table(name = "course")
@Document(indexName = "course")
public class Course extends AbstractEntity {
@Basic
@Column(name = "name", nullable = false, length = 20)
......@@ -25,7 +29,7 @@ public class Course extends AbstractEntity {
@JoinTable(name = "student_course", joinColumns = @JoinColumn(name = "id_course"), inverseJoinColumns = @JoinColumn(name = "id_student"))
private List<StudentAccount> students;
@Basic
@ElementCollection
@Column(name = "class_ids", nullable = true)
private List<Integer> classIds;
......@@ -68,23 +72,20 @@ public class Course extends AbstractEntity {
this.students = students;
}
// public List<SClass> getClasses() {
// return new ArrayList<>();
// }
public List<Integer> getClasses() {
return classIds;
}
// public void setClasses(List<SClass> classes) {
// this.classes = classes;
// }
public void setClasses(List<Integer> classes) {
this.classIds = classes;
}
@Override
public String toString(){
return "Course{ " + "name=" + name + ", credits=" + credits + ", capacity=" + capacity
+ ", teachers=" + teachers + ", students=" + students.stream().map(AbstractEntity::getId).toList() + ", classes=" + classIds + "}";
public String toString() {
return "Course{" +
"name='" + name + '\'' +
", credits=" + credits +
", capacity=" + capacity +
'}';
}
}
package ear.kos2.repository;
import ear.kos2.model.Course;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CourseRepository extends ElasticsearchRepository<Course, String> {
// Find courses by name
List<Course> findByName(String name);
// Find courses by credits
List<Course> findByCredits(Integer credits);
// Find courses by capacity
List<Course> findByCapacity(Integer capacity);
// Find courses by teacher ID
@Query("{\"nested\": {\"path\": \"teachers\", \"query\": {\"bool\": {\"must\": [{\"match\": {\"teachers.id\": \"?0\"}}]}}}}")
List<Course> findByTeachers_Id(String teacherId);
}
\ No newline at end of file
package ear.kos2.rest;
import ear.kos2.exception.NotFoundException;
import ear.kos2.exception.ValidationException;
import ear.kos2.model.Course;
import ear.kos2.model.StudentAccount;
import ear.kos2.repository.CourseRepository;
import ear.kos2.rest.util.RestUtils;
import ear.kos2.service.CourseService;
import org.slf4j.Logger;
......@@ -13,24 +13,24 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/courses")
//@PreAuthorize("permitAll()")
public class CourseController {
private static final Logger LOG = LoggerFactory.getLogger(CourseController.class);
private final CourseService courseService;
private final CourseRepository courseRepository;
@Autowired
public CourseController(CourseService courseService) {
public CourseController(CourseService courseService, CourseRepository courseRepository) {
this.courseService = courseService;
this.courseRepository = courseRepository;
}
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
......@@ -41,7 +41,9 @@ public class CourseController {
//@PreAuthorize("hasRole('ROLE_TEACHER')")
@PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Void> createCourse(@RequestBody Course course) {
courseService.persist(course);
courseService.persist(course); //normal DB persist
courseRepository.save(course); //elasticsearch repository persist
LOG.debug("Created course {}.", course);
final HttpHeaders headers = RestUtils.createLocationHeaderFromCurrentUri("/{id}", course.getId());
return new ResponseEntity<>(headers, HttpStatus.CREATED);
......@@ -49,23 +51,70 @@ public class CourseController {
@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getCourse(@PathVariable Integer id) {
final Course p = courseService.find(id);
if (p == null) {
throw NotFoundException.create("Course", id);
// non elastic + elastic implementation
try {
final Optional<Course> p = courseRepository.findById(String.valueOf(id));
if(p.isPresent()) {
return ResponseEntity.status(HttpStatus.FOUND).body(p.toString());
} else {
final Course c = courseService.find(id);
if (c == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("A course with that id was not found.");
}
return ResponseEntity.status(HttpStatus.FOUND).body(c.toString());
}
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("Unexpected error during search ocurred.");
}
// return p;
return ResponseEntity.status(HttpStatus.FOUND).body(p.toString());
}
@GetMapping(value = "/search/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Course> getCourse(@PathVariable String name) {
final List<Course> p = courseService.findByName(name);
if (p == null) {
throw NotFoundException.create("Course", name);
// elastic search methods
@GetMapping(value = "/search/name/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Course> searchByName(@PathVariable String name) {
return courseRepository.findByName(name);
}
@GetMapping(value = "/search/credits/{credits}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Course> searchByCredits(@PathVariable Integer credits) {
return courseRepository.findByCredits(credits);
}
@GetMapping(value = "/search/capacity/{capacity}", produces = MediaType.APPLICATION_JSON_VALUE)
public List<Course> searchByCapacity(@PathVariable Integer capacity) {
return courseRepository.findByCapacity(capacity);
}
@GetMapping("/search/teacher/{teacherId}")
public List<Course> getByTeacherId(@PathVariable String teacherId) {
return courseRepository.findByTeachers_Id(teacherId);
}
@PostMapping(value = "/create_test_course", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> insertCourseElastic() {
try {
Course temp = new Course();
temp.setName("new elastic course");
temp.setCredits(4);
temp.setCapacity(40);
courseService.persist(temp);
courseRepository.save(temp);
return ResponseEntity.status(HttpStatus.OK).body("Success");
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Unexpected failure");
}
return p;
}
// pre elastic name search
// @GetMapping(value = "/search/{name}", produces = MediaType.APPLICATION_JSON_VALUE)
// public List<Course> getCourse(@PathVariable String name) {
// final List<Course> p = courseService.findByName(name);
// if (p == null) {
// throw NotFoundException.create("Course", name);
// }
// return p;
// }
//@PreAuthorize("hasRole('ROLE_TEACHER')")
@PutMapping(value = "/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseStatus(HttpStatus.NO_CONTENT)
......
......@@ -31,3 +31,8 @@ spring.jpa.show-sql=true
spring.jpa.properties.hibernate.hbm2ddl.auto=create
spring.jackson.default-property-inclusion=non_null
# elastic sarch config
spring.data.elasticsearch.cluster-name=elasticsearch
spring.data.elasticsearch.cluster-nodes=localhost:9200
spring.data.elasticsearch.repositories.enabled=true
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment