Commit ef6d3802 by Jan Hrabal

work in progress - backend

parent b63018c4
......@@ -11,7 +11,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<classpathentry including="**/*.java" kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
......@@ -28,5 +28,11 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
......@@ -11,12 +11,12 @@
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
......
package com.jh.memsource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MemsourceConfig {
@Autowired
private ObjectMapper objectMapper;
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
package com.jh.memsource.model;
import java.util.Collections;
import java.util.List;
/**
* Common container for paged collections
*
* @author Jan
*
* @param <T>
*/
public class PagedList<T> {
private static final PagedList<?> EMPTY = new PagedList<>();
private int pages;
private int pageSize;
private int pageNumber;
private List<T> items;
public PagedList() {
super();
items = Collections.emptyList();
}
public PagedList(List<T> items, int pageNumber, int pageSize) {
super();
this.items = items;
this.pageSize = pageSize;
this.pageNumber = pageNumber;
}
public int getPages() {
return pages;
}
public void setPages(int pages) {
this.pages = pages;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public List<T> getItems() {
return items;
}
public void setItems(List<T> items) {
this.items = items;
}
@SuppressWarnings("unchecked")
public static <T> PagedList<T> emptyList() {
return (PagedList<T>) EMPTY;
}
}
package com.jh.memsource.project;
package com.jh.memsource.model;
public class Project {
......
package com.jh.memsource.settings;
package com.jh.memsource.model;
import javax.persistence.Column;
import javax.persistence.Entity;
......
package com.jh.memsource.project;
import java.util.Collections;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.jh.memsource.model.PagedList;
import com.jh.memsource.model.Project;
import com.jh.memsource.settings.SettingsService;
@RestController
public class ProjectApiController {
@Autowired
private ProjectService service;
@Autowired
private SettingsService settingsService;
@GetMapping("/projects")
public @ResponseBody List<Project> getSettings() {
List<Project> projects = service.getProjects();
if (projects == null) {
return Collections.emptyList();
}
//map to DTO
return projects;
public @ResponseBody PagedList<Project> getSettings() {
return service.getProjects(settingsService.getSettings());
}
......
package com.jh.memsource.project;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jh.memsource.model.PagedList;
import com.jh.memsource.model.Project;
import com.jh.memsource.model.Settings;
import com.jh.memsource.project.repo.ProjectRepository;
@Service
public class ProjectService {
public List<Project> getProjects() {
List<Project> projects = new ArrayList<>();
for (int i = 1; i < 11; i++) {
projects.add(new Project(String.format("Project %s", i), null, null, null));
}
return projects;
}
private ProjectRepository repository;
/**
* Returns list of projects
*
* @return
*/
public PagedList<Project> getProjects(Settings settings) {
return repository.listProjects(settings, 0, 20);
}
@Autowired
public void setRepository(ProjectRepository repository) {
this.repository = repository;
}
}
package com.jh.memsource.project;
public class RemoteProject {
private String name;
private String status;
private String sourceLanguage;
private String targetLanguage;
}
package com.jh.memsource.project.repo;
/*
{
"userName": "string",
"password": "string",
"code": "string"
}
*/
public class LoginRequest {
private String userName;
private String password;
public LoginRequest() {
super();
}
public LoginRequest(String userName, String password) {
super();
this.userName = userName;
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package com.jh.memsource.project.repo;
/*
{
"token": "string"
}
*/
public class LoginResponse {
private String token;
public LoginResponse() {
super();
}
public LoginResponse(String token) {
super();
this.token = token;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
}
package com.jh.memsource.project.repo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Repository;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
import com.jh.memsource.model.PagedList;
import com.jh.memsource.model.Project;
import com.jh.memsource.model.Settings;
/**
* This class accesses API at https://cloud.memsource.com/web/docs/api
*
* @author Jan
*
*/
@Repository
public class ProjectRepository {
private static final Logger LOG = LoggerFactory.getLogger(ProjectRepository.class);
private RestTemplate restTemplate;
private String apiBaseUrl;
private String loginApiUri;
private String projectApiUri;
private int defaultPageSize;
/**
* Cached auth token
*/
private String authToken;
/**
* Lists projects
*
* @param settings
* @param page
* @param pageSize
* @return
*/
public PagedList<Project> listProjects(Settings settings, Integer page, Integer pageSize) {
if (settings == null) {
}
if (page == null || page < 0) {
page = 0;
}
if (pageSize == null || pageSize < 1) {
pageSize = defaultPageSize;
}
return fetchProjects(settings, page, pageSize, true);
}
protected PagedList<Project> fetchProjects(Settings settings, int page, int pageSize, boolean retryAuth) {
synchronized(this) {
if (authToken == null) {
authToken = getAuthToken(settings);
}
}
try {
Map<String, Object> params = new HashMap<>();
params.put("token", authToken);
params.put("page", page);
params.put("pageSize", pageSize);
ResponseEntity<ProjectsResponse> response = restTemplate.getForEntity(String.format("%s/%s?token={token}&pageNumber={page}&pageSize={pageSize}", apiBaseUrl, projectApiUri), ProjectsResponse.class, params);
ProjectsResponse body = response.getBody();
if (body == null || body.getContent() == null) {
return new PagedList<Project>();
}
// map response
List<ProjectResponse> content = body.getContent();
List<Project> items = content.stream().map(pr -> new Project(pr.getName(), pr.getStatus(), pr.getSourceLang(), pr.getTargetLangs())).collect(Collectors.toList());
return new PagedList<Project>(items, body.getTotalPages(), pageSize);
} catch (HttpStatusCodeException e) {
//handle expired token
if (HttpStatus.UNAUTHORIZED.equals(e.getStatusCode()) && retryAuth) {
authToken = null;
return fetchProjects(settings, page, pageSize, false);
}
LOG.error("Cannot get list of projects", e);
throw e;
}
}
protected String getAuthToken(Settings settings) {
ResponseEntity<LoginResponse> response = restTemplate.postForEntity(String.format("%s/%s", apiBaseUrl, loginApiUri), new LoginRequest(settings.getUsername(), settings.getPassword()), LoginResponse.class);
return response.getBody().getToken();
}
@Value("${memsource.api.url.base:https://cloud.memsource.com/web}")
public void setApiBaseUrl(String apiBaseUrl) {
this.apiBaseUrl = apiBaseUrl;
}
@Value("${memsource.api.url.login:api2/v1/auth/login}")
public void setLoginApiUri(String loginApiUri) {
this.loginApiUri = loginApiUri;
}
@Value("${memsource.api.url.project:api2/v1/projects}")
public void setProjectApiUri(String projectApiUri) {
this.projectApiUri = projectApiUri;
}
@Value("${paging.pageSize:20}")
public void setDefaultPageSize(int defaultPageSize) {
this.defaultPageSize = defaultPageSize;
}
@Autowired
public void setRestTemplate(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
}
package com.jh.memsource.project.repo;
/*
{
"uid": "string",
"internalId": 0,
"id": "string",
"name": "string",
"dateCreated": "2019-09-16T12:29:49Z",
"domain": {},
"subDomain": {},
"owner": {},
"sourceLang": "string",
"targetLangs": [string],
"userRole": "string"
}
*/
public class ProjectResponse {
private String uid;
private String name;
private String sourceLang;
private String[] targetLangs;
private String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSourceLang() {
return sourceLang;
}
public void setSourceLang(String sourceLang) {
this.sourceLang = sourceLang;
}
public String[] getTargetLangs() {
return targetLangs;
}
public void setTargetLangs(String[] targetLangs) {
this.targetLangs = targetLangs;
}
}
package com.jh.memsource.project.repo;
import java.util.List;
/*
{
"totalElements": 0,
"totalPages": 0,
"pageSize": 0,
"pageNumber": 0,
"numberOfElements": 0,
"content": [
{
"uid": "string",
"internalId": 0,
"id": "string",
"name": "string",
"dateCreated": "2019-09-16T12:29:49Z",
"domain": {},
"subDomain": {},
"owner": {},
"sourceLang": "string",
"targetLangs": [string],
"userRole": "string"
}
]
}
*/
public class ProjectsResponse {
private Integer totalElements;
private Integer totalPages;
private Integer totalSize;
private Integer pageNumber;
private List<ProjectResponse> content;
public Integer getTotalElements() {
return totalElements;
}
public void setTotalElements(Integer totalElements) {
this.totalElements = totalElements;
}
public Integer getTotalPages() {
return totalPages;
}
public void setTotalPages(Integer totalPages) {
this.totalPages = totalPages;
}
public Integer getTotalSize() {
return totalSize;
}
public void setTotalSize(Integer totalSize) {
this.totalSize = totalSize;
}
public Integer getPageNumber() {
return pageNumber;
}
public void setPageNumber(Integer pageNumber) {
this.pageNumber = pageNumber;
}
public List<ProjectResponse> getContent() {
return content;
}
public void setContent(List<ProjectResponse> content) {
this.content = content;
}
}
......@@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
import com.jh.memsource.model.Settings;
@RestController
public class SettingsApiController {
......
......@@ -5,6 +5,9 @@ import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jh.memsource.model.Settings;
import com.jh.memsource.settings.repo.SettingsRepository;
@Service
public class SettingsService {
......
package com.jh.memsource.settings;
package com.jh.memsource.settings.repo;
import java.util.Objects;
......@@ -10,6 +10,8 @@ import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import com.jh.memsource.model.Settings;
@Repository
public class SettingsRepository {
......
Manifest-Version: 1.0
Implementation-Title: memsource
Implementation-Version: 0.0.1
Build-Jdk-Spec: 1.8
Created-By: Maven Integration for Eclipse
#Generated by Maven Integration for Eclipse
#Mon Sep 16 11:44:07 CEST 2019
version=0.0.1
groupId=com.jh
m2e.projectName=memsource
m2e.projectLocation=C\:\\Users\\jh\\git\\memsource\\backend
artifactId=memsource
<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>com.jh</groupId>
<artifactId>memsource</artifactId>
<version>0.0.1</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.date>${maven.build.timestamp}</project.build.date>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
<project.build.date>${maven.build.timestamp}</project.build.date>
<java.version>8</java.version>
</properties>
<dependencies>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-hibernate5</artifactId>
</dependency>
<!-- db -->
<!-- <dependency> -->
<!-- <groupId>org.postgresql</groupId> -->
<!-- <artifactId>postgresql</artifactId> -->
<!-- </dependency> -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
<resource>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources</directory>
</resource>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
<testResources>
<testResource>
<filtering>false</filtering>
<directory>${basedir}/src/test/java</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</testResource>
<testResource>
<filtering>false</filtering>
<directory>${basedir}/src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.4.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<sourcepath>${basedir}/dummy</sourcepath>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version><!--$NO-MVN-MAN-VER$-->
<configuration>
<release>${java.version}</release>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>com.springsource.repository.maven.release</id>
<url>http://repo.springsource.org/release/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>com.springsource.repository.bundles.release</id>
<url>http://repository.springsource.com/maven/bundles/release</url>
</repository>
<repository>
<id>com.springsource.repository.bundles.external</id>
<url>http://repository.springsource.com/maven/bundles/external</url>
</repository>
</repositories>
</project>
......@@ -68,7 +68,7 @@ export default (props) => {
setLoading(true);
try {
let response = await backend("/projects");
setProjects(response.body);
setProjects(response.body.items);
} catch (e) {
//TODO
setProjects(false);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment