/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.api.util; import static org.mule.runtime.core.api.rx.Exceptions.rxExceptionToMuleException; import static reactor.core.Exceptions.unwrap; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.api.message.Message; import org.mule.runtime.api.streaming.Cursor; import org.mule.runtime.api.streaming.CursorProvider; import org.mule.runtime.api.util.Reference; import org.mule.runtime.core.api.Event; import org.mule.runtime.core.util.func.CheckedFunction; /** * Utilities for handling {@link Cursor} instances * * @since 4.0 */ public final class StreamingUtils { /** * Executes the given function {@code f} considering that the given {@code event} might have * a {@link CursorProvider} as payload. In that case, this method obtains a cursor from the provider * and executes the function. * <p> * Closing the opened cursor, handling exceptions and return values are all taken care of by this utility * method. * * @param event an {@link Event} * @param f the function to execute * @return the output {@link Event} * @throws MuleException */ public static Event withCursoredEvent(Event event, CheckedFunction<Event, Event> f) throws MuleException { if (event.getMessage().getPayload() == null) { return event; } Reference<Throwable> exception = new Reference<>(); CheckedFunction<Event, Event> function = new CheckedFunction<Event, Event>() { @Override public Event applyChecked(Event event) throws Throwable { return f.apply(event); } @Override public Event handleException(Throwable throwable) { exception.set(unwrap(throwable)); return null; } }; Object payload = event.getMessage().getPayload().getValue(); CursorProvider cursorProvider = null; Cursor cursor = null; try { if (payload instanceof CursorProvider) { cursorProvider = (CursorProvider) payload; cursor = cursorProvider.openCursor(); event = replacePayload(event, cursor); } Event value = function.apply(event); if (value == null) { handlePossibleException(exception); } else if (value.getMessage().getPayload().getValue() == cursor) { value = replacePayload(value, cursorProvider); } return value; } finally { if (cursor != null) { cursor.release(); } } } private static Event replacePayload(Event event, Object newPayload) { return Event.builder(event) .message(Message.builder(event.getMessage()) .payload(newPayload) .build()) .build(); } private static void handlePossibleException(Reference<Throwable> exception) throws MuleException { Throwable t = exception.get(); if (t != null) { throw rxExceptionToMuleException(t); } } private StreamingUtils() {} }