Skip to content

Commit 6100488

Browse files
authored
moved commons code to io.aiven.commons (#524)
Moved code in aiven-commons project into io.aiven.commons based packages
1 parent fb3a763 commit 6100488

File tree

10 files changed

+955
-954
lines changed

10 files changed

+955
-954
lines changed

commons/src/main/java/io/aiven/kafka/connect/common/utils/CasedString.java renamed to commons/src/main/java/io/aiven/commons/strings/CasedString.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
package io.aiven.kafka.connect.common.utils;
17+
package io.aiven.commons.strings;
1818

1919
import java.util.ArrayList;
2020
import java.util.Arrays;
Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
/*
2+
* Copyright 2024 Aiven Oy
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.aiven.commons.kafka.testkit;
18+
19+
import org.apache.kafka.connect.connector.Connector;
20+
import org.apache.kafka.connect.converters.ByteArrayConverter;
21+
import org.apache.kafka.connect.runtime.ConnectorConfig;
22+
import org.apache.kafka.connect.runtime.WorkerConfig;
23+
import org.apache.kafka.connect.util.clusters.EmbeddedConnectCluster;
24+
import org.apache.kafka.connect.util.clusters.WorkerHandle;
25+
import org.slf4j.Logger;
26+
import org.slf4j.LoggerFactory;
27+
28+
import java.io.IOException;
29+
import java.net.ServerSocket;
30+
import java.time.Duration;
31+
import java.util.Arrays;
32+
import java.util.HashMap;
33+
import java.util.List;
34+
import java.util.Map;
35+
import java.util.Properties;
36+
import java.util.Set;
37+
38+
/**
39+
* Runs an embedded connect cluster.
40+
*/
41+
public final class KafkaConnectRunner {
42+
/**
43+
* The logger
44+
*/
45+
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConnectRunner.class);
46+
47+
/**
48+
* The cluster
49+
*/
50+
private EmbeddedConnectCluster connectCluster;
51+
52+
/** The time between offset topic flushes */
53+
private final Duration offsetFlushInterval;
54+
55+
/** The container listener port */
56+
private int containerListenerPort;
57+
58+
/** The cluster name */
59+
private String clusterName;
60+
61+
/**
62+
* Finds 2 simultaneously free port for Kafka listeners
63+
*
64+
* @return list of 2 ports
65+
* @throws IOException
66+
* when port allocation failure happens
67+
*/
68+
static List<Integer> findListenerPorts() throws IOException {
69+
try (ServerSocket socket = new ServerSocket(0); ServerSocket socket2 = new ServerSocket(0)) {
70+
return Arrays.asList(socket.getLocalPort(), socket2.getLocalPort());
71+
} catch (IOException e) {
72+
throw new IOException("Failed to allocate port for test", e);
73+
}
74+
}
75+
76+
/**
77+
* Create a connect runner with the specified flush interval.
78+
*
79+
* @param offsetFlushInterval
80+
* The interval between flush calls to the offset topic.
81+
*/
82+
public KafkaConnectRunner(final Duration offsetFlushInterval) {
83+
this.offsetFlushInterval = offsetFlushInterval;
84+
}
85+
86+
/**
87+
* Gets the set of WorkerHandles in the cluster.
88+
*
89+
* @return a set of worker handles in the cluster.
90+
*/
91+
public Set<WorkerHandle> listWorkers() {
92+
return this.connectCluster.workers();
93+
}
94+
95+
/**
96+
* Gets the cluster name.
97+
*
98+
* @return the cluster name.
99+
*/
100+
public String getClusterName() {
101+
return clusterName;
102+
}
103+
104+
/**
105+
* Gets the offset topic name.
106+
*
107+
* @return the offset topic name.
108+
*/
109+
public String getOffsetTopic() {
110+
return "connect-offset-topic-" + clusterName;
111+
}
112+
113+
/**
114+
* Gets the configuration topic name.
115+
*
116+
* @return the configuration topic name.
117+
*/
118+
public String getConfigTopic() {
119+
return "connect-config-topic-" + clusterName;
120+
}
121+
122+
/**
123+
* Gets the storage topic name.
124+
*
125+
* @return the storage topic name.
126+
*/
127+
public String getStorageTopic() {
128+
return "connect-storage-topic-" + clusterName;
129+
}
130+
131+
/**
132+
* Gets the group ID.
133+
*
134+
* @return the group Id.
135+
*/
136+
public String getGroupId() {
137+
return "connect-integration-test-" + clusterName;
138+
}
139+
140+
/**
141+
* Starts a connect cluster.
142+
*
143+
* @param clusterName
144+
* the name for the cluster
145+
* @param connectorClass
146+
* the class for the connector.
147+
* @throws IOException
148+
* if listener ports can not be found.
149+
*/
150+
public void startConnectCluster(final String clusterName, final Class<? extends Connector> connectorClass)
151+
throws IOException {
152+
final List<Integer> ports = findListenerPorts();
153+
startConnectCluster(clusterName, ports.get(0), ports.get(1), connectorClass);
154+
}
155+
156+
/**
157+
* Starts a connect cluster
158+
*
159+
* @param clusterName
160+
* the name for the cluster
161+
* @param localPort
162+
* the local port for the server.
163+
* @param containerPort
164+
* the container port for the server.
165+
* @param connectorClass
166+
* the class for the connector.
167+
*/
168+
public void startConnectCluster(final String clusterName, final int localPort, final int containerPort,
169+
final Class<? extends Connector> connectorClass) {
170+
this.clusterName = clusterName;
171+
this.containerListenerPort = containerPort;
172+
final Properties brokerProperties = new Properties();
173+
brokerProperties.put("advertised.listeners", "PLAINTEXT://localhost:" + localPort
174+
+ ",TESTCONTAINERS://host.testcontainers.internal:" + containerPort);
175+
brokerProperties.put("listeners",
176+
"PLAINTEXT://localhost:" + localPort + ",TESTCONTAINERS://localhost:" + containerPort);
177+
brokerProperties.put("listener.security.protocol.map", "PLAINTEXT:PLAINTEXT,TESTCONTAINERS:PLAINTEXT");
178+
179+
connectCluster = new EmbeddedConnectCluster.Builder().name(clusterName).brokerProps(brokerProperties)
180+
.workerProps(getWorkerProperties(connectorClass)).numWorkers(1).build();
181+
connectCluster.start();
182+
LOGGER.info("connectCluster {} started", clusterName);
183+
}
184+
185+
/**
186+
* Gets the container port.
187+
*
188+
* @return the container port
189+
*/
190+
public int getContainerPort() {
191+
return containerListenerPort;
192+
}
193+
194+
/**
195+
* Gets the bootstrap server URL as a string.
196+
*
197+
* @return the bootstrap server URL as a string.
198+
*/
199+
public String getBootstrapServers() {
200+
return connectCluster.kafka().bootstrapServers();
201+
}
202+
203+
/**
204+
* Deletes a container.
205+
*
206+
* @param connectorName
207+
* the container to delete.
208+
*/
209+
public void deleteConnector(final String connectorName) {
210+
if (connectCluster.connectors().contains(connectorName)) {
211+
connectCluster.deleteConnector(connectorName);
212+
}
213+
}
214+
215+
/**
216+
* Stops the cluster.
217+
*/
218+
public void stopConnectCluster() {
219+
// stop all Connect, Kafka and Zk threads.
220+
if (connectCluster != null) {
221+
connectCluster.stop();
222+
}
223+
LOGGER.info("connectCluster stopped");
224+
}
225+
226+
/**
227+
* Configures a connector.
228+
*
229+
* @param connectorName
230+
* The name for the connector.
231+
* @param connectorConfig
232+
* the map of data items for the configuraiton of the connector.
233+
* @return the result of the cluster configuration call.
234+
*/
235+
public String configureConnector(final String connectorName, final Map<String, String> connectorConfig) {
236+
return connectCluster.configureConnector(connectorName, connectorConfig);
237+
}
238+
239+
/**
240+
* Pauses the named connector.
241+
*
242+
* @param connectorName
243+
* the connector to pause.
244+
*/
245+
public void pauseConnector(final String connectorName) {
246+
connectCluster.pauseConnector(connectorName);
247+
}
248+
249+
/**
250+
* Resumes the named connector.
251+
*
252+
* @param connectorName
253+
* the connector to resume.
254+
*/
255+
public void resumeConnector(final String connectorName) {
256+
connectCluster.resumeConnector(connectorName);
257+
}
258+
259+
/**
260+
* Restarts a connector.
261+
*
262+
* @param connectorName
263+
* the name of the connector to restart.
264+
*/
265+
public void restartConnector(final String connectorName) {
266+
if (connectCluster != null) {
267+
LOGGER.info("Restarting connector {}", connectorName);
268+
connectCluster.restartConnector(connectorName);
269+
LOGGER.info("Connector {} restarted", connectorName);
270+
271+
}
272+
}
273+
274+
/**
275+
* Get default worker properties. Sets the connector properties as follows:
276+
* <ul>
277+
* <li>key converter = ByteArrayConverter</li>
278+
* <li>value converter = ByteArrayConverter</li>
279+
* <li>plugin discovery = HYBRID_WARN</li>
280+
* <li>offset flush interval = interval defined in this class constructor.</li>
281+
* <li>connector class = connector class (if not {@code null}</li>
282+
* </ul>
283+
*
284+
* @param connectorClass
285+
* the connector class to start, may be {@code null}.
286+
* @return the default set of worker properties.
287+
*/
288+
public Map<String, String> getWorkerProperties(final Class<? extends Connector> connectorClass) {
289+
Map<String, String> workerProperties = new HashMap<>();
290+
workerProperties.put(ConnectorConfig.KEY_CONVERTER_CLASS_CONFIG, ByteArrayConverter.class.getName());
291+
workerProperties.put(ConnectorConfig.VALUE_CONVERTER_CLASS_CONFIG, ByteArrayConverter.class.getCanonicalName());
292+
workerProperties.put(WorkerConfig.OFFSET_COMMIT_INTERVAL_MS_CONFIG,
293+
Long.toString(offsetFlushInterval.toMillis()));
294+
workerProperties.put("plugin.discovery", "HYBRID_WARN");
295+
296+
if (connectorClass != null) {
297+
workerProperties.put(ConnectorConfig.CONNECTOR_CLASS_CONFIG, connectorClass.getName());
298+
}
299+
return workerProperties;
300+
}
301+
}

0 commit comments

Comments
 (0)