Search code examples
javaconcatenationoutputstreammutinysmallrye

How to concatenate 2 different types of streams using Smallrye Mutiny Multi?


I would like to concatenate 2 OutputStream of different types using the method Multi.createBy().concatenating().streams. Is there a way to achieve this?

I have 2 streams one is of ByteArrayOutputStream and other is of custom type CustomerEvent and I would like to concatenate them using the SmallRye Mutiny. Is there a way to achieve this?

public class CustomerGenerator {

    private ByteArrayOutputStream jsonOutput;
    private JsonGenerator jsonGenerator;

    private CustomerGenerator() {
        try {
            jsonOutput = new ByteArrayOutputStream();
            jsonGenerator = new JsonFactory().createGenerator(jsonOutput).useDefaultPrettyPrinter();
        } catch (IOException ex) {
            throw new CustomerGeneratorException("Exception occurred during the generation of customer document : " + ex);
        }
    }

    public Multi < Customer > generateCustomer(final Input input) {
        try {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("type", "customerDocument");
            jsonGenerator.writeStringField("creationDate", Instant.now().toString());
            jsonGenerator.writeFieldName("customerBody");
            jsonGenerator.writeStartObject();
            jsonGenerator.writeFieldName("customerList");
            jsonGenerator.writeEndObject(); // End body
            jsonGenerator.writeEndObject(); // End whole json file

            Multi < ByteArrayOutputStream > jsonWrapper = Multi.createFrom().item(jsonOutput);
            return Multi.createBy().concatenating().streams(jsonWrapper, Multi.createFrom().publisher(new CustomerPublisher(input))));
    } catch (IOException ex) {
        throw new CustomerGeneratorException("Exception occurred during customer document wrapper creation : " + ex);
    }
}
}

As you can see from the code sample, I would like to concatenate the generated JSON to my other JSON of type Customer. Is there a way to achieve this?

Multi < ByteArrayOutputStream > jsonWrapper = Multi.createFrom().item(jsonOutput);
return Multi.createBy().concatenating().streams(jsonWrapper, Multi.createFrom().publisher(new CustomerPublisher(input))));

Solution

  • Both Multi have to return a Multi<Customer> if you want to concatenate them.

    Looking at your code, it seems that what you need to do is to convert the json into a Customer (or collection of Customer) and then convert it to a Multi. I don't know how you convert the JSON to a Customer, assuming you have a function convertToCustomer, this is how the code should look like:

    Multi<Customer> customerMulti = Multi.createFrom().item( convertToCustomer(jsonGenerator)) 
    Multi<Customer> customersPublisher = Multi.createFrom().publisher(new CustomerPublisher(input));
    
    // Now you can concatenate the two
    Multi<Customer> result =  Multi.createBy().concatenating()
                                   .streams(customerMulti, customersPublisher);
    

    Alternatively, your method could return a Multi<Object>. But I suspect this is not what you need.