This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git
The following commit(s) were added to refs/heads/dev by this push:
new f6ed9579c5 [Improve][Connector-V2] Add nonblank validation for
required Slack options (#12178)
f6ed9579c5 is described below
commit f6ed9579c5e7f94e486e900b53d703ed2f5fa04b
Author: Supidan <[email protected]>
AuthorDate: Tue Sep 8 05:33:25 2026 +0000
[Improve][Connector-V2] Add nonblank validation for required Slack options
(#12178)
Co-authored-by: Supidan <[email protected]>
---
.../seatunnel/slack/sink/SlackSinkFactory.java | 9 +-
.../seatunnel/slack/SlackFactoryTest.java | 31 -------
.../seatunnel/slack/sink/SlackFactoryTest.java | 96 ++++++++++++++++++++++
3 files changed, 101 insertions(+), 35 deletions(-)
diff --git
a/seatunnel-connectors-v2/connector-slack/src/main/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackSinkFactory.java
b/seatunnel-connectors-v2/connector-slack/src/main/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackSinkFactory.java
index 4fbe80562e..8dafb6ef3b 100644
---
a/seatunnel-connectors-v2/connector-slack/src/main/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackSinkFactory.java
+++
b/seatunnel-connectors-v2/connector-slack/src/main/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackSinkFactory.java
@@ -26,6 +26,8 @@ import
org.apache.seatunnel.connectors.seatunnel.slack.config.SlackSinkOptions;
import com.google.auto.service.AutoService;
+import static org.apache.seatunnel.api.configuration.util.Conditions.notBlank;
+
@AutoService(Factory.class)
public class SlackSinkFactory implements TableSinkFactory {
@Override
@@ -36,10 +38,9 @@ public class SlackSinkFactory implements TableSinkFactory {
@Override
public OptionRule optionRule() {
return OptionRule.builder()
- .required(
- SlackSinkOptions.WEBHOOKS_URL,
- SlackSinkOptions.OAUTH_TOKEN,
- SlackSinkOptions.SLACK_CHANNEL)
+ .required(SlackSinkOptions.WEBHOOKS_URL,
notBlank(SlackSinkOptions.WEBHOOKS_URL))
+ .required(SlackSinkOptions.OAUTH_TOKEN,
notBlank(SlackSinkOptions.OAUTH_TOKEN))
+ .required(SlackSinkOptions.SLACK_CHANNEL,
notBlank(SlackSinkOptions.SLACK_CHANNEL))
.build();
}
diff --git
a/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/SlackFactoryTest.java
b/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/SlackFactoryTest.java
deleted file mode 100644
index f7e553535d..0000000000
---
a/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/SlackFactoryTest.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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.seatunnel.connectors.seatunnel.slack;
-
-import org.apache.seatunnel.connectors.seatunnel.slack.sink.SlackSinkFactory;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-class SlackFactoryTest {
-
- @Test
- void optionRule() {
- Assertions.assertNotNull((new SlackSinkFactory()).optionRule());
- }
-}
diff --git
a/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackFactoryTest.java
b/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackFactoryTest.java
new file mode 100644
index 0000000000..d99dfc813e
--- /dev/null
+++
b/seatunnel-connectors-v2/connector-slack/src/test/java/org/apache/seatunnel/connectors/seatunnel/slack/sink/SlackFactoryTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.seatunnel.connectors.seatunnel.slack.sink;
+
+import org.apache.seatunnel.api.configuration.ReadonlyConfig;
+import org.apache.seatunnel.api.configuration.util.ConfigValidator;
+import org.apache.seatunnel.api.configuration.util.OptionValidationException;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.stream.Stream;
+
+class SlackFactoryTest {
+
+ @Test
+ void validConfig() {
+ Assertions.assertDoesNotThrow(() -> validate(validOptions()));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"webhooks_url", "oauth_token", "slack_channel"})
+ void missingRequiredOption(String key) {
+ Map<String, Object> options = validOptions();
+ options.remove(key);
+ assertInvalid(options, key);
+ }
+
+ @ParameterizedTest(name = "{0}: {1}")
+ @MethodSource("blankRequiredOptions")
+ void blankRequiredOption(String key, String description, String value) {
+ Map<String, Object> options = validOptions();
+ options.put(key, value);
+ assertInvalid(options, key);
+ }
+
+ private static Stream<Arguments> blankRequiredOptions() {
+ return Stream.of("webhooks_url", "oauth_token", "slack_channel")
+ .flatMap(
+ key ->
+ Stream.of(
+ Arguments.of(key, "empty", ""),
+ Arguments.of(key, "space", " "),
+ Arguments.of(key, "tab", "\t"),
+ Arguments.of(key, "newline", "\n"),
+ Arguments.of(key, "mixed whitespace",
" \t\r\n ")));
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"webhooks_url", "oauth_token", "slack_channel"})
+ void preserveNonblankValues(String key) {
+ Map<String, Object> options = validOptions();
+ options.put(key, " arbitrary nonblank value ");
+ Assertions.assertDoesNotThrow(() -> validate(options));
+ }
+
+ private void assertInvalid(Map<String, Object> options, String key) {
+ OptionValidationException exception =
+ Assertions.assertThrows(OptionValidationException.class, () ->
validate(options));
+ Assertions.assertTrue(exception.getMessage().contains(key));
+ }
+
+ private void validate(Map<String, Object> options) {
+ ConfigValidator.of(ReadonlyConfig.fromMap(options))
+ .validate(new SlackSinkFactory().optionRule());
+ }
+
+ private Map<String, Object> validOptions() {
+ Map<String, Object> options = new HashMap<>();
+ options.put("webhooks_url",
"https://hooks.slack.com/services/test/test/test");
+ options.put("oauth_token", "test-oauth-token");
+ options.put("slack_channel", "seatunnel-alerts");
+ return options;
+ }
+}