Moving to Mongo instead of Postgresql for storage.

This will allow us to store the widget, plugin & page information much more cleanly and directly into the DB.
This commit is contained in:
Arpit Mohan 2019-03-19 12:13:21 +05:30
parent 9cea9f94f2
commit f7aaafacfb
13 changed files with 116 additions and 78 deletions

View File

@ -23,10 +23,10 @@
<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-data-jpa</artifactId>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
@ -41,6 +41,10 @@
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -2,12 +2,12 @@ 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 org.springframework.data.mongodb.config.EnableMongoAuditing;
import reactor.core.scheduler.Scheduler;
import reactor.core.scheduler.Schedulers;
@Configuration
@EnableJpaAuditing
@EnableMongoAuditing
public class CommonConfig {
private String ELASTIC_THREAD_POOL_NAME = "mobtools-elastic-pool";
@ -16,4 +16,5 @@ public class CommonConfig {
public Scheduler scheduler() {
return Schedulers.newElastic(ELASTIC_THREAD_POOL_NAME);
}
}

View File

@ -0,0 +1,27 @@
package com.mobtools.server.configurations;
import com.mongodb.reactivestreams.client.MongoClient;
import com.mongodb.reactivestreams.client.MongoClients;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories;
@EnableReactiveMongoRepositories
public class MongoConfig extends AbstractReactiveMongoConfiguration {
@Override
public MongoClient reactiveMongoClient() {
return MongoClients.create();
}
@Bean
public ReactiveMongoTemplate reactiveMongoTemplate() throws Exception {
return new ReactiveMongoTemplate(reactiveMongoClient(), "mobtools");
}
@Override
protected String getDatabaseName() {
return "mobtools";
}
}

View File

@ -38,9 +38,9 @@ public class WidgetController extends BaseController {
.map(widget -> new ResponseDto<>(HttpStatus.OK.value(), widget, null));
}
@PutMapping("")
public Mono<ResponseDto<Widget>> update(@RequestBody Widget widget) throws Exception {
return widgetService.update(widget)
@PutMapping("/{id}")
public Mono<ResponseDto<Widget>> update(@PathVariable String id, @RequestBody Widget widget) throws Exception {
return widgetService.update(id, widget)
.map(updatedWidget -> new ResponseDto<>(HttpStatus.OK.value(), updatedWidget, null));
}

View File

@ -3,45 +3,41 @@ package com.mobtools.server.domains;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
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 org.springframework.data.annotation.*;
import org.springframework.data.domain.Persistable;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
@EntityListeners(AuditingEntityListener.class)
@MappedSuperclass
@Getter
@Setter
@ToString
@DynamicUpdate
public abstract class BaseDomain implements Serializable {
public abstract class BaseDomain implements Persistable<String> {
private static final long serialVersionUID = 7459916000501322517L;
@Temporal(TemporalType.TIMESTAMP)
@Column(nullable = false, updatable = false)
@Id
private String id;
@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;
// @Version
// protected Long version;
@Override
public boolean isNew() {
return this.getId() == null;
}
}

View File

@ -4,20 +4,15 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.*;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@SequenceGenerator(initialValue = 1, name = "tenant_gen", sequenceName = "tenant_gen")
@Document
public class Tenant extends BaseDomain {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "tenant_gen")
@Column(nullable = false, updatable = false)
private Long id;
private String domain;

View File

@ -4,27 +4,17 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.*;
@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")
@Document
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

@ -4,30 +4,19 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.mongodb.core.mapping.Document;
import javax.persistence.*;
@Entity
@Getter
@Setter
@ToString
@NoArgsConstructor
@SequenceGenerator(initialValue = 1, name = "widget_gen", sequenceName = "widget_gen")
@Document
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

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

View File

@ -2,9 +2,10 @@ package com.mobtools.server.repositories;
import com.mobtools.server.domains.Widget;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Mono;
@Repository
public interface WidgetRepository extends BaseRepository<Widget, Long> {
Widget findByName(String name);
Mono<Widget> findByName(String name);
}

View File

@ -12,5 +12,5 @@ public interface WidgetService {
Mono<Widget> create(Widget widget);
Mono<Widget> update(Widget widget) throws Exception;
Mono<Widget> update(String id, Widget widget) throws Exception;
}

View File

@ -2,8 +2,15 @@ package com.mobtools.server.services;
import com.mobtools.server.domains.Widget;
import com.mobtools.server.repositories.WidgetRepository;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@ -15,40 +22,61 @@ public class WidgetServiceImpl extends BaseService implements WidgetService {
private WidgetRepository widgetRepository;
private final MongoConverter mongoConverter;
private final ReactiveMongoTemplate mongoTemplate;
@Autowired
public WidgetServiceImpl(Scheduler scheduler, WidgetRepository widgetRepository) {
public WidgetServiceImpl(Scheduler scheduler, WidgetRepository widgetRepository, MongoConverter mongoConverter, ReactiveMongoTemplate mongoTemplate) {
super(scheduler);
this.widgetRepository = widgetRepository;
this.mongoConverter = mongoConverter;
this.mongoTemplate = mongoTemplate;
}
@Override
public Mono<Widget> getByName(String name) {
return Mono.fromCallable(() -> widgetRepository.findByName(name))
.subscribeOn(scheduler);
return widgetRepository.findByName(name);
}
@Override
public Flux<Widget> get() {
return Mono.fromCallable(() -> widgetRepository.findAll())
.flatMapMany(Flux::fromIterable)
.subscribeOn(scheduler);
return widgetRepository.findAll();
}
@Override
public Mono<Widget> create(Widget widget) {
return Mono.fromCallable(
() -> widgetRepository.save(widget)
).subscribeOn(this.scheduler);
return widgetRepository.save(widget);
}
@Override
public Mono<Widget> update(Widget widget) throws Exception {
if(widget.getId() == null) {
public Mono<Widget> update(String id, Widget widget) throws Exception {
if (id == null) {
throw new Exception("Invalid id provided");
}
return Mono.fromCallable(
() -> widgetRepository.save(widget)
).subscribeOn(this.scheduler);
Query query = new Query();
query.addCriteria(Criteria.where("id").is(id));
Update updateObj = new Update();
// DBObject update = getDbObject(widget);
// Map<String, Object> updateMap = update.toMap();
// updateMap.entrySet().stream().forEach(entry -> {
// updateObj.set(entry.getKey(), entry.getValue());
// });
updateObj.set("name", "testName");
mongoTemplate.updateFirst(query,updateObj, Widget.class);
return widgetRepository.save(widget);
}
private DBObject getDbObject(Object o) {
BasicDBObject basicDBObject = new BasicDBObject();
mongoConverter.write(o, basicDBObject);
return basicDBObject;
}
}

View File

@ -14,3 +14,10 @@ spring.jpa.show-sql=true
# Jackson Properties
spring.jackson.default-property-inclusion=non_null
#Mongo properties
spring.data.mongodb.database=mobtools
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
#spring.data.mongodb.username=
#spring.data.mongodb.password=