diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..83853db
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..63e9001
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..4b661a5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index c5786a0..09660ce 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,21 @@
+# Global Line Network Test
+Test for Global Line Network
+
+## 1. Technologies Used
+- Java 8
+- IntelliJ
+- Maven
+- SpringBoot
+- Spring Data JPA
+- h2database
+- SpringBootTest
+
+## 2. Implementation details
+- Implemented services to perfor curd operation for user
+- Can be deployed and run through springboot
+- Test is added to verify service
+
+## 3. Instalation and Testing
+- It is Maven project with spring boot all libs can be added thorugh maven and project can run throgh spring boot
+- Service can be called at http://localhost:8080/
-
-
-
-
-
-Thanks for taking the time to do our front-end / full-stack practical coding challenge.
-
-The objective of this challenge is to evaluate your domain knowledge in front-end / full-stack development: code organization, style and best practices.
-
-# Overview:
-The main challenge will be to build a simple user management tool that will perform basic CRUD operations on a user. Please use mockups as a reference
-about look of the application. There are no business rules & guidelines other than to show us what you’re truly made of. It can be as simple or as complex as you want it to be.
-
-### Prerequisites
-There are none :) Our main solutions stack include but not limited to Kotlin, Java, AngularJS, Flutter, Spring...
-Feel free to use any languages and technologies you are comfortable with.
-
-## Mockups
-
-
-
-
-
-
-### Front-end:
-- For API please use https://reqres.in/.
-
-### Back-end:
-- The API should be similar to https://reqres.in/, performing basic operations for user.
-
-_We'll be happy if you cover application with tests._
-
-### Submission Guidelines
-- Please fork the repo and then submit a Pull Request when you are done.
-- Instructions must be provided to run the application, install any dependencies, and any other information needed.
-- Please use version control and make sure we can see the history of how you went about it, rather than just uploading the complete project to GitHub.
-
-## Questions? ###
-Please feel free to reach out and ask any questions while you are working on a solution.
-Send your questions to [tech@chimaera.my](mailto:tech@chimaera.my).
-
-
-Good luck!
-
-
-
-
-
diff --git a/coding-challenge.iml b/coding-challenge.iml
new file mode 100644
index 0000000..78b2cc5
--- /dev/null
+++ b/coding-challenge.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..c3826d8
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,62 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.2.2.RELEASE
+
+
+
+ org.example
+ coding-challenge
+ 1.0-SNAPSHOT
+ codingchallenge
+ codingchallenge
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ com.h2database
+ h2
+ runtime
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/gln/GLNApplication.java b/src/main/java/com/gln/GLNApplication.java
new file mode 100644
index 0000000..4d21cbe
--- /dev/null
+++ b/src/main/java/com/gln/GLNApplication.java
@@ -0,0 +1,13 @@
+package com.gln;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class GLNApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(GLNApplication.class, args);
+ }
+
+}
diff --git a/src/main/java/com/gln/controller/UserController.java b/src/main/java/com/gln/controller/UserController.java
new file mode 100644
index 0000000..684a0d6
--- /dev/null
+++ b/src/main/java/com/gln/controller/UserController.java
@@ -0,0 +1,50 @@
+package com.gln.controller;
+
+import com.gln.entity.User;
+import com.gln.service.UserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Optional;
+
+
+@RestController
+@RequestMapping("/user")
+public class UserController {
+
+ @Autowired
+ UserService userService;
+
+ @PostMapping("/create")
+ public User saveUser(@RequestBody User user) {
+ return userService.save(user);
+ }
+
+ @PutMapping("/update")
+ public User update(@RequestBody User user) {
+ return userService.save(user);
+ }
+
+ @DeleteMapping("/delete")
+ public ResponseEntity delete(@RequestBody User user) {
+ userService.delete(user);
+ return new ResponseEntity<>(HttpStatus.ACCEPTED);
+ }
+
+ @GetMapping("/{id}")
+ public ResponseEntity getUser(@PathVariable Long id) {
+ Optional user = userService.get(id);
+ if (user.equals(Optional.empty()))
+ return new ResponseEntity<>(HttpStatus.NOT_FOUND);
+ else
+ return new ResponseEntity<>(user.get(), HttpStatus.NOT_FOUND);
+ }
+
+ @GetMapping("list")
+ public Page getUserList(@RequestParam Integer pageNo) {
+ return userService.getList(pageNo);
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/gln/entity/User.java b/src/main/java/com/gln/entity/User.java
new file mode 100644
index 0000000..d551156
--- /dev/null
+++ b/src/main/java/com/gln/entity/User.java
@@ -0,0 +1,65 @@
+package com.gln.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+
+@Entity
+public class User {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.AUTO)
+ private Long id;
+ private String email;
+ private String firstName;
+ private String lastName;
+ private String avatar;
+
+ protected User() {
+ }
+
+ public User(String firstName, String lastName, String email, String avatar) {
+ this.firstName = firstName;
+ this.lastName = lastName;
+ this.email = email;
+ this.avatar = avatar;
+ }
+
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public String getAvatar() {
+ return avatar;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public void setFirstName(String firstName) {
+ this.firstName = firstName;
+ }
+
+ public void setLastName(String lastName) {
+ this.lastName = lastName;
+ }
+
+ public void setAvatar(String avatar) {
+ this.avatar = avatar;
+ }
+}
diff --git a/src/main/java/com/gln/repository/UserRepository.java b/src/main/java/com/gln/repository/UserRepository.java
new file mode 100644
index 0000000..a91e509
--- /dev/null
+++ b/src/main/java/com/gln/repository/UserRepository.java
@@ -0,0 +1,8 @@
+package com.gln.repository;
+
+import com.gln.entity.User;
+import org.springframework.data.repository.PagingAndSortingRepository;
+
+public interface UserRepository extends PagingAndSortingRepository {
+
+}
diff --git a/src/main/java/com/gln/service/UserService.java b/src/main/java/com/gln/service/UserService.java
new file mode 100644
index 0000000..9ad4db2
--- /dev/null
+++ b/src/main/java/com/gln/service/UserService.java
@@ -0,0 +1,38 @@
+package com.gln.service;
+
+import com.gln.entity.User;
+import com.gln.repository.UserRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.PageRequest;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+public class UserService {
+ @Autowired
+ UserRepository repository;
+
+ public User save(User user) {
+ return repository.save(user);
+
+ }
+
+ public void delete(User user) {
+ repository.delete(user);
+
+ }
+
+ public Optional get(Long id) {
+ return repository.findById(id);
+
+ }
+
+ public Page getList(int pageNo) {
+ Pageable pageable = PageRequest.of(pageNo, 6);
+ return repository.findAll(pageable);
+
+ }
+}
diff --git a/src/test/java/com/gln/UserTest.java b/src/test/java/com/gln/UserTest.java
new file mode 100644
index 0000000..af245cf
--- /dev/null
+++ b/src/test/java/com/gln/UserTest.java
@@ -0,0 +1,92 @@
+package com.gln;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gln.entity.User;
+import com.gln.service.UserService;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+
+@SpringBootTest(classes = GLNApplication.class)
+@AutoConfigureMockMvc
+public class UserTest {
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private ObjectMapper mapper;
+
+ private User user;
+ private String userJson;
+
+ @BeforeEach
+ public void loadUser() throws Exception {
+ user = new User("first", "last", "abc@emil.com", "www.avatar.com");
+ userJson = mapper.writeValueAsString(user);
+ }
+
+
+ @Test
+ public void createUserTest() throws Exception {
+
+ this.mockMvc.perform(post("/user/create")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(userJson)
+ ).andExpect(status().isOk());
+ }
+
+ @Test
+ public void updateUserTest() throws Exception {
+
+ this.mockMvc.perform(post("/user/create")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(userJson)
+ ).andExpect(status().isOk());
+
+ MvcResult result = this.mockMvc.perform(get("/user/1")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(userJson)).andReturn();
+
+ User updateUser = mapper.readValue(result.getResponse().getContentAsString(), User.class);
+ updateUser.setFirstName("ufirstName");
+ updateUser.setLastName("ulastName");
+
+
+ this.mockMvc.perform(put("/user/update")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(mapper.writeValueAsString(updateUser))
+ ).andExpect(status().isOk()).andExpect(content().json(mapper.writeValueAsString(updateUser)));
+ }
+
+ @Test
+ public void deleteUserTest() throws Exception {
+
+ this.mockMvc.perform(post("/user/create")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(userJson)
+ ).andExpect(status().isOk());
+
+ MvcResult result = this.mockMvc.perform(get("/user/1")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(userJson)).andReturn();
+
+ User deleteUser = mapper.readValue(result.getResponse().getContentAsString(), User.class);
+
+
+ this.mockMvc.perform(delete("/user/delete")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(mapper.writeValueAsString(deleteUser))
+ ).andExpect(status().isAccepted());
+ }
+}