All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
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.
org.apache.camel.component.pg.replication.slot.PgReplicationSlotEndpoint Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.camel.component.pg.replication.slot;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.camel.Category;
import org.apache.camel.Component;
import org.apache.camel.Consumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.ScheduledPollEndpoint;
import org.postgresql.PGProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Poll for PostgreSQL Write-Ahead Log (WAL) records using Streaming Replication Slots.
*/
@UriEndpoint(firstVersion = "3.0.0", scheme = "pg-replication-slot", title = "PostgresSQL Replication Slot",
syntax = "pg-replication-slot:host:port/database/slot:outputPlugin",
category = { Category.DATABASE }, consumerOnly = true)
public class PgReplicationSlotEndpoint extends ScheduledPollEndpoint {
private static final Logger LOG = LoggerFactory.getLogger(PgReplicationSlotEndpoint.class);
private static final Pattern URI_PATTERN = Pattern.compile(
"^pg-replication-slot:(//)?(?[^:]*):?(?\\d*)?/(?\\w+)/(?\\w+):(?\\w+).*$");
@UriPath(description = "Postgres host", label = "common", defaultValue = "localhost")
private String host = "localhost";
@UriPath(description = "Postgres port", label = "common", defaultValue = "5432")
private Integer port = 5432;
@UriPath(description = "Postgres database name", label = "common")
@Metadata(required = true)
private String database;
@UriPath
@Metadata(description = "Replication Slot name", label = "common", required = true)
private String slot;
@UriPath
@Metadata(description = "Output plugin name", label = "common", required = true)
private String outputPlugin;
@UriParam(description = "Postgres user", label = "common", defaultValue = "postgres")
private String user = "postgres";
@UriParam(description = "Postgres password", label = "common", secret = true)
private String password;
@UriParam(label = "advanced", defaultValue = "10")
private Integer statusInterval = 10;
@UriParam(label = "advanced", prefix = "slotOptions.", multiValue = true)
private Map slotOptions = Collections.emptyMap();
@UriParam(label = "advanced", defaultValue = "true")
private Boolean autoCreateSlot = true;
public PgReplicationSlotEndpoint(String uri, Component component) {
super(uri, component);
parseUri(uri);
}
@Override
public Producer createProducer() throws Exception {
throw new UnsupportedOperationException("Producer not supported");
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
PgReplicationSlotConsumer consumer = new PgReplicationSlotConsumer(this, processor);
configureConsumer(consumer);
return consumer;
}
/**
* Creates a new PostgreSQL JDBC connection that's setup for replication.
*/
Connection newDbConnection() throws SQLException {
Properties props = new Properties();
PGProperty.USER.set(props, this.getUser());
PGProperty.PASSWORD.set(props, this.getPassword());
PGProperty.ASSUME_MIN_SERVER_VERSION.set(props, "9.6");
PGProperty.REPLICATION.set(props, "database");
PGProperty.PREFER_QUERY_MODE.set(props, "simple");
PGProperty.TCP_KEEP_ALIVE.set(props, true);
return DriverManager.getConnection(
String.format("jdbc:postgresql://%s:%d/%s", this.getHost(), this.getPort(), this.getDatabase()),
props);
}
/**
* Parse the provided URI and extract available parameters
*
* @throws IllegalArgumentException if there is an error in the parameters
*/
protected final void parseUri(String uri) {
LOG.debug("URI: {}", uri);
Matcher matcher = URI_PATTERN.matcher(uri);
if (!matcher.matches()) {
throw new IllegalArgumentException("The provided URL does not match the acceptable pattern");
}
if (matcher.group("host").length() > 0) {
this.setHost(matcher.group("host"));
}
if (matcher.group("port").length() > 0) {
this.setPort(Integer.valueOf(matcher.group("port")));
}
this.setDatabase(matcher.group("database"));
this.setSlot(matcher.group("slot"));
this.setOutputPlugin(matcher.group("plugin"));
}
public String getHost() {
return host;
}
/**
* PostgreSQL server host
*/
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
/**
* PostgreSQL server port
*/
public void setPort(Integer port) {
this.port = port;
}
public String getDatabase() {
return database;
}
/**
* PostgreSQL database name
*/
public void setDatabase(String database) {
this.database = database;
}
public String getSlot() {
return slot;
}
/**
* Replication slot name.
*/
public void setSlot(String slot) {
this.slot = slot;
}
public String getOutputPlugin() {
return outputPlugin;
}
/**
* Output plugin name (e.g. test_decoding, wal2json)
*/
public void setOutputPlugin(String outputPlugin) {
this.outputPlugin = outputPlugin;
}
public String getUser() {
return user;
}
/**
* PostgreSQL username
*/
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
/**
* PostgreSQL password
*/
public void setPassword(String password) {
this.password = password;
}
public Integer getStatusInterval() {
return statusInterval;
}
/**
* Specifies the number of seconds between status packets sent back to Postgres server.
*/
public void setStatusInterval(Integer statusInterval) {
this.statusInterval = statusInterval;
}
public Map getSlotOptions() {
return slotOptions;
}
/**
* Slot options to be passed to the output plugin.
*/
public void setSlotOptions(Map slotOptions) {
this.slotOptions = slotOptions;
}
public Boolean getAutoCreateSlot() {
return autoCreateSlot;
}
/**
* Auto create slot if it does not exist
*/
public void setAutoCreateSlot(Boolean autoCreateSlot) {
this.autoCreateSlot = autoCreateSlot;
}
}