From ad5f4212997c699374850a1ff57ef094119e1f31 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:14:46 +0800 Subject: [PATCH 01/10] Add the files of the REST API project --- .../restapi/DemoRestApplication.java | 39 +++++++++++ .../controller/DepartmentController.java | 64 +++++++++++++++++++ .../restapi/controller/HelloControllor.java | 17 +++++ .../mentoring/restapi/modal/Department.java | 58 +++++++++++++++++ .../repository/DepartmentRepository.java | 13 ++++ .../restapi/web/AuthorizationManager.java | 57 +++++++++++++++++ .../restapi/web/RestApiControlAdvice.java | 50 +++++++++++++++ .../mentoring/restapi/web/SecurityFilter.java | 56 ++++++++++++++++ .../web/exception/BadRequestError.java | 16 +++++ .../restapi/web/exception/HttpException.java | 28 ++++++++ .../web/exception/InternalServerError.java | 17 +++++ .../web/exception/UnauthorizedError.java | 16 +++++ 12 files changed, 431 insertions(+) create mode 100644 src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java create mode 100644 src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java create mode 100644 src/main/java/com/epam/mentoring/restapi/controller/HelloControllor.java create mode 100644 src/main/java/com/epam/mentoring/restapi/modal/Department.java create mode 100644 src/main/java/com/epam/mentoring/restapi/repository/DepartmentRepository.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/AuthorizationManager.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/RestApiControlAdvice.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/SecurityFilter.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/exception/BadRequestError.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/exception/HttpException.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/exception/InternalServerError.java create mode 100644 src/main/java/com/epam/mentoring/restapi/web/exception/UnauthorizedError.java diff --git a/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java b/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java new file mode 100644 index 0000000..50f59f2 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java @@ -0,0 +1,39 @@ +package com.epam.mentoring.restapi; + +import com.epam.mentoring.restapi.modal.Department; +import com.epam.mentoring.restapi.repository.DepartmentRepository; +import com.epam.mentoring.restapi.web.SecurityFilter; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.embedded.FilterRegistrationBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; + +@SpringBootApplication +public class DemoRestApplication { + + public static void main(String[] args) { + SpringApplication springApplication = new SpringApplication(); + ApplicationContext ctx = + SpringApplication.run(DemoRestApplication.class, args); + initDB(ctx); + } + + private static void initDB(ApplicationContext ctx){ + DepartmentRepository deptRepository= (DepartmentRepository) ctx.getBean(DepartmentRepository.class); + deptRepository.save(new Department("HR", "Human Resource")); + deptRepository.save(new Department("DEV", "Development")); + } + + + @Bean + public FilterRegistrationBean filterRegistrationBean() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean(); + SecurityFilter securityFilter = new SecurityFilter(); + registrationBean.setFilter(securityFilter); + registrationBean.addUrlPatterns("/api/*"); + + return registrationBean; + } + +} diff --git a/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java b/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java new file mode 100644 index 0000000..9eefa86 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java @@ -0,0 +1,64 @@ +package com.epam.mentoring.restapi.controller; + +import com.epam.mentoring.restapi.modal.Department; +import com.epam.mentoring.restapi.repository.DepartmentRepository; +import com.epam.mentoring.restapi.web.exception.BadRequestError; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * Created with IntelliJ IDEA. + * User: Francis + * Date: 12-5-13 + * Time: 上午8:42 + * To change this template use File | Settings | File Templates. + */ +@RestController +@RequestMapping(value = "/api/") +public class DepartmentController { + private static org.apache.log4j.Logger LOG= org.apache.log4j.Logger.getLogger(DepartmentController.class); + @Autowired + private DepartmentRepository repository; + + @RequestMapping(method= RequestMethod.GET, value= "/departments") + public @ResponseBody List getDepartments(){ + List list= repository.findAll(); + + return list; + } + + ////produces = {"application/json","application/xml"}) + @RequestMapping(method= RequestMethod.GET, value= "/departments/{id}", headers="Accept=application/json") + public @ResponseBody + Department getDepartment(@PathVariable long id){ + Department department= repository.findOne(id); + + return department; + } + + @RequestMapping(method= RequestMethod.POST, value= "/departments", headers="Accept=application/json") + public @ResponseBody Long save(@RequestBody Department s){ + LOG.info("creating Department: "+ s.getName()); + //validate(s, false); + repository.save(s); + return s.getId(); + } + + @RequestMapping(method= RequestMethod.PUT, value= "/departments/{id}", headers="Accept=application/json") +public @ResponseBody void update(@RequestBody Department s, @PathVariable long id){ + LOG.info("update Department: "+ id+ ","+ s.getName()); + if(s.getId()!= id) + throw new BadRequestError("id is not match"); + repository.save(s); + } + + @RequestMapping(method= RequestMethod.DELETE, value= "/departments/{id}", headers="Accept=application/json") + public @ResponseBody void delete(@PathVariable long id){ + LOG.info("delUser: "+ id); + repository.delete(id); + } + + +} diff --git a/src/main/java/com/epam/mentoring/restapi/controller/HelloControllor.java b/src/main/java/com/epam/mentoring/restapi/controller/HelloControllor.java new file mode 100644 index 0000000..510055e --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/controller/HelloControllor.java @@ -0,0 +1,17 @@ +package com.epam.mentoring.restapi.controller; + +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * Created by pengfrancis on 16/5/19. + */ +@RestController +public class HelloControllor { + + @RequestMapping(value = "hello/{name}") + public String hello(@PathVariable String name){ + return "hello, "+ name; + } +} diff --git a/src/main/java/com/epam/mentoring/restapi/modal/Department.java b/src/main/java/com/epam/mentoring/restapi/modal/Department.java new file mode 100644 index 0000000..5ebdfc0 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/modal/Department.java @@ -0,0 +1,58 @@ +package com.epam.mentoring.restapi.modal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; + +/** + * Created by pengfrancis on 16/5/15. + */ +@Entity +public class Department { + @Id + @GeneratedValue + private Long id; + @Column(name="name") + private String name; + @Column(name="description") + private String description; + + public Department() { + + } + public Department(String name, String description) { + this.name = name; + this.description = description; + } + + public Department(Long id, String name) { + this.id = id; + this.name = name; + } + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/src/main/java/com/epam/mentoring/restapi/repository/DepartmentRepository.java b/src/main/java/com/epam/mentoring/restapi/repository/DepartmentRepository.java new file mode 100644 index 0000000..87947f0 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/repository/DepartmentRepository.java @@ -0,0 +1,13 @@ +package com.epam.mentoring.restapi.repository; + +import com.epam.mentoring.restapi.modal.Department; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +/** + * Created by pengfrancis on 16/5/15. + */ +@Repository +public interface DepartmentRepository extends JpaRepository { + +} diff --git a/src/main/java/com/epam/mentoring/restapi/web/AuthorizationManager.java b/src/main/java/com/epam/mentoring/restapi/web/AuthorizationManager.java new file mode 100644 index 0000000..87e492e --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/AuthorizationManager.java @@ -0,0 +1,57 @@ +package com.epam.mentoring.restapi.web; + +import java.time.LocalDateTime; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * Created by pengfrancis on 16/5/18. + */ +public class AuthorizationManager { + /** + * map of token -> UserToken + */ + public static Map tokenMap= new ConcurrentHashMap<> (); + /** + * map of Role -> UserToken + */ + public static Map accessControlMap= new ConcurrentHashMap<> (); + + public static boolean authorize(String uri, String method, String token){ + if(token== null) + return false; + //todo check ACL + //1.return true if uri is public + + //2. check if token is valid + UserToken userToken= tokenMap.get(token); + //todo + + //3. check role has AccessControl + + + //4. further check, e.g. realm + + /*String[] uriParts = uri.split("[#?]"); + String path = uriParts[0]; + String rest = uri.substring(uriParts[0].length()); */ + + return true; + } +} + +class UserToken{ + public long id; + public String name; + public String role; + public long inChargeDepartmentId; + public LocalDateTime expireTime; +} + + +class AccessControl{ + public String role; + public String resource; + public String operation; + public boolean limitedRealm; +} \ No newline at end of file diff --git a/src/main/java/com/epam/mentoring/restapi/web/RestApiControlAdvice.java b/src/main/java/com/epam/mentoring/restapi/web/RestApiControlAdvice.java new file mode 100644 index 0000000..04805bc --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/RestApiControlAdvice.java @@ -0,0 +1,50 @@ +package com.epam.mentoring.restapi.web; + +import com.epam.mentoring.restapi.web.exception.BadRequestError; +import com.epam.mentoring.restapi.web.exception.InternalServerError; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; + +/** + * Created by pengfrancis on 16/5/15. + */ + +@ControllerAdvice +public class RestApiControlAdvice { + + @ExceptionHandler(value=RuntimeException.class) + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public String handle(RuntimeException e) { + return "INTERNAL_SERVER_ERROR"; + } + + @ExceptionHandler(value=Exception.class) + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public String handle(Exception e) { + //log it + return "INTERNAL_SERVER_ERROR"; + + } + + @ExceptionHandler(value=InternalServerError.class) + @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) + @ResponseBody + public String handle(InternalServerError e) { + return e.getMessage()== null ? "INTERNAL_SERVER_ERROR" : "INTERNAL_SERVER_ERROR: "+ e.getMessage(); + } + + + @ExceptionHandler(value=BadRequestError.class) + @ResponseStatus(value = HttpStatus.BAD_REQUEST) + @ResponseBody + public String handle(BadRequestError e) { + return e.getMessage()== null ? "BAD_REQUEST" : "BAD_REQUEST: "+ e.getMessage(); + } + + +} diff --git a/src/main/java/com/epam/mentoring/restapi/web/SecurityFilter.java b/src/main/java/com/epam/mentoring/restapi/web/SecurityFilter.java new file mode 100644 index 0000000..6d9adce --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/SecurityFilter.java @@ -0,0 +1,56 @@ +package com.epam.mentoring.restapi.web; + +import org.springframework.http.HttpStatus; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Map; + +/** + * Created by pengfrancis on 16/5/18. + */ + +//@WebFilter(filterName="myFilter",urlPatterns="/api/*") +public class SecurityFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + + System.out.println("Filtering........"); + String token= null; + Map params= servletRequest.getParameterMap(); + try{ + token= ((String[])params.get("token"))[0]; + }catch (Exception e){ + token= null; + } + HttpServletRequest request= (HttpServletRequest) servletRequest; + String uri = request.getRequestURI(); + System.out.println("Authenticate: "+ request.getMethod()+" "+ uri + ", token="+ token); + + boolean authorizatePass= (token!=null && token.startsWith("a")); + // AuthorizationManager.authorize(uri, request.getMethod(), token) + + if(!authorizatePass){ + //throw new UnauthorizedError(); + HttpServletResponse httpResponse = (HttpServletResponse) servletResponse; + //httpResponse.sendRedirect("/login.jsp"); + httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value()); + httpResponse.getWriter().print(HttpStatus.UNAUTHORIZED.getReasonPhrase()); + return; + } + + filterChain.doFilter(servletRequest, servletResponse); + } + + @Override + public void destroy() { + + } +} diff --git a/src/main/java/com/epam/mentoring/restapi/web/exception/BadRequestError.java b/src/main/java/com/epam/mentoring/restapi/web/exception/BadRequestError.java new file mode 100644 index 0000000..49572fd --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/exception/BadRequestError.java @@ -0,0 +1,16 @@ +package com.epam.mentoring.restapi.web.exception; + +import org.springframework.http.HttpStatus; + +/** + * Created by pengfrancis on 16/5/18. + */ +public class BadRequestError extends HttpException { + + public BadRequestError() { + super(HttpStatus.BAD_REQUEST); + } + public BadRequestError(String message) { + super(HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/com/epam/mentoring/restapi/web/exception/HttpException.java b/src/main/java/com/epam/mentoring/restapi/web/exception/HttpException.java new file mode 100644 index 0000000..51185b4 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/exception/HttpException.java @@ -0,0 +1,28 @@ +package com.epam.mentoring.restapi.web.exception; + +import org.springframework.http.HttpStatus; + +/** + * Created by pengfrancis on 16/5/18. + */ +public abstract class HttpException extends RuntimeException{ + private HttpStatus httpStatus; + private String message; + + public HttpException(HttpStatus httpStatus){ + this.httpStatus= httpStatus; + //if(httpStatus!=null) + + } + public HttpException(HttpStatus httpStatus, String message){ + this.httpStatus= httpStatus; + this.message= message; + + } + public HttpStatus getStatusCode(){ + return httpStatus; + } + public String getMessage(){ + return message; + } +} diff --git a/src/main/java/com/epam/mentoring/restapi/web/exception/InternalServerError.java b/src/main/java/com/epam/mentoring/restapi/web/exception/InternalServerError.java new file mode 100644 index 0000000..5e8935f --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/exception/InternalServerError.java @@ -0,0 +1,17 @@ +package com.epam.mentoring.restapi.web.exception; + +import org.springframework.http.HttpStatus; + +/** + * Created by pengfrancis on 16/5/18. + */ +public class InternalServerError extends HttpException { + + public InternalServerError() { + super(HttpStatus.INTERNAL_SERVER_ERROR); + } + public InternalServerError(String message) { + super(HttpStatus.INTERNAL_SERVER_ERROR, message); + } +} + diff --git a/src/main/java/com/epam/mentoring/restapi/web/exception/UnauthorizedError.java b/src/main/java/com/epam/mentoring/restapi/web/exception/UnauthorizedError.java new file mode 100644 index 0000000..e48344f --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/web/exception/UnauthorizedError.java @@ -0,0 +1,16 @@ +package com.epam.mentoring.restapi.web.exception; + +import org.springframework.http.HttpStatus; + +/** + * Created by pengfrancis on 16/5/18. + */ +public class UnauthorizedError extends HttpException { + + public UnauthorizedError() { + super(HttpStatus.UNAUTHORIZED); + } + public UnauthorizedError(String message) { + super(HttpStatus.UNAUTHORIZED, message); + } +} From 8a5ad45382b82d00566ccdfd99aa3b291a28f35e Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:16:26 +0800 Subject: [PATCH 02/10] Replace the Maven config for the REST API --- pom.xml | 82 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/pom.xml b/pom.xml index 904b2df..22e8dd1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,54 +4,70 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.epam - java-mentoring-program + EPAM + RESTPractice 1.0-SNAPSHOT - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - + + demoRest + Practice project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.3.5.RELEASE + + + + + UTF-8 + 1.8 + + - com.fasterxml.jackson.core - jackson-annotations - 2.4.5 + org.springframework.boot + spring-boot-starter-data-jpa + + + + com.h2database + h2 + runtime - com.fasterxml.jackson.core - jackson-databind - 2.4.5 + org.springframework.boot + spring-boot-starter-test + test - org.apache.commons - commons-csv - 1.2 + org.springframework.boot + spring-boot-starter-web - junit - junit - 4.12 + org.springframework.restdocs + spring-restdocs-mockmvc test + - com.google.guava - guava - 13.0.1 + com.fasterxml.jackson.dataformat + jackson-dataformat-xml - com.google.guava - guava - 13.0.1 + org.springframework + spring-web + 4.2.6.RELEASE + + + + org.springframework.boot + spring-boot-maven-plugin + + + + - \ No newline at end of file + From 627802bfa33c4e3eeeb92c0541e5a70f35e51b12 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:17:43 +0800 Subject: [PATCH 03/10] The only one Spring boot config file From e2ba3ee8db795eebdbce69655afee53acba92142 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:19:11 +0800 Subject: [PATCH 04/10] Unit test files --- .../restapi/DemoRestApplicationTests.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/test/java/com/epam/mentoring/restapi/DemoRestApplicationTests.java diff --git a/src/test/java/com/epam/mentoring/restapi/DemoRestApplicationTests.java b/src/test/java/com/epam/mentoring/restapi/DemoRestApplicationTests.java new file mode 100644 index 0000000..af8f7f7 --- /dev/null +++ b/src/test/java/com/epam/mentoring/restapi/DemoRestApplicationTests.java @@ -0,0 +1,43 @@ +package com.epam.mentoring.restapi; + +import com.epam.mentoring.restapi.controller.HelloControllor; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import static org.hamcrest.Matchers.equalTo; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = DemoRestApplication.class) //MockServletContext +@WebAppConfiguration +public class DemoRestApplicationTests { + + private MockMvc mvc; + + @Before + public void setUp() throws Exception { + mvc = MockMvcBuilders.standaloneSetup(new HelloControllor()).build(); + } + + @Test + public void contextLoads() { + } + + @Test + public void helloTest() throws Exception { + mvc.perform(MockMvcRequestBuilders.get("/hello/abc").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect(content().string(equalTo("hello, abc"))); + } + + +} From 4cbc11af2df2214d070445ebc66d6aa34240add2 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:38:17 +0800 Subject: [PATCH 05/10] Task for implement the service method --- .../controller/EmployeeController.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java diff --git a/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java new file mode 100644 index 0000000..f84ed94 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java @@ -0,0 +1,24 @@ +package com.epam.mentoring.restapi.controller; + +/** + * Created by pengfrancis on 16/5/19. + */ +public class EmployeeController { + //todo add Restful services to getAll + + //todo add Restful services to get + + + //todo add Restful services to getByName + + + //todo add Restful services to create, + + + //todo add Restful services to put, response 404(Not Found) when encounter the exception that the id is not exist + + + //todo add Restful services to delete + + +} From c74d8408887b69b597b5863b1db7abaacc346531 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:39:02 +0800 Subject: [PATCH 06/10] Add files via upload --- .../mentoring/restapi/modal/Employee.java | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 src/main/java/com/epam/mentoring/restapi/modal/Employee.java diff --git a/src/main/java/com/epam/mentoring/restapi/modal/Employee.java b/src/main/java/com/epam/mentoring/restapi/modal/Employee.java new file mode 100644 index 0000000..a2a002f --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/modal/Employee.java @@ -0,0 +1,76 @@ +package com.epam.mentoring.restapi.modal; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import java.time.LocalDate; + +/** + * Created by pengfrancis on 16/5/15. + */ +@Entity +public class Employee { + @Id + @GeneratedValue + private Long id; + @Column + private String name; + @Column + private String code; + @Column + private Long departmentId; + @Column + private LocalDate onBoardDate; + + public Employee(){ + + } + + public Employee(String name, String code, Long departmentId, LocalDate onBoardDate) { + this.name = name; + this.code = code; + this.departmentId = departmentId; + this.onBoardDate = onBoardDate; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public Long getDepartmentId() { + return departmentId; + } + + public void setDepartmentId(Long departmentId) { + this.departmentId = departmentId; + } + + public LocalDate getOnBoardDate() { + return onBoardDate; + } + + public void setOnBoardDate(LocalDate onBoardDate) { + this.onBoardDate = onBoardDate; + } +} From d4a801cd3d60f8bde69e6fdb90700a6972998f51 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:39:36 +0800 Subject: [PATCH 07/10] Add files via upload --- .../restapi/repository/EmployeeRepository.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java diff --git a/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java new file mode 100644 index 0000000..0b2e471 --- /dev/null +++ b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java @@ -0,0 +1,12 @@ +package com.epam.mentoring.restapi.repository; + +import com.epam.mentoring.restapi.modal.Employee; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +/** + * Created by pengfrancis on 16/5/19. + */ +@Repository +public interface EmployeeRepository extends JpaRepository { +} From 4ec2a974a788c3e48bdb65bb21cc9ac9b7630374 Mon Sep 17 00:00:00 2001 From: fpem Date: Thu, 19 May 2016 18:45:44 +0800 Subject: [PATCH 08/10] Added the Hometask 6 description at bottom --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 689dfe2..1bfaaef 100644 --- a/README.md +++ b/README.md @@ -28,3 +28,18 @@ In pull request mark your mentor (@mentorName) so it can review it. To complite task one you need to fix DataProcessorTest unit tests. All methods in DataProcessor with "7" in a name should be implemented using Java 7, when other should be done with Java 8 streaming api. + +## Hometask 6 + +To implement the REST service in EmployeeController for modal class Employee with EmployeeRepository as DAO, service functionalities including: + //todo add Restful services to getAll + + //todo add Restful services to get + + //todo add Restful services to getByName + + //todo add Restful services to create + + //todo add Restful services to put, response 404(Not Found) when encounter the exception that the id is not exist + + //todo add Restful services to delete From 50ab91434626b8a102344e907c7a8dc281ad97bf Mon Sep 17 00:00:00 2001 From: northzzn Date: Tue, 24 May 2016 23:04:45 +0800 Subject: [PATCH 09/10] HW#6 --- .../controller/EmployeeController.java | 62 ++++++++++++++++--- .../repository/EmployeeRepository.java | 11 +++- 2 files changed, 62 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java index f84ed94..679d030 100644 --- a/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java +++ b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java @@ -1,24 +1,66 @@ package com.epam.mentoring.restapi.controller; -/** - * Created by pengfrancis on 16/5/19. - */ -public class EmployeeController { - //todo add Restful services to getAll +import java.util.List; - //todo add Restful services to get +import javax.xml.ws.http.HTTPException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; - //todo add Restful services to getByName +import com.epam.mentoring.restapi.modal.Employee; +import com.epam.mentoring.restapi.repository.EmployeeRepository; +/** + * Created by pengfrancis on 16/5/19. + */ +@RestController +public class EmployeeController { - //todo add Restful services to create, + @Autowired + private EmployeeRepository employeeRepository; + // todo add Restful services to getAll + @RequestMapping(method = RequestMethod.GET, value = "/employee/getall") + public @ResponseBody List getAll() { + return employeeRepository.findAll(); + } - //todo add Restful services to put, response 404(Not Found) when encounter the exception that the id is not exist + // todo add Restful services to get + @RequestMapping(method = RequestMethod.GET, value = "/employee/get/{id}") + public @ResponseBody Employee get(@PathVariable Long id) { + return employeeRepository.findOne(id); + } + // todo add Restful services to getByName + @RequestMapping(method = RequestMethod.GET, value = "/employee/getbyname/{name}") + public @ResponseBody List getByName(@PathVariable String name) { + return employeeRepository.findByName(name); + } - //todo add Restful services to delete + // todo add Restful services to create, + @RequestMapping(method = RequestMethod.POST, value = "/employee/create") + public void create(@RequestBody Employee employee) { + employeeRepository.save(employee); + } + // todo add Restful services to put, response 404(Not Found) when encounter + // the exception that the id is not exist + @RequestMapping(method = RequestMethod.PUT, value = "/employee/put") + public void put(@RequestBody Employee employee) { + if (employeeRepository.findOne(employee.getId()) == null) { + throw new HTTPException(404); + } + employeeRepository.save(employee); + } + // todo add Restful services to delete + @RequestMapping(method = RequestMethod.POST, value = "/employee/delete/{id}") + public void delete(@PathVariable Long id) { + employeeRepository.delete(id); + } } diff --git a/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java index 0b2e471..745c175 100644 --- a/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java +++ b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java @@ -1,12 +1,21 @@ package com.epam.mentoring.restapi.repository; -import com.epam.mentoring.restapi.modal.Employee; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; +import com.epam.mentoring.restapi.modal.Employee; + /** * Created by pengfrancis on 16/5/19. */ @Repository public interface EmployeeRepository extends JpaRepository { + + @Query(value = "SELECT * FROM Employee WHERE name := name") + List findByName(@Param("name") String name); + } From f00810472e6a4acdf69115da94bf6fdc7ec0fc36 Mon Sep 17 00:00:00 2001 From: northzzn Date: Wed, 25 May 2016 21:08:10 +0800 Subject: [PATCH 10/10] hw#6 --- pom.xml | 26 +++++++--- .../restapi/DemoRestApplication.java | 24 +++++---- .../controller/DepartmentController.java | 51 +++++++++++-------- .../controller/EmployeeController.java | 23 +++++---- .../repository/EmployeeRepository.java | 2 +- 5 files changed, 79 insertions(+), 47 deletions(-) diff --git a/pom.xml b/pom.xml index 22e8dd1..b40be36 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,11 @@ org.springframework.boot spring-boot-starter-data-jpa - + + org.springframework.boot + spring-boot-devtools + true + com.h2database h2 @@ -43,6 +47,16 @@ org.springframework.boot spring-boot-starter-web + + org.apache.commons + commons-csv + 1.2 + + + com.google.guava + guava + 13.0.1 + org.springframework.restdocs spring-restdocs-mockmvc @@ -53,11 +67,11 @@ com.fasterxml.jackson.dataformat jackson-dataformat-xml - - org.springframework - spring-web - 4.2.6.RELEASE - + + + + + diff --git a/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java b/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java index 50f59f2..349e90f 100644 --- a/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java +++ b/src/main/java/com/epam/mentoring/restapi/DemoRestApplication.java @@ -1,7 +1,9 @@ package com.epam.mentoring.restapi; import com.epam.mentoring.restapi.modal.Department; +import com.epam.mentoring.restapi.modal.Employee; import com.epam.mentoring.restapi.repository.DepartmentRepository; +import com.epam.mentoring.restapi.repository.EmployeeRepository; import com.epam.mentoring.restapi.web.SecurityFilter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -23,17 +25,21 @@ private static void initDB(ApplicationContext ctx){ DepartmentRepository deptRepository= (DepartmentRepository) ctx.getBean(DepartmentRepository.class); deptRepository.save(new Department("HR", "Human Resource")); deptRepository.save(new Department("DEV", "Development")); - } - - @Bean - public FilterRegistrationBean filterRegistrationBean() { - FilterRegistrationBean registrationBean = new FilterRegistrationBean(); - SecurityFilter securityFilter = new SecurityFilter(); - registrationBean.setFilter(securityFilter); - registrationBean.addUrlPatterns("/api/*"); - return registrationBean; + EmployeeRepository employeeRepository = (EmployeeRepository) ctx.getBean(EmployeeRepository.class); + employeeRepository.save(new Employee("name", "code", 1L, null)); } +// +// @Bean +// public FilterRegistrationBean filterRegistrationBean() { +// FilterRegistrationBean registrationBean = new FilterRegistrationBean(); +// SecurityFilter securityFilter = new SecurityFilter(); +// registrationBean.setFilter(securityFilter); +// registrationBean.addUrlPatterns("/api/*"); +// +// return registrationBean; +// } + } diff --git a/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java b/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java index 9eefa86..b786bcd 100644 --- a/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java +++ b/src/main/java/com/epam/mentoring/restapi/controller/DepartmentController.java @@ -18,45 +18,52 @@ @RestController @RequestMapping(value = "/api/") public class DepartmentController { - private static org.apache.log4j.Logger LOG= org.apache.log4j.Logger.getLogger(DepartmentController.class); + private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(DepartmentController.class); @Autowired private DepartmentRepository repository; - @RequestMapping(method= RequestMethod.GET, value= "/departments") - public @ResponseBody List getDepartments(){ - List list= repository.findAll(); - + @RequestMapping(method = RequestMethod.GET, value = "/departments") + public + @ResponseBody + List getDepartments() { + List list = repository.findAll(); return list; } - ////produces = {"application/json","application/xml"}) - @RequestMapping(method= RequestMethod.GET, value= "/departments/{id}", headers="Accept=application/json") - public @ResponseBody - Department getDepartment(@PathVariable long id){ - Department department= repository.findOne(id); - + @RequestMapping(method = RequestMethod.GET, value = "/departments/{id}") + public + @ResponseBody + Department getDepartment(@PathVariable long id) { + Department department = repository.findOne(id); return department; } - @RequestMapping(method= RequestMethod.POST, value= "/departments", headers="Accept=application/json") - public @ResponseBody Long save(@RequestBody Department s){ - LOG.info("creating Department: "+ s.getName()); - //validate(s, false); + + @RequestMapping(method = RequestMethod.POST, value = "/departments") + public + @ResponseBody + Long save(@RequestBody Department s) { + LOG.info("creating Department: " + s.getName()); + //validate(s, false); repository.save(s); return s.getId(); } - @RequestMapping(method= RequestMethod.PUT, value= "/departments/{id}", headers="Accept=application/json") -public @ResponseBody void update(@RequestBody Department s, @PathVariable long id){ - LOG.info("update Department: "+ id+ ","+ s.getName()); - if(s.getId()!= id) + @RequestMapping(method = RequestMethod.PUT, value = "/departments/{id}") + public + @ResponseBody + void update(@RequestBody Department s, @PathVariable long id) { + LOG.info("update Department: " + id + "," + s.getName()); + if (s.getId() != id) throw new BadRequestError("id is not match"); repository.save(s); } - @RequestMapping(method= RequestMethod.DELETE, value= "/departments/{id}", headers="Accept=application/json") - public @ResponseBody void delete(@PathVariable long id){ - LOG.info("delUser: "+ id); + @RequestMapping(method = RequestMethod.DELETE, value = "/departments/{id}") + public + @ResponseBody + void delete(@PathVariable long id) { + LOG.info("delUser: " + id); repository.delete(id); } diff --git a/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java index 679d030..a3a7fd7 100644 --- a/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java +++ b/src/main/java/com/epam/mentoring/restapi/controller/EmployeeController.java @@ -1,10 +1,13 @@ package com.epam.mentoring.restapi.controller; +import java.util.ArrayList; import java.util.List; import javax.xml.ws.http.HTTPException; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -19,47 +22,49 @@ * Created by pengfrancis on 16/5/19. */ @RestController +@RequestMapping(value = "/api/employee") public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; // todo add Restful services to getAll - @RequestMapping(method = RequestMethod.GET, value = "/employee/getall") + @RequestMapping(method = RequestMethod.GET, value = "") public @ResponseBody List getAll() { return employeeRepository.findAll(); } // todo add Restful services to get - @RequestMapping(method = RequestMethod.GET, value = "/employee/get/{id}") + @RequestMapping(method = RequestMethod.GET, value = "/{id}") public @ResponseBody Employee get(@PathVariable Long id) { return employeeRepository.findOne(id); } // todo add Restful services to getByName - @RequestMapping(method = RequestMethod.GET, value = "/employee/getbyname/{name}") + @RequestMapping(method = RequestMethod.GET, value = "/name/{name}") public @ResponseBody List getByName(@PathVariable String name) { - return employeeRepository.findByName(name); + return employeeRepository.findByName(name); } // todo add Restful services to create, - @RequestMapping(method = RequestMethod.POST, value = "/employee/create") + @RequestMapping(method = RequestMethod.POST, value = "/create") public void create(@RequestBody Employee employee) { employeeRepository.save(employee); } // todo add Restful services to put, response 404(Not Found) when encounter // the exception that the id is not exist - @RequestMapping(method = RequestMethod.PUT, value = "/employee/put") - public void put(@RequestBody Employee employee) { + @RequestMapping(method = RequestMethod.PUT, value = "/put") + public ResponseEntity put(@RequestBody Employee employee) { if (employeeRepository.findOne(employee.getId()) == null) { - throw new HTTPException(404); + return new ResponseEntity(HttpStatus.NOT_FOUND); } employeeRepository.save(employee); + return new ResponseEntity(HttpStatus.OK); } // todo add Restful services to delete - @RequestMapping(method = RequestMethod.POST, value = "/employee/delete/{id}") + @RequestMapping(method = RequestMethod.POST, value = "/delete/{id}") public void delete(@PathVariable Long id) { employeeRepository.delete(id); } diff --git a/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java index 745c175..772cd08 100644 --- a/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java +++ b/src/main/java/com/epam/mentoring/restapi/repository/EmployeeRepository.java @@ -15,7 +15,7 @@ @Repository public interface EmployeeRepository extends JpaRepository { - @Query(value = "SELECT * FROM Employee WHERE name := name") + @Query(value = "SELECT e FROM Employee e WHERE e.name = ?1") List findByName(@Param("name") String name); }