add openhack files
This commit is contained in:
4
apis/user-java/.gitignore
vendored
Normal file
4
apis/user-java/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
target
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
27
apis/user-java/Dockerfile
Normal file
27
apis/user-java/Dockerfile
Normal file
@ -0,0 +1,27 @@
|
||||
# First stage to build the application
|
||||
FROM maven:3.6.3-openjdk-11-slim AS build-env
|
||||
ADD ./pom.xml pom.xml
|
||||
ADD ./src src/
|
||||
RUN mvn clean package
|
||||
|
||||
# build runtime image
|
||||
FROM openjdk:11-jre-slim
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# docker build argument
|
||||
# This can be specified during the docker build step by adding " --build-arg build_version=<value>"
|
||||
# App version can be accessed via the uri path /api/version/user-java
|
||||
# https://vsupalov.com/docker-build-pass-environment-variables/
|
||||
ARG build_version="user-java default"
|
||||
|
||||
ENV SQL_USER="YourUserName" \
|
||||
SQL_PASSWORD="changeme" \
|
||||
SQL_SERVER="changeme.database.windows.net" \
|
||||
SQL_DBNAME="mydrivingDB" \
|
||||
APP_VERSION=$build_version
|
||||
|
||||
# Add the application's jar to the container
|
||||
COPY --from=build-env target/swagger-spring-1.0.0.jar user-java.jar
|
||||
|
||||
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/user-java.jar"]
|
73
apis/user-java/README.md
Normal file
73
apis/user-java/README.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Overview
|
||||
|
||||
This server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project.
|
||||
By using the [OpenAPI-Spec](https://github.com/swagger-api/swagger-core), you can easily generate a server stub.
|
||||
This is an example of building a swagger-enabled server in Java using the SpringBoot framework.
|
||||
|
||||
The underlying library integrating swagger to SpringBoot is [springfox](https://github.com/springfox/springfox)
|
||||
|
||||
Start your server as an simple java application.
|
||||
|
||||
You can view the api documentation in swagger-ui by pointing to
|
||||
[http://localhost:8080/api/swagger-ui.html](http://localhost:8080/api/swagger-ui.html)
|
||||
|
||||
Change default port value in `src/main/resources/application.properties`
|
||||
|
||||
## Build the project
|
||||
|
||||
1. Install Maven [https://maven.apache.org/install.html](https://maven.apache.org/install.html) and setup the environment path accordingly
|
||||
|
||||
2. Go into the project root directory that has the pom.xml and run `mvn package`
|
||||
|
||||
## Run only the unit tests
|
||||
|
||||
`mvn test`
|
||||
|
||||
## Run the application
|
||||
|
||||
1. Modify the `src/main/resources/application.properties` values with valid SQL Server values.
|
||||
|
||||
```java
|
||||
spring.datasource.url=someurl
|
||||
spring.datasource.username=username
|
||||
spring.datasource.password=password
|
||||
```
|
||||
|
||||
1. Start the API: `mvn spring-boot:run`
|
||||
|
||||
### POST API Example
|
||||
|
||||
This curl command creates a new user with ID 1234.
|
||||
|
||||
```bash
|
||||
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
|
||||
"createdAt":"2018-08-07", \
|
||||
"deleted": false, \
|
||||
"firstName": "Hacker", \
|
||||
"fuelConsumption": 0, \
|
||||
"hardAccelerations": 0, \
|
||||
"hardStops": 0, \
|
||||
"id": "1234", \
|
||||
"lastName": "Test", \
|
||||
"maxSpeed": 0, \
|
||||
"profilePictureUri": "https://pbs.twimg.com/profile_images/1003946090146693122/IdMjh-FQ_bigger.jpg", \
|
||||
"ranking": 0, \
|
||||
"rating": 0, \
|
||||
"totalDistance": 0, \
|
||||
"totalTime": 0, \
|
||||
"totalTrips": 0, \
|
||||
"updatedAt": "2018-08-07", \
|
||||
"userId": "Hacker3" \
|
||||
}' 'http://localhost:8080/api/user/1234'
|
||||
```
|
||||
|
||||
### PATCH API Example
|
||||
|
||||
This updates the `fuelConsumption` and `hardStops` fields from the user created above.
|
||||
|
||||
```bash
|
||||
curl -X PATCH --header 'Content-Type: application/json' --header 'Accept: application/json' -d '{ \
|
||||
"fuelConsumption":20, \
|
||||
"hardStops":74371 \
|
||||
}
|
||||
```
|
15
apis/user-java/buildtest.sh
Normal file
15
apis/user-java/buildtest.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
|
||||
# https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
|
||||
|
||||
# clean the output of the previous build
|
||||
mvn clean
|
||||
|
||||
# run unit tests
|
||||
mvn test
|
||||
|
||||
# create distributable package
|
||||
mvn package
|
||||
|
||||
# run integration tests
|
||||
mvn verify
|
115
apis/user-java/pom.xml
Normal file
115
apis/user-java/pom.xml
Normal file
@ -0,0 +1,115 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-spring</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>swagger-spring</name>
|
||||
<version>1.0.0</version>
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<springfox-version>2.9.2</springfox-version>
|
||||
</properties>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.5.9.RELEASE</version>
|
||||
</parent>
|
||||
<build>
|
||||
<sourceDirectory>src/main/java</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>application.properties</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
<!--SpringFox dependencies -->
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger2</artifactId>
|
||||
<version>${springfox-version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.springfox</groupId>
|
||||
<artifactId>springfox-swagger-ui</artifactId>
|
||||
<version>${springfox-version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.joschi.jackson</groupId>
|
||||
<artifactId>jackson-datatype-threetenbp</artifactId>
|
||||
<version>2.6.4</version>
|
||||
</dependency>
|
||||
<!-- Bean Validation API support -->
|
||||
<dependency>
|
||||
<groupId>javax.validation</groupId>
|
||||
<artifactId>validation-api</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- JPA Data (We are going to use Repositories, Entities, Hibernate, etc...) -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.microsoft.sqlserver</groupId>
|
||||
<artifactId>mssql-jdbc</artifactId>
|
||||
<version>8.2.2.jre11</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jayway.jsonpath</groupId>
|
||||
<artifactId>json-path</artifactId>
|
||||
<version>2.2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,22 @@
|
||||
package io.swagger;
|
||||
|
||||
import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
|
||||
import com.fasterxml.jackson.databind.util.ISO8601Utils;
|
||||
|
||||
import java.text.FieldPosition;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
public class RFC3339DateFormat extends ISO8601DateFormat {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// Same as ISO8601DateFormat but serializing milliseconds.
|
||||
@Override
|
||||
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
|
||||
String value = ISO8601Utils.format(date, true);
|
||||
toAppendTo.append(value);
|
||||
return toAppendTo;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package io.swagger;
|
||||
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.ExitCodeGenerator;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
@EntityScan(
|
||||
basePackageClasses = {Swagger2SpringBoot.class, Jsr310JpaConverters.class}
|
||||
)
|
||||
@SpringBootApplication
|
||||
@EnableSwagger2
|
||||
@ComponentScan(basePackages = { "io.swagger", "io.swagger.api" })
|
||||
public class Swagger2SpringBoot implements CommandLineRunner {
|
||||
|
||||
@Override
|
||||
public void run(String... arg0) throws Exception {
|
||||
if (arg0.length > 0 && arg0[0].equals("exitcode")) {
|
||||
throw new ExitException();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new SpringApplication(Swagger2SpringBoot.class).run(args);
|
||||
}
|
||||
|
||||
class ExitException extends RuntimeException implements ExitCodeGenerator {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public int getExitCode() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.swagger.api;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class ApiException extends Exception{
|
||||
private int code;
|
||||
public ApiException (int code, String msg) {
|
||||
super(msg);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package io.swagger.api;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class ApiOriginFilter implements javax.servlet.Filter {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain chain) throws IOException, ServletException {
|
||||
HttpServletResponse res = (HttpServletResponse) response;
|
||||
res.addHeader("Access-Control-Allow-Origin", "*");
|
||||
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
|
||||
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package io.swagger.api;
|
||||
|
||||
import javax.xml.bind.annotation.XmlTransient;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@javax.xml.bind.annotation.XmlRootElement
|
||||
public class ApiResponseMessage {
|
||||
public static final int ERROR = 1;
|
||||
public static final int WARNING = 2;
|
||||
public static final int INFO = 3;
|
||||
public static final int OK = 4;
|
||||
public static final int TOO_BUSY = 5;
|
||||
|
||||
int code;
|
||||
String type;
|
||||
String message;
|
||||
|
||||
public ApiResponseMessage(){}
|
||||
|
||||
public ApiResponseMessage(int code, String message){
|
||||
this.code = code;
|
||||
switch(code){
|
||||
case ERROR:
|
||||
setType("error");
|
||||
break;
|
||||
case WARNING:
|
||||
setType("warning");
|
||||
break;
|
||||
case INFO:
|
||||
setType("info");
|
||||
break;
|
||||
case OK:
|
||||
setType("ok");
|
||||
break;
|
||||
case TOO_BUSY:
|
||||
setType("too busy");
|
||||
break;
|
||||
default:
|
||||
setType("unknown");
|
||||
break;
|
||||
}
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@XmlTransient
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* NOTE: This class is auto generated by the swagger code generator program (2.3.1).
|
||||
* https://github.com/swagger-api/swagger-codegen
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package io.swagger.api;
|
||||
|
||||
import io.swagger.model.ErrorResponseDefault;
|
||||
import io.swagger.model.Healthcheck;
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Api(value = "User Java", description = "User-Java API", tags = { "User Java" })
|
||||
public interface HealthcheckApi {
|
||||
|
||||
@ApiOperation(value = "", nickname = "healthcheckUserGet", notes = "Returns healthcheck for systems looking to ensure API is up and operational", response = Healthcheck.class, tags={ })
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 200, message = "Service is healthy", response = Healthcheck.class),
|
||||
@ApiResponse(code = 200, message = "An error occurred", response = ErrorResponseDefault.class) })
|
||||
@RequestMapping(value = "/healthcheck/user-java",
|
||||
produces = { "application/json" },
|
||||
method = RequestMethod.GET)
|
||||
ResponseEntity<Healthcheck> healthcheckUserGet();
|
||||
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package io.swagger.api;
|
||||
|
||||
import io.swagger.model.Healthcheck;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Controller
|
||||
public class HealthcheckApiController implements HealthcheckApi {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HealthcheckApiController.class);
|
||||
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
public HealthcheckApiController(ObjectMapper objectMapper, HttpServletRequest request) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public ResponseEntity<Healthcheck> healthcheckUserGet() {
|
||||
|
||||
try {
|
||||
return new ResponseEntity<Healthcheck>(objectMapper.readValue("{ \"message\" : \"User-Java Service Healthcheck\", \"status\" : \"healthy\"}", Healthcheck.class), HttpStatus.OK);
|
||||
} catch (IOException e) {
|
||||
log.error("Couldn't serialize response for content type application/json", e);
|
||||
return new ResponseEntity<Healthcheck>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.swagger.api;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class NotFoundException extends ApiException {
|
||||
private int code;
|
||||
public NotFoundException (int code, String msg) {
|
||||
super(code, msg);
|
||||
this.code = code;
|
||||
}
|
||||
}
|
43
apis/user-java/src/main/java/io/swagger/api/UserApi.java
Normal file
43
apis/user-java/src/main/java/io/swagger/api/UserApi.java
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* NOTE: This class is auto generated by the swagger code generator program (2.3.1).
|
||||
* https://github.com/swagger-api/swagger-codegen
|
||||
* Do not edit the class manually.
|
||||
*/
|
||||
package io.swagger.api;
|
||||
|
||||
import io.swagger.model.ErrorResponseDefault;
|
||||
import io.swagger.model.InlineResponseDefault;
|
||||
import io.swagger.model.Profile;
|
||||
import io.swagger.annotations.*;
|
||||
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;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.validation.Valid;
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Api(value = "User Java", description = "User-Java API", tags = { "User Java" })
|
||||
public interface UserApi {
|
||||
|
||||
@ApiOperation(value = "", nickname = "updateUser", notes = "Update User", response = Profile.class, tags={ })
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 200, message = "User Updated", response = Profile.class),
|
||||
@ApiResponse(code = 404, message = "User profile not found"),
|
||||
@ApiResponse(code = 200, message = "Unknown Error", response = ErrorResponseDefault.class) })
|
||||
@RequestMapping(value = "/user-java/{userID}",
|
||||
consumes = { "application/json" },
|
||||
method = RequestMethod.PATCH)
|
||||
ResponseEntity<Profile> updateUser(@ApiParam(value = "User's unique ID",required=true) @PathVariable("userID") String userID,@ApiParam(value = "Details of the profile" ,required=true ) @Valid @RequestBody Profile profile);
|
||||
|
||||
@ApiOperation(value = "", nickname = "userPOST", notes = "Declares and creates a new profile", response = Profile.class, tags={ })
|
||||
@ApiResponses(value = {
|
||||
@ApiResponse(code = 201, message = "Creation successful", response = Profile.class),
|
||||
@ApiResponse(code = 200, message = "An error occurred", response = InlineResponseDefault.class) })
|
||||
@RequestMapping(value = "/user-java/{userID}",
|
||||
consumes = { "application/json" },
|
||||
method = RequestMethod.POST)
|
||||
ResponseEntity<Profile> userPOST(@ApiParam(value = "User's unique ID",required=true) @PathVariable("userID") String userID,@ApiParam(value = "Details of the profile" ,required=true ) @Valid @RequestBody Profile profile);
|
||||
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package io.swagger.api;
|
||||
|
||||
import io.swagger.model.Profile;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.annotations.*;
|
||||
import io.swagger.repository.UserRepositoryService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Controller
|
||||
public class UserApiController implements UserApi {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(UserApiController.class);
|
||||
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
private HttpServletRequest request;
|
||||
|
||||
@Autowired
|
||||
UserRepositoryService userRepositoryService;
|
||||
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
public UserApiController(ObjectMapper objectMapper, HttpServletRequest request) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
public ResponseEntity<Profile> updateUser(@ApiParam(value = "User's unique ID",required=true) @PathVariable("userID") String userID,@ApiParam(value = "Details of the profile" ,required=true ) @Valid @RequestBody Profile profile) {
|
||||
String accept = request.getHeader("Accept");
|
||||
if (accept != null && accept.contains("application/json")) {
|
||||
try {
|
||||
profile.setId(userID);
|
||||
Profile updatedUser = userRepositoryService.update(profile);
|
||||
return new ResponseEntity<Profile>(updatedUser, HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
log.error("Error updating user profile", e.getMessage());
|
||||
return new ResponseEntity<Profile>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return new ResponseEntity<Profile>(HttpStatus.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
public ResponseEntity<Profile> userPOST(@ApiParam(value = "User's unique ID",required=true) @PathVariable("userID") String userID,@ApiParam(value = "Details of the profile" ,required=true ) @Valid @RequestBody Profile profile) {
|
||||
String accept = request.getHeader("Accept");
|
||||
if (accept != null && accept.contains("application/json")) {
|
||||
try {
|
||||
return new ResponseEntity<Profile>(userRepositoryService.save(profile), HttpStatus.OK);
|
||||
} catch (Exception e) {
|
||||
log.error("Couldn't create new profile", e.getMessage());
|
||||
return new ResponseEntity<Profile>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return new ResponseEntity<Profile>(HttpStatus.NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
}
|
17
apis/user-java/src/main/java/io/swagger/api/VersionApi.java
Normal file
17
apis/user-java/src/main/java/io/swagger/api/VersionApi.java
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
package io.swagger.api;
|
||||
|
||||
import io.swagger.annotations.*;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Api(value = "version", description = "the version API")
|
||||
public interface VersionApi {
|
||||
@ApiOperation(value = "", nickname = "versionGet", notes = "Returns version for systems looking to identify the current API version or tag", response = String.class, tags={ })
|
||||
@RequestMapping(value = "/version/user-java",
|
||||
produces = { "text/plain" },
|
||||
method = RequestMethod.GET)
|
||||
ResponseEntity<String> versionGet();
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package io.swagger.api;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Controller
|
||||
public class VersionApiController implements VersionApi {
|
||||
private static final Logger log = LoggerFactory.getLogger(VersionApiController.class);
|
||||
private final HttpServletRequest request;
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@org.springframework.beans.factory.annotation.Autowired
|
||||
public VersionApiController(ObjectMapper objectMapper, HttpServletRequest request) {
|
||||
this.objectMapper = objectMapper;
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseEntity<String> versionGet() {
|
||||
String version = System.getenv("APP_VERSION");
|
||||
return new ResponseEntity<String>(version, HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,232 @@
|
||||
package io.swagger.configuration;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonTokenId;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import com.fasterxml.jackson.datatype.threetenbp.DateTimeUtils;
|
||||
import com.fasterxml.jackson.datatype.threetenbp.DecimalUtils;
|
||||
import com.fasterxml.jackson.datatype.threetenbp.deser.ThreeTenDateTimeDeserializerBase;
|
||||
import com.fasterxml.jackson.datatype.threetenbp.function.BiFunction;
|
||||
import com.fasterxml.jackson.datatype.threetenbp.function.Function;
|
||||
import org.threeten.bp.DateTimeException;
|
||||
import org.threeten.bp.Instant;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.ZoneId;
|
||||
import org.threeten.bp.ZonedDateTime;
|
||||
import org.threeten.bp.format.DateTimeFormatter;
|
||||
import org.threeten.bp.temporal.Temporal;
|
||||
import org.threeten.bp.temporal.TemporalAccessor;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* Deserializer for ThreeTen temporal {@link Instant}s, {@link OffsetDateTime}, and {@link ZonedDateTime}s.
|
||||
* Adapted from the jackson threetenbp InstantDeserializer to add support for deserializing rfc822 format.
|
||||
*
|
||||
* @author Nick Williams
|
||||
*/
|
||||
public class CustomInstantDeserializer<T extends Temporal>
|
||||
extends ThreeTenDateTimeDeserializerBase<T> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static final CustomInstantDeserializer<Instant> INSTANT = new CustomInstantDeserializer<Instant>(
|
||||
Instant.class, DateTimeFormatter.ISO_INSTANT,
|
||||
new Function<TemporalAccessor, Instant>() {
|
||||
@Override
|
||||
public Instant apply(TemporalAccessor temporalAccessor) {
|
||||
return Instant.from(temporalAccessor);
|
||||
}
|
||||
},
|
||||
new Function<FromIntegerArguments, Instant>() {
|
||||
@Override
|
||||
public Instant apply(FromIntegerArguments a) {
|
||||
return Instant.ofEpochMilli(a.value);
|
||||
}
|
||||
},
|
||||
new Function<FromDecimalArguments, Instant>() {
|
||||
@Override
|
||||
public Instant apply(FromDecimalArguments a) {
|
||||
return Instant.ofEpochSecond(a.integer, a.fraction);
|
||||
}
|
||||
},
|
||||
null
|
||||
);
|
||||
|
||||
public static final CustomInstantDeserializer<OffsetDateTime> OFFSET_DATE_TIME = new CustomInstantDeserializer<OffsetDateTime>(
|
||||
OffsetDateTime.class, DateTimeFormatter.ISO_OFFSET_DATE_TIME,
|
||||
new Function<TemporalAccessor, OffsetDateTime>() {
|
||||
@Override
|
||||
public OffsetDateTime apply(TemporalAccessor temporalAccessor) {
|
||||
return OffsetDateTime.from(temporalAccessor);
|
||||
}
|
||||
},
|
||||
new Function<FromIntegerArguments, OffsetDateTime>() {
|
||||
@Override
|
||||
public OffsetDateTime apply(FromIntegerArguments a) {
|
||||
return OffsetDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId);
|
||||
}
|
||||
},
|
||||
new Function<FromDecimalArguments, OffsetDateTime>() {
|
||||
@Override
|
||||
public OffsetDateTime apply(FromDecimalArguments a) {
|
||||
return OffsetDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId);
|
||||
}
|
||||
},
|
||||
new BiFunction<OffsetDateTime, ZoneId, OffsetDateTime>() {
|
||||
@Override
|
||||
public OffsetDateTime apply(OffsetDateTime d, ZoneId z) {
|
||||
return d.withOffsetSameInstant(z.getRules().getOffset(d.toLocalDateTime()));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
public static final CustomInstantDeserializer<ZonedDateTime> ZONED_DATE_TIME = new CustomInstantDeserializer<ZonedDateTime>(
|
||||
ZonedDateTime.class, DateTimeFormatter.ISO_ZONED_DATE_TIME,
|
||||
new Function<TemporalAccessor, ZonedDateTime>() {
|
||||
@Override
|
||||
public ZonedDateTime apply(TemporalAccessor temporalAccessor) {
|
||||
return ZonedDateTime.from(temporalAccessor);
|
||||
}
|
||||
},
|
||||
new Function<FromIntegerArguments, ZonedDateTime>() {
|
||||
@Override
|
||||
public ZonedDateTime apply(FromIntegerArguments a) {
|
||||
return ZonedDateTime.ofInstant(Instant.ofEpochMilli(a.value), a.zoneId);
|
||||
}
|
||||
},
|
||||
new Function<FromDecimalArguments, ZonedDateTime>() {
|
||||
@Override
|
||||
public ZonedDateTime apply(FromDecimalArguments a) {
|
||||
return ZonedDateTime.ofInstant(Instant.ofEpochSecond(a.integer, a.fraction), a.zoneId);
|
||||
}
|
||||
},
|
||||
new BiFunction<ZonedDateTime, ZoneId, ZonedDateTime>() {
|
||||
@Override
|
||||
public ZonedDateTime apply(ZonedDateTime zonedDateTime, ZoneId zoneId) {
|
||||
return zonedDateTime.withZoneSameInstant(zoneId);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
protected final Function<FromIntegerArguments, T> fromMilliseconds;
|
||||
|
||||
protected final Function<FromDecimalArguments, T> fromNanoseconds;
|
||||
|
||||
protected final Function<TemporalAccessor, T> parsedToValue;
|
||||
|
||||
protected final BiFunction<T, ZoneId, T> adjust;
|
||||
|
||||
protected CustomInstantDeserializer(Class<T> supportedType,
|
||||
DateTimeFormatter parser,
|
||||
Function<TemporalAccessor, T> parsedToValue,
|
||||
Function<FromIntegerArguments, T> fromMilliseconds,
|
||||
Function<FromDecimalArguments, T> fromNanoseconds,
|
||||
BiFunction<T, ZoneId, T> adjust) {
|
||||
super(supportedType, parser);
|
||||
this.parsedToValue = parsedToValue;
|
||||
this.fromMilliseconds = fromMilliseconds;
|
||||
this.fromNanoseconds = fromNanoseconds;
|
||||
this.adjust = adjust == null ? new BiFunction<T, ZoneId, T>() {
|
||||
@Override
|
||||
public T apply(T t, ZoneId zoneId) {
|
||||
return t;
|
||||
}
|
||||
} : adjust;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected CustomInstantDeserializer(CustomInstantDeserializer<T> base, DateTimeFormatter f) {
|
||||
super((Class<T>) base.handledType(), f);
|
||||
parsedToValue = base.parsedToValue;
|
||||
fromMilliseconds = base.fromMilliseconds;
|
||||
fromNanoseconds = base.fromNanoseconds;
|
||||
adjust = base.adjust;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JsonDeserializer<T> withDateFormat(DateTimeFormatter dtf) {
|
||||
if (dtf == _formatter) {
|
||||
return this;
|
||||
}
|
||||
return new CustomInstantDeserializer<T>(this, dtf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T deserialize(JsonParser parser, DeserializationContext context) throws IOException {
|
||||
//NOTE: Timestamps contain no timezone info, and are always in configured TZ. Only
|
||||
//string values have to be adjusted to the configured TZ.
|
||||
switch (parser.getCurrentTokenId()) {
|
||||
case JsonTokenId.ID_NUMBER_FLOAT: {
|
||||
BigDecimal value = parser.getDecimalValue();
|
||||
long seconds = value.longValue();
|
||||
int nanoseconds = DecimalUtils.extractNanosecondDecimal(value, seconds);
|
||||
return fromNanoseconds.apply(new FromDecimalArguments(
|
||||
seconds, nanoseconds, getZone(context)));
|
||||
}
|
||||
|
||||
case JsonTokenId.ID_NUMBER_INT: {
|
||||
long timestamp = parser.getLongValue();
|
||||
if (context.isEnabled(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS)) {
|
||||
return this.fromNanoseconds.apply(new FromDecimalArguments(
|
||||
timestamp, 0, this.getZone(context)
|
||||
));
|
||||
}
|
||||
return this.fromMilliseconds.apply(new FromIntegerArguments(
|
||||
timestamp, this.getZone(context)
|
||||
));
|
||||
}
|
||||
|
||||
case JsonTokenId.ID_STRING: {
|
||||
String string = parser.getText().trim();
|
||||
if (string.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (string.endsWith("+0000")) {
|
||||
string = string.substring(0, string.length() - 5) + "Z";
|
||||
}
|
||||
T value;
|
||||
try {
|
||||
TemporalAccessor acc = _formatter.parse(string);
|
||||
value = parsedToValue.apply(acc);
|
||||
if (context.isEnabled(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)) {
|
||||
return adjust.apply(value, this.getZone(context));
|
||||
}
|
||||
} catch (DateTimeException e) {
|
||||
throw _peelDTE(e);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
throw context.mappingException("Expected type float, integer, or string.");
|
||||
}
|
||||
|
||||
private ZoneId getZone(DeserializationContext context) {
|
||||
// Instants are always in UTC, so don't waste compute cycles
|
||||
return (_valueClass == Instant.class) ? null : DateTimeUtils.timeZoneToZoneId(context.getTimeZone());
|
||||
}
|
||||
|
||||
private static class FromIntegerArguments {
|
||||
public final long value;
|
||||
public final ZoneId zoneId;
|
||||
|
||||
private FromIntegerArguments(long value, ZoneId zoneId) {
|
||||
this.value = value;
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
}
|
||||
|
||||
private static class FromDecimalArguments {
|
||||
public final long integer;
|
||||
public final int fraction;
|
||||
public final ZoneId zoneId;
|
||||
|
||||
private FromDecimalArguments(long integer, int fraction, ZoneId zoneId) {
|
||||
this.integer = integer;
|
||||
this.fraction = fraction;
|
||||
this.zoneId = zoneId;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package io.swagger.configuration;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
/**
|
||||
* Home redirection to swagger api documentation
|
||||
*/
|
||||
@Controller
|
||||
public class HomeController {
|
||||
@RequestMapping(value = "/")
|
||||
public String index() {
|
||||
System.out.println("swagger-ui.html");
|
||||
return "redirect:swagger-ui.html";
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.swagger.configuration;
|
||||
|
||||
import com.fasterxml.jackson.datatype.threetenbp.ThreeTenModule;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.threeten.bp.Instant;
|
||||
import org.threeten.bp.OffsetDateTime;
|
||||
import org.threeten.bp.ZonedDateTime;
|
||||
|
||||
@Configuration
|
||||
public class JacksonConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ThreeTenModule.class)
|
||||
ThreeTenModule threeTenModule() {
|
||||
ThreeTenModule module = new ThreeTenModule();
|
||||
module.addDeserializer(Instant.class, CustomInstantDeserializer.INSTANT);
|
||||
module.addDeserializer(OffsetDateTime.class, CustomInstantDeserializer.OFFSET_DATE_TIME);
|
||||
module.addDeserializer(ZonedDateTime.class, CustomInstantDeserializer.ZONED_DATE_TIME);
|
||||
return module;
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package io.swagger.configuration;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2
|
||||
@EnableWebMvc
|
||||
public class SwaggerDocumentationConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("My Driving User Java API")
|
||||
.description("API for the user in the My Driving example app. https://github.com/Azure-Samples/openhack-devops-team")
|
||||
.license("")
|
||||
.licenseUrl("http://unlicense.org")
|
||||
.termsOfServiceUrl("")
|
||||
.version("0.1.0")
|
||||
.contact(new Contact("","", ""))
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Docket customImplementation(){
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.basePackage("io.swagger.api"))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.pathMapping("/")
|
||||
.directModelSubstitute(org.threeten.bp.LocalDate.class, java.sql.Date.class)
|
||||
.directModelSubstitute(org.threeten.bp.OffsetDateTime.class, java.util.Date.class)
|
||||
.apiInfo(apiInfo());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addRedirectViewController("/docs/user-java/api-docs", "/api-docs").setKeepQueryParams(true);
|
||||
registry.addRedirectViewController("/docs/user-java/swagger-resources/configuration/ui","/swagger-resources/configuration/ui");
|
||||
registry.addRedirectViewController("/docs/user-java/swagger-resources/configuration/security","/swagger-resources/configuration/security");
|
||||
registry.addRedirectViewController("/docs/user-java/swagger-resources", "/swagger-resources");
|
||||
registry.addRedirectViewController("/docs/user-java", "/docs/user-java/swagger-ui.html");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/docs/user-java/**").addResourceLocations("classpath:/META-INF/resources/");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package io.swagger.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* ErrorResponseDefault
|
||||
*/
|
||||
@Validated
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class ErrorResponseDefault {
|
||||
@JsonProperty("status")
|
||||
private Integer status = null;
|
||||
|
||||
@JsonProperty("message")
|
||||
private String message = null;
|
||||
|
||||
public ErrorResponseDefault status(Integer status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error code (if available)
|
||||
* @return status
|
||||
**/
|
||||
@ApiModelProperty(value = "Error code (if available)")
|
||||
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public ErrorResponseDefault message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Error Message
|
||||
* @return message
|
||||
**/
|
||||
@ApiModelProperty(value = "Error Message")
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(java.lang.Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ErrorResponseDefault errorResponseDefault = (ErrorResponseDefault) o;
|
||||
return Objects.equals(this.status, errorResponseDefault.status) &&
|
||||
Objects.equals(this.message, errorResponseDefault.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(status, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class ErrorResponseDefault {\n");
|
||||
|
||||
sb.append(" status: ").append(toIndentedString(status)).append("\n");
|
||||
sb.append(" message: ").append(toIndentedString(message)).append("\n");
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to string with each line indented by 4 spaces
|
||||
* (except the first line).
|
||||
*/
|
||||
private String toIndentedString(java.lang.Object o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
}
|
||||
|
102
apis/user-java/src/main/java/io/swagger/model/Healthcheck.java
Normal file
102
apis/user-java/src/main/java/io/swagger/model/Healthcheck.java
Normal file
@ -0,0 +1,102 @@
|
||||
package io.swagger.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
/**
|
||||
* Healthcheck
|
||||
*/
|
||||
@Validated
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class Healthcheck {
|
||||
@JsonProperty("message")
|
||||
private String message = null;
|
||||
|
||||
@JsonProperty("status")
|
||||
private String status = null;
|
||||
|
||||
public Healthcheck message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return message
|
||||
**/
|
||||
@ApiModelProperty(value = "")
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public Healthcheck status(String status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return status
|
||||
**/
|
||||
@ApiModelProperty(value = "")
|
||||
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(java.lang.Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Healthcheck healthcheck = (Healthcheck) o;
|
||||
return Objects.equals(this.message, healthcheck.message) &&
|
||||
Objects.equals(this.status, healthcheck.status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(message, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class Healthcheck {\n");
|
||||
|
||||
sb.append(" message: ").append(toIndentedString(message)).append("\n");
|
||||
sb.append(" status: ").append(toIndentedString(status)).append("\n");
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to string with each line indented by 4 spaces
|
||||
* (except the first line).
|
||||
*/
|
||||
private String toIndentedString(java.lang.Object o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,105 @@
|
||||
package io.swagger.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import javax.validation.constraints.*;
|
||||
|
||||
/**
|
||||
* InlineResponseDefault
|
||||
*/
|
||||
@Validated
|
||||
@javax.annotation.Generated(value = "io.swagger.codegen.languages.SpringCodegen", date = "2018-08-03T19:26:46.543Z")
|
||||
|
||||
public class InlineResponseDefault {
|
||||
@JsonProperty("status")
|
||||
private Integer status = null;
|
||||
|
||||
@JsonProperty("message")
|
||||
private String message = null;
|
||||
|
||||
public InlineResponseDefault status(Integer status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get status
|
||||
* @return status
|
||||
**/
|
||||
@ApiModelProperty(required = true, value = "")
|
||||
@NotNull
|
||||
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public InlineResponseDefault message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message
|
||||
* @return message
|
||||
**/
|
||||
@ApiModelProperty(required = true, value = "")
|
||||
@NotNull
|
||||
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(java.lang.Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
InlineResponseDefault inlineResponseDefault = (InlineResponseDefault) o;
|
||||
return Objects.equals(this.status, inlineResponseDefault.status) &&
|
||||
Objects.equals(this.message, inlineResponseDefault.message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(status, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("class InlineResponseDefault {\n");
|
||||
|
||||
sb.append(" status: ").append(toIndentedString(status)).append("\n");
|
||||
sb.append(" message: ").append(toIndentedString(message)).append("\n");
|
||||
sb.append("}");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to string with each line indented by 4 spaces
|
||||
* (except the first line).
|
||||
*/
|
||||
private String toIndentedString(java.lang.Object o) {
|
||||
if (o == null) {
|
||||
return "null";
|
||||
}
|
||||
return o.toString().replace("\n", "\n ");
|
||||
}
|
||||
}
|
||||
|
BIN
apis/user-java/src/main/java/io/swagger/model/Profile.java
Normal file
BIN
apis/user-java/src/main/java/io/swagger/model/Profile.java
Normal file
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
package io.swagger.repository;
|
||||
|
||||
import io.swagger.model.Profile;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface UserRepository extends JpaRepository<Profile, String> {
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package io.swagger.repository;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import io.swagger.model.Profile;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
@Service
|
||||
public class UserRepositoryService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserRepositoryService.class);
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
|
||||
|
||||
public Profile update(Profile updateEntry) {
|
||||
long start = System.currentTimeMillis();
|
||||
Preconditions.checkNotNull(updateEntry, "User profile cannot be null");
|
||||
|
||||
LOGGER.info("Updating user profile for user=%s", updateEntry.getId());
|
||||
Profile existingUser = findOne(updateEntry.getId());
|
||||
if (existingUser == null) {
|
||||
throw new NullPointerException("Unable to locate user");
|
||||
}
|
||||
|
||||
existingUser.setTotalTrips(updateEntry.getTotalTrips() == null? existingUser.getTotalTrips() : updateEntry.getTotalTrips());
|
||||
existingUser.setTotalDistance(updateEntry.getTotalDistance() == null ? existingUser.getTotalTrips() : updateEntry.getTotalDistance());
|
||||
existingUser.setTotalTime(updateEntry.getTotalTime() == null ? existingUser.getTotalTime() : updateEntry.getTotalTime());
|
||||
existingUser.setHardStops(updateEntry.getHardStops() == null ? existingUser.getHardStops() : updateEntry.getHardStops());
|
||||
existingUser.setHardAccelerations(updateEntry.getHardAccelerations() == null ? existingUser.getHardAccelerations() : updateEntry.getHardAccelerations());
|
||||
existingUser.setFuelConsumption(updateEntry.getFuelConsumption() == null ? existingUser.getFuelConsumption() : updateEntry.getFuelConsumption());
|
||||
existingUser.setMaxSpeed(updateEntry.getMaxSpeed() == null ? existingUser.getMaxSpeed() : updateEntry.getMaxSpeed());
|
||||
existingUser.setRating(updateEntry.getRating() == null ? existingUser.getRating() : updateEntry.getRating());
|
||||
existingUser.setRating(updateEntry.getRanking() == null ? existingUser.getRanking() : updateEntry.getRanking());
|
||||
|
||||
Profile userProfile = save(existingUser);
|
||||
long end = System.currentTimeMillis();
|
||||
long timeElapsed = end - start;
|
||||
|
||||
LOGGER.info("Update method called: on {} and response time in ms: {}", timestamp, timeElapsed);
|
||||
return userProfile;
|
||||
}
|
||||
|
||||
public Profile save(Profile newProfile) {
|
||||
Preconditions.checkNotNull(newProfile, "User profile cannot be null");
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
Profile userProfile = userRepository.save(newProfile);
|
||||
long end = System.currentTimeMillis();
|
||||
long timeElapsed = end - start;
|
||||
|
||||
LOGGER.info("Save method called: on {} and response time in ms: {}", timestamp, timeElapsed);
|
||||
return userProfile;
|
||||
}
|
||||
|
||||
private Profile findOne(String Id) {
|
||||
Preconditions.checkNotNull(Id, "User Id cannot be null");
|
||||
return userRepository.findOne(Id);
|
||||
}
|
||||
|
||||
}
|
10
apis/user-java/src/main/resources/application.properties
Normal file
10
apis/user-java/src/main/resources/application.properties
Normal file
@ -0,0 +1,10 @@
|
||||
springfox.documentation.swagger.v2.path=/api-docs
|
||||
server.contextPath=/api
|
||||
server.port=8080
|
||||
spring.jackson.date-format=io.swagger.RFC3339DateFormat
|
||||
spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
|
||||
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
|
||||
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect
|
||||
spring.datasource.url=jdbc:sqlserver://${SQL_SERVER};databaseName=${SQL_DBNAME};trustServerCertificate=true;selectMethod=cursor
|
||||
spring.datasource.username=${SQL_USER}
|
||||
spring.datasource.password=${SQL_PASSWORD}
|
119
apis/user-java/src/test/java/UserApiControllerTest.java
Normal file
119
apis/user-java/src/test/java/UserApiControllerTest.java
Normal file
@ -0,0 +1,119 @@
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import io.swagger.api.UserApiController;
|
||||
import io.swagger.model.Profile;
|
||||
import io.swagger.repository.UserRepositoryService;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UserApiControllerTest {
|
||||
|
||||
public static final MediaType APPLICATION_JSON_UTF8 = new MediaType(MediaType.APPLICATION_JSON.getType(), MediaType.APPLICATION_JSON.getSubtype(), Charset.forName("utf8"));
|
||||
|
||||
@InjectMocks
|
||||
private UserApiController userApiController;
|
||||
|
||||
private MockMvc mockMvc;
|
||||
|
||||
private Profile profile;
|
||||
|
||||
@Mock
|
||||
HttpServletRequest httpServletRequest;
|
||||
|
||||
@Mock
|
||||
UserRepositoryService userRepositoryService;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
|
||||
// this must be called for the @Mock annotations above to be processed
|
||||
// and for the mock service to be injected into the controller under
|
||||
// test.
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mockMvc = MockMvcBuilders.standaloneSetup(userApiController).build();
|
||||
profile = new Profile();
|
||||
profile.setFirstName("test");
|
||||
profile.setUserId("userId");
|
||||
profile.setRanking(1);
|
||||
profile.setTotalDistance(1000f);
|
||||
profile.setId("2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSave() throws Exception {
|
||||
when(httpServletRequest.getHeader("Accept")).thenReturn("accept,application/json;charset=UTF-8");
|
||||
when(userRepositoryService.save(profile)).thenReturn(profile);
|
||||
mockMvc.perform(
|
||||
post("/user-java/2")
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.content(convertObjectToJsonBytes(profile))
|
||||
)
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
|
||||
verify(userRepositoryService, times(1)).save(profile);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSave_shouldNotImplemented() throws Exception {
|
||||
mockMvc.perform(
|
||||
post("/user-java/2")
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.content(convertObjectToJsonBytes(profile))
|
||||
)
|
||||
.andExpect(MockMvcResultMatchers.status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_shouldNotImplemented() throws Exception {
|
||||
mockMvc.perform(
|
||||
patch("/user-java/2")
|
||||
.contentType(MediaType.APPLICATION_JSON_UTF8)
|
||||
.accept(MediaType.APPLICATION_JSON)
|
||||
.content(convertObjectToJsonBytes(profile))
|
||||
)
|
||||
.andExpect(MockMvcResultMatchers.status().is5xxServerError());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() throws Exception {
|
||||
profile.setRanking(2);
|
||||
profile.setTotalDistance(2500F);
|
||||
when(httpServletRequest.getHeader("Accept")).thenReturn("accept,application/json;charset=UTF-8");
|
||||
when(userRepositoryService.update(profile)).thenReturn(profile);
|
||||
mockMvc.perform(
|
||||
patch("/user-java/2")
|
||||
.contentType(APPLICATION_JSON_UTF8)
|
||||
.content(convertObjectToJsonBytes(profile)))
|
||||
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8));
|
||||
verify(userRepositoryService, times(1)).update(profile);
|
||||
|
||||
}
|
||||
|
||||
public static byte[] convertObjectToJsonBytes(Object object) throws IOException {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
return mapper.writeValueAsBytes(object);
|
||||
}
|
||||
}
|
84
apis/user-java/src/test/java/UserRepositoryServiceTest.java
Normal file
84
apis/user-java/src/test/java/UserRepositoryServiceTest.java
Normal file
@ -0,0 +1,84 @@
|
||||
import io.swagger.model.Profile;
|
||||
import io.swagger.repository.UserRepository;
|
||||
import io.swagger.repository.UserRepositoryService;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class UserRepositoryServiceTest {
|
||||
|
||||
private static final String USER_ID = "test1";
|
||||
private static final String ID = "1234";
|
||||
private static final String FIRST_NAME = "test";
|
||||
private static final String LAST_NAME = "lastname";
|
||||
private static final int RANKING = 1;
|
||||
private static final float TOTAL_DISTANCE = 1000;
|
||||
|
||||
private Profile profile;
|
||||
|
||||
private Integer ranking = 2;
|
||||
private Float distance = 2000F;
|
||||
|
||||
@Mock
|
||||
UserRepository userRepository;
|
||||
|
||||
@InjectMocks
|
||||
UserRepositoryService userRepositoryService;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
profile = new Profile();
|
||||
profile.setUserId(USER_ID);
|
||||
profile.setId(ID);
|
||||
profile.setFirstName(FIRST_NAME);
|
||||
profile.setLastName(LAST_NAME);
|
||||
profile.setRanking(RANKING);
|
||||
profile.setTotalDistance(TOTAL_DISTANCE);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
profile = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSave() {
|
||||
when(userRepository.save(any(Profile.class))).thenReturn(profile);
|
||||
assertNotNull(userRepositoryService.save(profile));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() {
|
||||
when(userRepository.findOne(ID)).thenReturn(profile);
|
||||
profile.setRanking(ranking);
|
||||
profile.setTotalDistance(distance);
|
||||
when(userRepository.save(profile)).thenReturn(profile);
|
||||
Profile updated = userRepositoryService.update(profile);
|
||||
assertEquals(ranking, updated.getRanking());
|
||||
assertEquals(distance, updated.getTotalDistance());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate_shouldThrowException() {
|
||||
when(userRepository.findOne(USER_ID)).thenReturn(null);
|
||||
try {
|
||||
userRepositoryService.update(profile);
|
||||
fail("Unable to locate user");
|
||||
|
||||
}catch (NullPointerException e) {
|
||||
assertEquals("Unable to locate user", e.getMessage());
|
||||
}
|
||||
verify(userRepository, never()).save(profile);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user