The create tenant flow is completely reactive. This was done because the earstwhile implementation was erroneous leading to unpredictable crashes.

This commit is contained in:
Trisha Anand 2019-07-28 04:46:53 +00:00 committed by Arpit Mohan
parent 00a588cbc5
commit ae0fd72d48
4 changed files with 38 additions and 31 deletions

View File

@ -2,12 +2,14 @@ package com.mobtools.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import reactor.core.publisher.Hooks;
@SpringBootApplication
public class ServerApplication {
public static void main(String[] args) {
SpringApplication.run(ServerApplication.class, args);
Hooks.onOperatorDebug();
}
}

View File

@ -28,6 +28,7 @@ public class SecurityConfig {
/**
* This configuration enables CORS requests for the most common HTTP Methods
*
* @return
*/
@Bean

View File

@ -2,15 +2,10 @@ package com.mobtools.server.controllers;
import com.mobtools.server.constants.Url;
import com.mobtools.server.domains.Tenant;
import com.mobtools.server.dtos.ResponseDto;
import com.mobtools.server.services.TenantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
@RequestMapping(Url.TENANT_URL)
@ -22,10 +17,4 @@ public class TenantController extends BaseController<TenantService, Tenant, Stri
super(tenantService);
}
@GetMapping("/{name}")
public Mono<ResponseDto<Tenant>> getByName(@PathVariable String name) {
return service.getByName(name)
.map(widget -> new ResponseDto<>(HttpStatus.OK.value(), widget, null));
}
}

View File

@ -13,8 +13,8 @@ import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Scheduler;
import javax.validation.constraints.NotNull;
import java.util.stream.Stream;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
@ -39,29 +39,44 @@ public class TenantServiceImpl extends BaseService<TenantRepository, Tenant, Str
return repository.findByName(name);
}
/*
* Create needs to first fetch and embed Setting in TenantSetting
* for the settings that have diverged from the default. Once the
* settings has been embedded in all the tenant settings, the library
* function is called to store the enhanced tenant object.
*/
@Override
public Mono<Tenant> create(@NotNull Tenant tenant) {
//Embed the setting object into tenantSetting. This is done only for settings for which the values deviate from the default.
//It is assumed that the tenant create API body would only contain the settings for which the default value and
//true value are different.
if (tenant.getTenantSettings() != null) {
try (Stream<TenantSetting> stream = tenant.getTenantSettings().stream()) {
Flux<TenantSetting> tenantSettingFlux = Flux.fromStream(stream);
tenantSettingFlux.map(this::getAndStoreSettingObjectInTenantSetting).subscribe();
}
}
return repository.save(tenant);
public Mono<Tenant> create(Tenant tenant) {
return Mono.just(tenant)
//transform the tenant data to embed setting object in each object in tenantSetting list.
.flatMap(this::enhanceTenantSettingList)
//Call the library function to save the updated tenant
.flatMap(tenantUpdated -> repository.save(tenantUpdated))
.subscribeOn(scheduler);
}
private Object getAndStoreSettingObjectInTenantSetting(TenantSetting tenantSetting) {
private Mono<Tenant> enhanceTenantSettingList(Tenant tenant) {
if (tenant.getTenantSettings() == null) tenant.setTenantSettings(new ArrayList<>());
Flux<TenantSetting> tenantSettingFlux = Flux.fromIterable(tenant.getTenantSettings());
// For each tenant setting, fetch and embed the setting, and once all the tenant setting are done, collect it
// back into a single list of tenant settings.
Mono<List<TenantSetting>> listMono = tenantSettingFlux.flatMap(this::fetchAndEmbedSetting).collectList();
return listMono.map(list -> {
tenant.setTenantSettings(list);
return list;
}).thenReturn(tenant);
}
private Mono<TenantSetting> fetchAndEmbedSetting(TenantSetting tenantSetting) {
String key = tenantSetting.getSetting().getKey();
Mono<Setting> setting = settingService.getByKey(key);
return setting.doOnNext(set -> tenantSetting.setSetting(set))
.thenReturn(tenantSetting)
.subscribe();
return setting.map(setting1 -> {
tenantSetting.setSetting(setting1);
return tenantSetting;
});
}
}