All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hazelcast.jet.pipeline.JmsSinkBuilder Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.hazelcast.jet.pipeline;

import com.hazelcast.function.BiFunctionEx;
import com.hazelcast.function.FunctionEx;
import com.hazelcast.function.SupplierEx;
import com.hazelcast.jet.config.JobConfig;
import com.hazelcast.jet.config.ProcessingGuarantee;
import com.hazelcast.jet.impl.connector.WriteJmsP;
import jakarta.jms.Connection;
import jakarta.jms.ConnectionFactory;
import jakarta.jms.Message;
import jakarta.jms.Session;
import jakarta.jms.XAConnectionFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static com.hazelcast.internal.util.Preconditions.checkNotNull;
import static com.hazelcast.jet.impl.util.Util.checkSerializable;

/**
 * See {@link Sinks#jmsQueueBuilder} or {@link Sinks#jmsTopicBuilder}.
 *
 * @param  type of the items the sink accepts
 *
 * @since Jet 3.0
 */
public final class JmsSinkBuilder {

    private final SupplierEx factorySupplier;
    private final boolean isTopic;

    private boolean exactlyOnce = true;
    private FunctionEx connectionFn;
    private BiFunctionEx messageFn;

    private String username;
    private String password;
    private String destinationName;

    /**
     * Use {@link Sinks#jmsQueueBuilder} or {@link Sinks#jmsTopicBuilder}.
     */
    JmsSinkBuilder(@Nonnull SupplierEx factorySupplier, boolean isTopic) {
        checkSerializable(factorySupplier, "factorySupplier");
        this.factorySupplier = factorySupplier;
        this.isTopic = isTopic;
    }

    /**
     * Sets the connection parameters. If {@code connectionFn} is provided, these
     * parameters are ignored.
     *
     * @param username   the username, Default value is {@code null}
     * @param password   the password, Default value is {@code null}
     */
    @Nonnull
    public JmsSinkBuilder connectionParams(@Nullable String username, @Nullable String password) {
        this.username = username;
        this.password = password;
        return this;
    }

    /**
     * Sets the function which creates a connection given a connection factory.
     * 

* If not provided, the following will be used: *

{@code
     *     if (factory instanceof XAConnectionFactory) {
     *         XAConnectionFactory xaFactory = (XAConnectionFactory) factory;
     *         return usernameLocal != null || passwordLocal != null
     *                 ? xaFactory.createXAConnection(usernameLocal, passwordLocal)
     *                 : xaFactory.createXAConnection();
     *     } else {
     *         return usernameLocal != null || passwordLocal != null
     *                 ? factory.createConnection(usernameLocal, passwordLocal)
     *                 : factory.createConnection();
     *     }
     * }
* * The given function must be stateless. */ @Nonnull public JmsSinkBuilder connectionFn(@Nullable FunctionEx connectionFn) { checkSerializable(connectionFn, "connectionFn"); this.connectionFn = connectionFn; return this; } /** * Sets the name of the destination. */ @Nonnull public JmsSinkBuilder destinationName(@Nonnull String destinationName) { this.destinationName = destinationName; return this; } /** * Sets the function which creates the message from the item. *

* If not provided, the builder creates a function which wraps {@code * item.toString()} into a {@link jakarta.jms.TextMessage}, unless the item * is already an instance of {@code javax.jms.Message}. *

* The given function must be stateless. */ @Nonnull public JmsSinkBuilder messageFn(@Nullable BiFunctionEx messageFn) { checkSerializable(messageFn, "messageFn"); this.messageFn = messageFn; return this; } /** * Enables or disables the exactly-once behavior of the sink using * two-phase commit of state snapshots. If enabled, the {@linkplain * JobConfig#setProcessingGuarantee(ProcessingGuarantee) processing * guarantee} of the job must be set to {@linkplain * ProcessingGuarantee#EXACTLY_ONCE exactly-once}, otherwise the sink's * guarantee will match that of the job. In other words, sink's * guarantee cannot be higher than job's, but can be lower to avoid the * additional overhead. * *

The default value is true. * * @param enable If true, sink's guarantee will match the job * guarantee. If false, sink's guarantee will be at-least-once * even if job's is exactly-once * @return this instance for fluent API */ @Nonnull public JmsSinkBuilder exactlyOnce(boolean enable) { this.exactlyOnce = enable; return this; } /** * Creates and returns the JMS {@link Sink} with the supplied components. */ @Nonnull public Sink build() { String usernameLocal = username; String passwordLocal = password; checkNotNull(destinationName); if (connectionFn == null) { connectionFn = factory -> { if (factory instanceof XAConnectionFactory xaFactory) { return usernameLocal != null || passwordLocal != null ? xaFactory.createXAConnection(usernameLocal, passwordLocal) : xaFactory.createXAConnection(); } else { return usernameLocal != null || passwordLocal != null ? factory.createConnection(usernameLocal, passwordLocal) : factory.createConnection(); } }; } if (messageFn == null) { messageFn = (session, item) -> item instanceof Message m ? m : session.createTextMessage(item.toString()); } FunctionEx connectionFnLocal = connectionFn; @SuppressWarnings("UnnecessaryLocalVariable") // it's necessary to not capture this in the lambda SupplierEx factorySupplierLocal = factorySupplier; SupplierEx newConnectionFn = () -> connectionFnLocal.apply(factorySupplierLocal.get()); return Sinks.fromProcessor(sinkName(), WriteJmsP.supplier(destinationName, exactlyOnce, newConnectionFn, messageFn, isTopic)); } private String sinkName() { return String.format("jms%sSink(%s)", isTopic ? "Topic" : "Queue", destinationName); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy