Concatenating two asynchronous operation in Quarkus

62 Views Asked by At

I’m working for the first time with reactive programming using Mutiny in Quarkus. I want to write a rest API that read asynchronously a file (Romance.txt), apply some transformation on it, and write the transformed text in a new file (RomanceSigned.txt) asynchronously.

The code I wrote is the following:

@ApplicationScoped
public class ReactiveService {
    
    @Inject
    Vertx vertx;


    public Uni<Buffer> readFile () {
        
        String fileName = new String("src/main/resources/Romance.txt");

        Uni<Buffer> textReaded = 
            vertx.fileSystem().readFile(fileName);

        textReaded.onItem()
            .transform(item -> modifyText(item))
            .subscribe()
                .with(item -> writeRomanceOnNewFile(item));


        return textReaded;

    }


    private Buffer modifyText (Buffer buffer) {

        byte[] byteText = buffer.getBytes();
        String stringText = new String(byteText);
        String upperCaseStringText = stringText.toUpperCase();
        String textModifiedAndSigned = upperCaseStringText.concat(" Hello World");
        return Buffer.buffer(textModifiedAndSigned);

    }


    private void writeRomanceOnNewFile (Buffer item) {
        
        vertx.fileSystem()
            .writeFile("src/main/resources/RomanceSigned.txt", item)
            .subscribe()
                .with(it -> System.out.println("File Written!"));

    }


}

My questions are:

  1. Is the previous code the correct way to concatenate two asynchronous operation (read file - write file)?
  2. What kind of changes I have to make to the previous code if I want to return RomanceSigned.txt file instead of Romance.txt as the code did?
1

There are 1 best solutions below

2
jponge On BEST ANSWER

(Mutiny maintainer here)

You should let Quarkus perform the subscriptions for you, and just compose the asynchronous operations with Mutiny.

I haven't tested, but it should probably look like:

@ApplicationScoped
public class ReactiveService {

  @Inject
  Vertx vertx;


  public Uni<Buffer> readFile() {

    String fileName = new String("src/main/resources/Romance.txt");

    Uni<Buffer> textReaded =
      vertx.fileSystem().readFile(fileName);

    return textReaded
      .onItem().transform(item -> modifyText(item))
      .onItem().transformToUni(buffer -> writeRomanceOnNewFile(buffer).replaceWith(buffer));
  }

  private Buffer modifyText(Buffer buffer) {
    byte[] byteText = buffer.getBytes();
    String stringText = new String(byteText);
    String upperCaseStringText = stringText.toUpperCase();
    String textModifiedAndSigned = upperCaseStringText.concat(" Hello World");
    return Buffer.buffer(textModifiedAndSigned);
  }

  private Uni<Void> writeRomanceOnNewFile(Buffer item) {
    return vertx
      .fileSystem()
      .writeFile("src/main/resources/RomanceSigned.txt", item);
  }
}

I assume you want to read the content, write to the other file, but return the read content in the end.

Hope it helps