diff --git a/pom.xml b/pom.xml
index 0f927f0..cb1cee9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,11 @@
org.springframework.boot
spring-boot-starter-data-mongodb
+
+ com.bol
+ spring-data-mongodb-encrypt
+ 2.2
+
org.springframework.boot
spring-boot-starter-data-redis
diff --git a/src/main/java/com/vinodh/config/MongoConfig.java b/src/main/java/com/vinodh/config/MongoConfig.java
new file mode 100644
index 0000000..ba04560
--- /dev/null
+++ b/src/main/java/com/vinodh/config/MongoConfig.java
@@ -0,0 +1,86 @@
+package com.vinodh.config;
+
+import com.bol.crypt.CryptVault;
+import com.bol.secure.CachedEncryptionEventListener;
+import com.bol.secure.ReflectionEncryptionEventListener;
+import com.mongodb.MongoClient;
+import com.mongodb.MongoClientURI;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
+import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
+import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
+import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
+
+import java.util.Base64;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 22:00
+ */
+@Configuration
+@EnableMongoRepositories(basePackages = "com.vinodh.repository")
+@PropertySource("classpath:application.yml")
+public class MongoConfig extends AbstractMongoConfiguration {
+
+ // normally you would use @Value to wire a property here
+ private static final byte[] secretKey = Base64.getDecoder().decode("hqHKBLV83LpCqzKpf8OvutbCs+O5wX5BPu3btWpEvXA=");
+ private static final byte[] oldKey = Base64.getDecoder().decode("cUzurmCcL+K252XDJhhWI/A/+wxYXLgIm678bwsE2QM=");
+
+// @Value("${spring.data.mongodb.secretKey}")
+// private String secretKey;
+//
+// @Value("${spring.data.mongodb.oldKey}")
+// private String oldKey;
+
+ @Value("${spring.data.mongodb.database}")
+ private String database;
+
+ @Value("${spring.data.mongodb.uri}")
+ private String uri;
+
+ @Override
+ public MongoClient mongoClient() {
+ return new MongoClient(new MongoClientURI(uri));
+ }
+
+ @Override
+ @Bean
+ public MappingMongoConverter mappingMongoConverter() throws Exception {
+ MappingMongoConverter converter = super.mappingMongoConverter();
+ // NB: without overriding defaultMongoTypeMapper, an _class field is put in every document
+ // since we know exactly which java class a specific document maps to, this is surplus
+ converter.setTypeMapper(new DefaultMongoTypeMapper(null));
+ return converter;
+ }
+
+ @Override
+ protected String getDatabaseName() {
+ return database;
+ }
+
+ @Bean
+ public CryptVault cryptVault() {
+ return new CryptVault()
+ .with256BitAesCbcPkcs5PaddingAnd128BitSaltKey(0, oldKey)
+ .with256BitAesCbcPkcs5PaddingAnd128BitSaltKey(1, secretKey)
+ // can be omitted if it's the highest version
+ .withDefaultKeyVersion(1);
+ }
+
+ @Bean
+ @Primary
+ public ReflectionEncryptionEventListener encryptionEventListener(CryptVault cryptVault) {
+ return new ReflectionEncryptionEventListener(cryptVault);
+ }
+
+// @Bean
+// public MongoEncryptionListener encryptionEventListener() {
+// return new MongoEncryptionListener();
+// }
+
+
+}
diff --git a/src/main/java/com/vinodh/config/MongoEncryptionListener.java b/src/main/java/com/vinodh/config/MongoEncryptionListener.java
new file mode 100644
index 0000000..7e1996f
--- /dev/null
+++ b/src/main/java/com/vinodh/config/MongoEncryptionListener.java
@@ -0,0 +1,76 @@
+//package com.vinodh.config;
+//
+//import com.bol.crypt.CryptVault;
+//import com.bol.crypt.FieldCryptException;
+//import com.bol.secure.AbstractEncryptionEventListener;
+//import com.bol.secure.Encrypted;
+//import org.bson.Document;
+//import org.springframework.data.mongodb.core.mapping.event.AfterConvertEvent;
+//import org.springframework.data.mongodb.core.mapping.event.BeforeConvertEvent;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.ReflectionUtils;
+//
+//import java.lang.reflect.Field;
+//import java.util.Map;
+//
+///**
+// * @author thimmv
+// * @createdAt 23-06-2019 22:40
+// */
+////@Component
+//public class MongoEncryptionListener extends AbstractEncryptionEventListener {
+//
+// public MongoEncryptionListener(CryptVault cryptVault) {
+// super(cryptVault);
+// }
+//
+// @Override
+// public void onBeforeConvert(BeforeConvertEvent event) {
+// Class extends String> targetClass = event.getCollectionName().getClass();
+// Document targetDocument = event.getDocument();
+// for (Map.Entry fieldsMap : targetDocument.entrySet()) {
+// String fieldName = fieldsMap.getKey();
+// if (fieldName.equals("_class")) continue;
+// Field field = ReflectionUtils.findField(targetClass, fieldName);
+// field.setAccessible(true);
+// if (field == null) continue;
+//
+// Object fieldValue = fieldsMap.getValue();
+// if (field.isAnnotationPresent(Encrypted.class)) {
+// // direct encryption
+// try {
+// targetDocument.put(fieldName, cryptVault.encrypt(fieldValue.toString().getBytes()));
+// } catch (Exception e) {
+// throw new FieldCryptException(fieldName, e);
+// }
+//
+// }
+// field.setAccessible(true);
+// }
+// }
+//
+// @Override
+// public void onAfterConvert(AfterConvertEvent event) {
+// Class extends String> targetClass = event.getCollectionName().getClass();
+// Document targetDocument = event.getDocument();
+// for (Map.Entry fieldsMap : targetDocument.entrySet()) {
+// String fieldName = fieldsMap.getKey();
+// if (fieldName.equals("_class")) continue;
+// Field field = ReflectionUtils.findField(targetClass, fieldName);
+// field.setAccessible(true);
+// if (field == null) continue;
+//
+// Object fieldValue = fieldsMap.getValue();
+// if (field.isAnnotationPresent(Encrypted.class)) {
+// // direct encryption
+// try {
+// targetDocument.put(fieldName, cryptVault.decrypt(fieldValue.toString().getBytes()));
+// } catch (Exception e) {
+// throw new FieldCryptException(fieldName, e);
+// }
+//
+// }
+// field.setAccessible(true);
+// }
+// }
+//}
diff --git a/src/main/java/com/vinodh/controller/MovieController.java b/src/main/java/com/vinodh/controller/MovieController.java
new file mode 100644
index 0000000..35eea95
--- /dev/null
+++ b/src/main/java/com/vinodh/controller/MovieController.java
@@ -0,0 +1,87 @@
+package com.vinodh.controller;
+
+import com.bol.crypt.CryptVault;
+import com.vinodh.documents.Movie;
+import com.vinodh.service.MovieService;
+import com.vinodh.service.NextSequenceService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+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.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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:41
+ */
+@RestController
+@RequestMapping("/movie")
+@Api(value = "Set of endpoints for Creating, Retrieving, Updating and Deleting of Movie information.")
+@Slf4j
+public class MovieController {
+
+
+ @Autowired
+ private MovieService movieService;
+
+ @Autowired
+ private CryptVault cryptVault;
+
+ @Autowired
+ private NextSequenceService nextSequenceService;
+
+ @GetMapping("/findAll")
+ @ApiOperation(value = "Find All available movies")
+ public ResponseEntity> getAllMovies() {
+ return ResponseEntity.ok(movieService.findAll());
+ }
+
+ @GetMapping("/findById")
+ @ApiOperation(value = "Find Movie based on ID")
+ public ResponseEntity findById(@ApiParam(value = "Find Movie based on ID.", required = true) @RequestParam Long id) {
+ return ResponseEntity.ok(movieService.findById(id));
+ }
+
+ @GetMapping("/findByTitle")
+ @ApiOperation(value = "Find Movie based on NAME")
+ public ResponseEntity> findByTitle(@ApiParam(value = "Find Movie based on Name.", required = true) @RequestParam String title) {
+ return ResponseEntity.ok(movieService.findByTitle(title));
+ }
+
+ @PostMapping("/save")
+ @ApiOperation(value = "Save new Movie details")
+ public ResponseEntity save(@ApiParam(value = "Movie information to be created.", required = true) @RequestBody Movie movie) {
+ if (movie.getId() == null) movie.setId(nextSequenceService.getNextSequence());
+ return ResponseEntity.ok(movieService.save(movie));
+ }
+
+ @PutMapping("/update")
+ @ApiOperation(value = "Update Movie details")
+ public ResponseEntity update(@ApiParam(value = "Movie information to be updated.", required = true) @RequestBody Movie movie) {
+ return ResponseEntity.ok(movieService.update(movie));
+ }
+
+ @DeleteMapping("/delete")
+ @ApiOperation(value = "Delete Movie details")
+ public void deleteUserByID(@ApiParam(value = "Delete Movie based on ID.", required = true) @RequestParam Long id) {
+ movieService.deleteById(id);
+ }
+
+ @DeleteMapping("/deleteAll")
+ @ApiOperation(value = "Delete All Movie details")
+ public void deleteAll() {
+ movieService.deleteAll();
+ }
+
+}
diff --git a/src/main/java/com/vinodh/documents/CustomSequences.java b/src/main/java/com/vinodh/documents/CustomSequences.java
new file mode 100644
index 0000000..d95127c
--- /dev/null
+++ b/src/main/java/com/vinodh/documents/CustomSequences.java
@@ -0,0 +1,17 @@
+package com.vinodh.documents;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+@NoArgsConstructor
+@Setter
+@Getter
+@Document(collection = "customSequences")
+public class CustomSequences {
+ @Id
+ private String id;
+ private Long seq;
+}
\ No newline at end of file
diff --git a/src/main/java/com/vinodh/documents/ImdbRating.java b/src/main/java/com/vinodh/documents/ImdbRating.java
new file mode 100644
index 0000000..9b54a98
--- /dev/null
+++ b/src/main/java/com/vinodh/documents/ImdbRating.java
@@ -0,0 +1,18 @@
+package com.vinodh.documents;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:49
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class ImdbRating {
+ private Long id;
+ private double rating;
+ private long votes;
+}
diff --git a/src/main/java/com/vinodh/documents/Movie.java b/src/main/java/com/vinodh/documents/Movie.java
new file mode 100644
index 0000000..e6938df
--- /dev/null
+++ b/src/main/java/com/vinodh/documents/Movie.java
@@ -0,0 +1,44 @@
+package com.vinodh.documents;
+
+import com.bol.secure.Encrypted;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import org.springframework.data.annotation.Id;
+import org.springframework.data.mongodb.core.mapping.Document;
+
+import java.time.LocalDateTime;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:42
+ */
+@Document("movies")
+@NoArgsConstructor
+@Setter
+@Getter
+public class Movie {
+
+ @Id
+ private Long id;
+
+ @Encrypted
+ private String title;
+
+ private int year, runtime;
+
+ private LocalDateTime released;
+
+ @Encrypted
+ private String poster, plot;
+
+ private Set cast = new HashSet<>();
+ private Set directors = new HashSet<>();
+ private Set countries = new HashSet<>();
+ private Set genres = new HashSet<>();
+
+ private ImdbRating imdb;
+
+}
diff --git a/src/main/java/com/vinodh/repository/MovieRepository.java b/src/main/java/com/vinodh/repository/MovieRepository.java
new file mode 100644
index 0000000..91e9661
--- /dev/null
+++ b/src/main/java/com/vinodh/repository/MovieRepository.java
@@ -0,0 +1,17 @@
+package com.vinodh.repository;
+
+import com.vinodh.documents.Movie;
+import org.springframework.data.mongodb.repository.MongoRepository;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:43
+ */
+@Repository
+public interface MovieRepository extends MongoRepository {
+ List findByTitle(String name);
+
+}
diff --git a/src/main/java/com/vinodh/service/EmployeeServiceImpl.java b/src/main/java/com/vinodh/service/EmployeeServiceImpl.java
index c0d0fc2..eb69435 100644
--- a/src/main/java/com/vinodh/service/EmployeeServiceImpl.java
+++ b/src/main/java/com/vinodh/service/EmployeeServiceImpl.java
@@ -47,6 +47,7 @@ public List findByName(String name) {
}
@Override
+ @CachePut(value = "Employee_Cache", key = "#employee.id")
public Employee save(Employee employee) {
return employeeRepository.save(employee);
}
diff --git a/src/main/java/com/vinodh/service/MovieService.java b/src/main/java/com/vinodh/service/MovieService.java
new file mode 100644
index 0000000..15a4060
--- /dev/null
+++ b/src/main/java/com/vinodh/service/MovieService.java
@@ -0,0 +1,26 @@
+package com.vinodh.service;
+
+import com.vinodh.documents.Movie;
+
+import java.util.List;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:42
+ */
+public interface MovieService {
+
+ List findAll();
+
+ Movie findById(Long id);
+
+ List findByTitle(String name);
+
+ Movie save(Movie movie);
+
+ Movie update(Movie movie);
+
+ void deleteById(Long id);
+
+ void deleteAll();
+}
diff --git a/src/main/java/com/vinodh/service/MovieServiceImpl.java b/src/main/java/com/vinodh/service/MovieServiceImpl.java
new file mode 100644
index 0000000..cc2b932
--- /dev/null
+++ b/src/main/java/com/vinodh/service/MovieServiceImpl.java
@@ -0,0 +1,81 @@
+package com.vinodh.service;
+
+import com.bol.crypt.CryptVault;
+import com.vinodh.documents.Movie;
+import com.vinodh.repository.MovieRepository;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.annotation.CacheEvict;
+import org.springframework.cache.annotation.CachePut;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+
+/**
+ * @author thimmv
+ * @createdAt 23-06-2019 15:43
+ */
+@Service
+@Slf4j
+public class MovieServiceImpl implements MovieService {
+
+ @Autowired
+ private MovieRepository movieRepository;
+
+ @Autowired
+ private MongoTemplate mongoTemplate;
+
+ @Autowired
+ private CryptVault cryptVault;
+
+ @Override
+ public List findAll() {
+ return movieRepository.findAll();
+ }
+
+ @Override
+ @Cacheable(value = "Movie_Cache", key = "#id")
+ public Movie findById(Long id) {
+ return movieRepository.findById(id).get();
+ }
+
+ @Override
+ @CachePut(value = "Movie_Cache", key = "#title")
+ public List findByTitle(String title) {
+ byte[] encrypt = cryptVault.encrypt(title.getBytes());
+ List movies = mongoTemplate.find(query(where("title : " + encrypt)), Movie.class);
+ return movieRepository.findByTitle(title);
+ }
+
+ @Override
+ @CachePut(value = "Movie_Cache", key = "#movie.id")
+ public Movie save(Movie movie) {
+ return movieRepository.save(movie);
+ }
+
+ @Override
+ @CachePut(value = "Movie_Cache", key = "#movie.id")
+ public Movie update(Movie movie) {
+ return movieRepository.save(movie);
+ }
+
+ @Override
+ @CacheEvict(value = "Movie_Cache", key = "#movie.id")
+ public void deleteById(Long id) {
+ movieRepository.deleteById(id);
+ }
+
+ @Override
+ @CacheEvict(value = "Movie_Cache", allEntries = false)
+ public void deleteAll() {
+ movieRepository.deleteAll();
+ }
+}
diff --git a/src/main/java/com/vinodh/service/NextSequenceService.java b/src/main/java/com/vinodh/service/NextSequenceService.java
new file mode 100644
index 0000000..ff6c985
--- /dev/null
+++ b/src/main/java/com/vinodh/service/NextSequenceService.java
@@ -0,0 +1,27 @@
+package com.vinodh.service;
+
+import com.vinodh.documents.CustomSequences;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoOperations;
+import org.springframework.data.mongodb.core.query.Update;
+import org.springframework.stereotype.Service;
+
+import static org.springframework.data.mongodb.core.query.Criteria.where;
+import static org.springframework.data.mongodb.core.query.Query.query;
+import static org.springframework.data.mongodb.core.FindAndModifyOptions.options;
+
+@Service
+public class NextSequenceService {
+
+ @Autowired
+ private MongoOperations mongoOperations;
+
+ public long getNextSequence() {
+ CustomSequences counter = mongoOperations.findAndModify(
+ query(where("_id").is("customSequences")),
+ new Update().inc("seq", 1),
+ options().returnNew(true).upsert(true),
+ CustomSequences.class);
+ return counter.getSeq();
+ }
+}
\ No newline at end of file