Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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 org.apache.flink.streaming.connectors.pulsar.table;
import org.apache.flink.configuration.ConfigOption;
import org.apache.flink.configuration.ConfigOptions;
import org.apache.flink.configuration.ReadableConfig;
import org.apache.flink.streaming.connectors.pulsar.config.StartupMode;
import org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions;
import org.apache.flink.streaming.connectors.pulsar.util.KeyHashMessageRouterImpl;
import org.apache.flink.table.api.TableException;
import org.apache.flink.table.api.ValidationException;
import org.apache.flink.table.descriptors.PulsarValidator;
import org.apache.flink.table.types.DataType;
import org.apache.flink.table.types.logical.LogicalType;
import org.apache.flink.table.types.logical.LogicalTypeRoot;
import org.apache.flink.table.types.logical.utils.LogicalTypeChecks;
import org.apache.flink.util.ExceptionUtils;
import org.apache.flink.util.FlinkException;
import org.apache.flink.util.InstantiationUtil;
import org.apache.flink.util.Preconditions;
import org.apache.flink.shaded.guava18.com.google.common.base.CaseFormat;
import lombok.EqualsAndHashCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.client.api.MessageId;
import org.apache.pulsar.client.api.MessageRouter;
import org.apache.pulsar.client.impl.MessageIdImpl;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.stream.IntStream;
import static org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions.ADMIN_URL_OPTION_KEY;
import static org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions.PULSAR_OPTION_KEY_PREFIX;
import static org.apache.flink.streaming.connectors.pulsar.internal.PulsarOptions.SERVICE_URL_OPTION_KEY;
import static org.apache.flink.streaming.connectors.pulsar.table.PulsarSinkSemantic.AT_LEAST_ONCE;
import static org.apache.flink.streaming.connectors.pulsar.table.PulsarSinkSemantic.EXACTLY_ONCE;
import static org.apache.flink.streaming.connectors.pulsar.table.PulsarSinkSemantic.NONE;
import static org.apache.flink.table.factories.FactoryUtil.FORMAT;
import static org.apache.flink.table.types.logical.utils.LogicalTypeChecks.hasRoot;
/**
* Option utils for pulsar table source sink.
*/
@Slf4j
public class PulsarTableOptions {
// --------------------------------------------------------------------------------------------
// Format options
// --------------------------------------------------------------------------------------------
public static final ConfigOption KEY_FORMAT = ConfigOptions
.key("key." + FORMAT.key())
.stringType()
.noDefaultValue()
.withDescription("Defines the format identifier for encoding key data. "
+ "The identifier is used to discover a suitable format factory.");
public static final ConfigOption VALUE_FORMAT = ConfigOptions
.key("value." + FORMAT.key())
.stringType()
.noDefaultValue()
.withFallbackKeys(FORMAT.key())
.withDescription("Defines the format identifier for encoding value data. "
+ "The identifier is used to discover a suitable format factory.");
public static final ConfigOption> KEY_FIELDS = ConfigOptions
.key("key.fields")
.stringType()
.asList()
.defaultValues()
.withDescription("Defines an explicit list of physical columns from the table schema "
+ "that configure the data type for the key format. By default, this list is "
+ "empty and thus a key is undefined.");
public static final ConfigOption VALUE_FIELDS_INCLUDE = ConfigOptions
.key("value.fields-include")
.enumType(ValueFieldsStrategy.class)
.defaultValue(ValueFieldsStrategy.ALL)
.withDescription("Defines a strategy how to deal with key columns in the data type of "
+ "the value format. By default, '" + ValueFieldsStrategy.ALL + "' physical "
+ "columns of the table schema will be included in the value format which "
+ "means that key columns appear in the data type for both the key and value "
+ "format.");
public static final ConfigOption KEY_FIELDS_PREFIX = ConfigOptions
.key("key.fields-prefix")
.stringType()
.noDefaultValue()
.withDescription("Defines a custom prefix for all fields of the key format to avoid "
+ "name clashes with fields of the value format. By default, the prefix is empty. "
+ "If a custom prefix is defined, both the table schema and "
+ "'" + KEY_FIELDS.key() + "' will work with prefixed names. When constructing "
+ "the data type of the key format, the prefix will be removed and the "
+ "non-prefixed names will be used within the key format. Please note that this "
+ "option requires that '" + VALUE_FIELDS_INCLUDE.key() + "' must be '"
+ ValueFieldsStrategy.EXCEPT_KEY + "'.");
// --------------------------------------------------------------------------------------------
// Pulsar specific options
// --------------------------------------------------------------------------------------------
public static final ConfigOption SERVICE_URL = ConfigOptions
.key(SERVICE_URL_OPTION_KEY)
.stringType()
.noDefaultValue()
.withDescription("Required pulsar server connection string");
public static final ConfigOption ADMIN_URL = ConfigOptions
.key(ADMIN_URL_OPTION_KEY)
.stringType()
.noDefaultValue()
.withDescription("Required pulsar admin connection string");
public static final ConfigOption GENERIC = ConfigOptions
.key(PulsarOptions.GENERIC)
.booleanType()
.defaultValue(false)
.withDescription("Indicate if the table is a generic flink table");
// --------------------------------------------------------------------------------------------
// Scan specific options
// --------------------------------------------------------------------------------------------
public static final ConfigOption> TOPIC = ConfigOptions
.key("topic")
.stringType()
.asList()
.noDefaultValue()
.withDescription(
"Topic names from which the table is read. Either 'topic' or 'topic-pattern' must be set for source. " +
"Option 'topic' is required for sink.");
public static final ConfigOption TOPIC_PATTERN = ConfigOptions
.key("topic-pattern")
.stringType()
.noDefaultValue()
.withDescription(
"Optional topic pattern from which the table is read for source. Either 'topic' or 'topic-pattern' must be set.");
public static final ConfigOption SCAN_STARTUP_MODE = ConfigOptions
.key("scan.startup.mode")
.stringType()
.defaultValue("latest")
.withDescription("Optional startup mode for Pulsar consumer, valid enumerations are "
+ "\"earliest\", \"latest\", \"external-subscription\",\n"
+ "or \"specific-offsets\"");
public static final ConfigOption SCAN_STARTUP_SPECIFIC_OFFSETS = ConfigOptions
.key("scan.startup.specific-offsets")
.stringType()
.noDefaultValue()
.withDescription("Optional offsets used in case of \"specific-offsets\" startup mode");
public static final ConfigOption SCAN_STARTUP_SUB_NAME = ConfigOptions
.key("scan.startup.sub-name")
.stringType()
.noDefaultValue()
.withDescription("Optional sub-name used in case of \"external-subscription\" startup mode");
public static final ConfigOption SCAN_STARTUP_SUB_START_OFFSET = ConfigOptions
.key("scan.startup.sub-start-offset")
.stringType()
.defaultValue("latest")
.withDescription("Optional sub-start-offset used in case of \"external-subscription\" startup mode");
public static final ConfigOption SCAN_STARTUP_TIMESTAMP_MILLIS = ConfigOptions
.key("scan.startup.timestamp-millis")
.longType()
.noDefaultValue()
.withDescription("Optional timestamp used in case of \"timestamp\" startup mode");
public static final ConfigOption PARTITION_DISCOVERY_INTERVAL_MILLIS = ConfigOptions
.key("partition.discovery.interval-millis")
.longType()
.noDefaultValue()
.withDescription("Optional discovery topic interval of \"interval-millis\" millis");
// --------------------------------------------------------------------------------------------
// Sink specific options
// --------------------------------------------------------------------------------------------
public static final ConfigOption SINK_MESSAGE_ROUTER = ConfigOptions
.key("sink.message-router")
.stringType()
.noDefaultValue()
.withDescription("Optional output MessageRouter \n"
+ "into pulsar's partitions valid enumerations are\n"
+ "\"key-hash\": (each Flink partition ends up in at most one pulsar partition by key'hash, must set key for message),\n"
+ "\"round-robin\": (a Flink partition is distributed to pulsar partitions round-robin, it's default messageRouter in pulsar)\n"
+ "\"custom class name\": (use a custom MessageRouter subclass)");
public static final ConfigOption SINK_SEMANTIC = ConfigOptions.key("sink.semantic")
.stringType()
.defaultValue("at-least-once")
.withDescription(
"Optional semantic when commit. Valid enumerationns are [\"at-least-once\", \"exactly-once\", \"none\"]");
public static final ConfigOption