Adding the Spring java API for creating Widget.

Migrating the code to Spring Java instead of Golang
This commit is contained in:
Arpit Mohan 2019-03-19 01:50:32 +05:30
parent 7ea78bf64c
commit e4f59ff941
22 changed files with 495 additions and 0 deletions

70
app/server/server/pom.xml Normal file
View File

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.mobtools</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>server</name>
<description>This is the API server for the Mobtools project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package com.mobtools.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
}
}

View File

@ -0,0 +1,19 @@
package com.mobtools.server.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
@Configuration
@EnableJpaAuditing
public class CommonConfig {
private String ELASTIC_THREAD_POOL_NAME = "mobtools-elastic-pool";
@Bean
public Scheduler scheduler() {
return Schedulers.newElastic(ELASTIC_THREAD_POOL_NAME);
}
}

View File

@ -0,0 +1,41 @@
package com.mobtools.server.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
@Configuration
@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfig {
// private final DaoAuthenticationManager reactiveAuthenticationManager;
// private final SecurityContextRepository securityContextRepository;
// @Autowired
// public SecurityConfig(DaoAuthenticationManager reactiveAuthenticationManager,
// SecurityContextRepository securityContextRepository) {
// this.reactiveAuthenticationManager = reactiveAuthenticationManager;
// this.securityContextRepository = securityContextRepository;
// }
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.csrf().disable()
.formLogin().disable()
.httpBasic().disable()
// .authenticationManager(reactiveAuthenticationManager)
// .securityContextRepository(securityContextRepository)
.authorizeExchange()
.anyExchange().permitAll()
.and()
.logout().disable()
.build();
}
}

View File

@ -0,0 +1,7 @@
package com.mobtools.server.constants;
public interface Url {
String BASE_URL = "/api";
String VERSION = "/v1";
String WIDGET_URL = BASE_URL + VERSION + "/widgets";
}

View File

@ -0,0 +1,4 @@
package com.mobtools.server.controllers;
public abstract class BaseController {
}

View File

@ -0,0 +1,47 @@
package com.mobtools.server.controllers;
import com.mobtools.server.constants.Url;
import com.mobtools.server.domains.Widget;
import com.mobtools.server.dtos.ResponseDto;
import com.mobtools.server.services.WidgetService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import javax.validation.Valid;
@RestController
@RequestMapping(Url.WIDGET_URL)
@RequiredArgsConstructor
public class WidgetController extends BaseController {
private final WidgetService widgetService;
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Mono<ResponseDto<Widget>> create(@Valid @RequestBody Widget widget) {
return widgetService.create(widget)
.map(createdWidget -> new ResponseDto<>(HttpStatus.CREATED.value(), createdWidget, null));
}
@GetMapping("")
public Flux<ResponseDto<Widget>> getAllWidgets() {
return widgetService.get()
.map(user -> new ResponseDto<>(HttpStatus.OK.value(), user, null));
}
@GetMapping("/{name}")
public Mono<ResponseDto<Widget>> getByName(@PathVariable String id) {
return widgetService.getByName(id)
.map(user -> new ResponseDto<>(HttpStatus.OK.value(), user, null));
}
@PutMapping("/{id}")
public Mono<ResponseDto<Widget>> getCureFitUser(@PathVariable Long id) {
return widgetService.update(id)
.map(cfUser -> new ResponseDto<>(HttpStatus.OK.value(), cfUser, null));
}
}

View File

@ -0,0 +1,45 @@
package com.mobtools.server.domains;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
@Setter
@ToString
public abstract class BaseDomain implements Serializable {
private static final long serialVersionUID = 7459916000501322517L;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false, updatable = false)
@CreatedDate
protected Date createdAt;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false)
@LastModifiedDate
protected Date updatedAt;
@Column
@CreatedBy
protected String createdBy;
@Column
@LastModifiedBy
protected String modifiedBy;
@Column(nullable = false)
protected Boolean deleted = false;
}

View File

@ -0,0 +1,5 @@
package com.mobtools.server.domains;
public enum PricingPlan {
FREE, STARTUP, BUSINESS, ENTERPRISE
}

View File

@ -0,0 +1,29 @@
package com.mobtools.server.domains;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@SequenceGenerator(initialValue = 1, name = "tenant_gen", sequenceName = "tenant_gen")
public class Tenant extends BaseDomain {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tenant_gen")
@Column(nullable = false, updatable = false)
private Long id;
private String domain;
private String name;
private String website;
}

View File

@ -0,0 +1,31 @@
package com.mobtools.server.domains;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
// Specially adding the table name here because the keyword "User" is reserved in Postgres
@Table(name = "users")
@Getter
@Setter
@ToString
@NoArgsConstructor
@SequenceGenerator(initialValue = 1, name = "user_gen", sequenceName = "user_gen")
public class User extends BaseDomain {
@Id
@Column(nullable = false)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_gen")
private Long id;
@Column
private String name;
@Column
private String email;
}

View File

@ -0,0 +1,34 @@
package com.mobtools.server.domains;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@SequenceGenerator(initialValue = 1, name = "widget_gen", sequenceName = "widget_gen")
public class Widget extends BaseDomain {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "widget_gen")
@Column(nullable = false, updatable = false)
private Long id;
@Column
private String name;
@Column
private WidgetType type;
@Column
private PricingPlan pricingPlan;
}

View File

@ -0,0 +1,5 @@
package com.mobtools.server.domains;
public enum WidgetType {
DB, DISPLAY
}

View File

@ -0,0 +1,21 @@
package com.mobtools.server.dtos;
import lombok.*;
import java.io.Serializable;
@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class ResponseDto<T> implements Serializable {
private static final long serialVersionUID = 8965011907233699993L;
private int status;
private T data;
private String message;
}

View File

@ -0,0 +1,11 @@
package com.mobtools.server.repositories;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import java.io.Serializable;
@NoRepositoryBean
public interface BaseRepository<T, ID extends Serializable> extends JpaRepository<T, ID> {
}

View File

@ -0,0 +1,9 @@
package com.mobtools.server.repositories;
import com.mobtools.server.domains.Widget;
import org.springframework.stereotype.Repository;
@Repository
public interface WidgetRepository extends BaseRepository<Widget, Long> {
}

View File

@ -0,0 +1,10 @@
package com.mobtools.server.services;
import lombok.RequiredArgsConstructor;
import reactor.core.scheduler.Scheduler;
@RequiredArgsConstructor
public abstract class BaseService {
final Scheduler scheduler;
}

View File

@ -0,0 +1,16 @@
package com.mobtools.server.services;
import com.mobtools.server.domains.Widget;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public interface WidgetService {
Mono<Widget> getByName(String id);
Flux<Widget> get();
Mono<Widget> create(Widget widget);
Mono<Widget> update(Long id);
}

View File

@ -0,0 +1,45 @@
package com.mobtools.server.services;
import com.mobtools.server.domains.Widget;
import com.mobtools.server.repositories.WidgetRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
@Service
@Slf4j
public class WidgetServiceImpl extends BaseService implements WidgetService {
private WidgetRepository widgetRepository;
@Autowired
public WidgetServiceImpl(Scheduler scheduler, WidgetRepository widgetRepository) {
super(scheduler);
this.widgetRepository = widgetRepository;
}
@Override
public Mono<Widget> getByName(String id) {
return null;
}
@Override
public Flux<Widget> get() {
return null;
}
@Override
public Mono<Widget> create(Widget widget) {
return Mono.fromCallable(
() -> widgetRepository.save(widget)
).subscribeOn(this.scheduler);
}
@Override
public Mono<Widget> update(Long id) {
return null;
}
}

View File

@ -0,0 +1,16 @@
# JDBC Properties
spring.datasource.url=jdbc:postgresql://localhost:5432/mobtoolsnew?useSSL=false
spring.datasource.username=postgres
spring.datasource.password=root
spring.datasource.hikari.pool-name=Hikari-Eval-Pool
spring.datasource.hikari.maximum-pool-size=16
# JPA Properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false
spring.jpa.show-sql=true
# Jackson Properties
spring.jackson.default-property-inclusion=non_null

View File

@ -0,0 +1,16 @@
package com.mobtools.server;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ServerApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@ -3,6 +3,7 @@ package url
const ComponentURL = "/components"
const QueryURL = "/query"
const LoginURL = "/login"
const AccountURL = "/accounts"
const AuthURL = "/auth/{provider}"
const AuthCallbackURL = "/auth/{provider}/callback"
const LogoutURL = "/logout/{provider}"