简体   繁体   English

Spring WebFlux - 如何从数据库中获取值并设置此值以创建 object

[英]Spring WebFlux - how to get value from database and set this value to create object

I really don't know how to create an object with data from Cassandra without breaking my reactive chain?我真的不知道如何使用来自 Cassandra 的数据创建 object 而不会破坏我的反应链?

I have some private method that is part of the whole reactive chain:我有一些私有方法是整个反应链的一部分:

private Mono<SecurityData> createSecurityData(Security securityOfType) {
    return jobsProgressRepository
        .findByAgentId(securityOfType.getAgentId()) //Flux<JobsProgress>
        .collectList() //Mono<List<JobsProgress>>
        .flatMap(this::getJobsProgressSummary) //Mono<JobsProgressSummary>
        .flatMap(job -> mapToSecurityData(job, securityOfType));
  }

and then i want to prepare some object:然后我想准备一些object:

private Mono<SecurityData> mapToSecurityData(JobsProgressSummary job, Security security ) {
    SecurityData securityData = new SecurityData();
    securityData.setAgentId(security.getAgentId());
    securityData.setGroupId(security.getGroupId());
    securityData.setHostname(getHostname(security)); --> here is the problem!!!
    return Mono.just(securityData);
  }

And getHostname method:和 getHostname 方法:

 private String getHostname(Security security) {
    String hostname = "";
    switch(security.getProductType()){
      case VM: hostname = vmRepository
          .findByAgentId(security.getAgentId()).blockFirst().getHostname();
      case HYPER: hostname = hyperRepository
          .findByAgentId(security.getAgentId()).blockFirst().getHostname();
      default: ""
    }
    return hostname;
  }

My repos look like:我的回购看起来像:

public interface HostRepository extends ReactiveCassandraRepository<Host, MapId> {
  Flux<Host> findByAgentId(UUID agentId);
}

Maybe is my approach wrong?也许我的方法是错误的? I can't of course use我当然不能使用

hostRepository
            .findByAgentId(security.getAgentId()).subscribe() // or blockFirst()

because I don't want to break my reactive chain...因为我不想打破我的反应链......

How can I solve my problem?我该如何解决我的问题? Please don't hesitate to give any, even very small tips:)请不要犹豫,给任何,即使是很小的提示:)

UPDATE更新

Here I added the missing body of the method getJobsProgressSummary:在这里,我添加了方法 getJobsProgressSummary 的缺失部分:

private Mono<JobsProgressSummary> getJobsProgressSummary(List<JobsProgress> jobs) {
    JobsProgressSummary jobsProgressSummary = new JobsProgressSummary();
    jobs.forEach(
        job -> {
          if (job.getStatus().toUpperCase(Locale.ROOT).equals(StatusEnum.RUNNING.name())) {
            jobsProgressSummary.setRunningJobs(jobsProgressSummary.getRunningJobs() + 1);
          } else if (job.getStatus().toUpperCase(Locale.ROOT).equals(StatusEnum.FAILED.name())) {
            jobsProgressSummary.setAmountOfErrors(jobsProgressSummary.getAmountOfErrors() + 1);
          } else if (isScheduledJob(job.getStartTime())) {
            jobsProgressSummary.setScheduledJobs(jobsProgressSummary.getScheduledJobs() + 1);
          }
        });
    Instant lastActivity =
        jobs.stream()
            .map(JobsProgress::getStartTime)
            .map(startTime -> Instant.ofEpochMilli(Long.parseLong(startTime)))
            .max(Instant::compareTo)
            .orElseGet(null);
    jobsProgressSummary.setLastActivity(lastActivity);
    return Mono.just(jobsProgressSummary);
  }

You need to chain everything together, your code currently is like a mix of imperative and reactive.您需要将所有内容链接在一起,您的代码目前就像是命令式和反应式的混合体。 Also you should never need to call block.此外,您永远不需要调用 block。

Something like below should work像下面这样的东西应该工作

private Mono<SecurityData> mapToSecurityData(JobsProgressSummary job, Security security ) {
    //Try to get hostname first, then process result
    return getHostname(security)
            //Map it. Probz should use builder or all args constructor to reduce code here
            .map(hostname -> {
                SecurityData securityData = new SecurityData();
                securityData.setAgentId(security.getAgentId());
                securityData.setGroupId(security.getGroupId());
                securityData.setHostname(hostname);
                return securityData;
            });
}

private Mono<String> getHostname(Security security) {
    Mono<String> hostname = Mono.empty();
    switch(security.getProductType()){
        //Also assuming hostname is a field in Security
        //just change Security to class name if not
        case VM: hostname = vmRepository.findByAgentId(security.getAgentId())
            .next()
            .map(Security::getHostname);
        case HYPER: hostname = hyperRepository.findByAgentId(security.getAgentId())
            .next()
            .map(Security::getHostname);
    }
    return hostname;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Webflux - 如何在不使用 block() 操作的情况下从 Flux 中获取价值 - Spring Webflux - how to get value from Flux without block() operations 如何从 Spring WebFlux 反应式中的 ServerRequest 对象获取请求正文? - How to get request body from ServerRequest object in Spring WebFlux reactive? Spring Webflux:从 Mono 中提取值 - Spring Webflux: Extract value from Mono Spring Webflux - 如何从 Mono/Flux 中多次检索值,而无需多次调用以获取这些 Mono/Flux - Spring Webflux - how to retrieve value from Mono/Flux multiple times without making multiple calls to get those Mono/Flux Spring webflux和从数据库读取 - Spring webflux and reading from database 如何在不阻塞的情况下从 Spring Webflux 中的 Mono 对象中提取数据? - How to extract data from a Mono object in Spring Webflux without blocking? Spring WebFlux - 如何从数据库中获取数据以用于下一步 - Spring WebFlux - how to get data from DB to use in the next step 如何从Mono获取用户名 <user> 在春季启动webflux? - How to get username from mono<user> on spring boot webflux? Spring WebFlux。 从数据库(直接和通量运算符)获取数据有两种方法吗? 有什么区别? - Spring WebFlux. There are two ways to get data from database (direct and flux-operators)? What difference? Spring Webflux Controller:在反应链中获取原始请求 object - Spring Webflux Controller : Get original request object in reactive chain
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM