Skip to content

Commit 225f4fa

Browse files
committed
Add Spring for Apache Pulsar
1 parent 28b7c58 commit 225f4fa

File tree

48 files changed

+7048
-9
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+7048
-9
lines changed

buildSrc/src/main/java/org/springframework/boot/build/classpath/CheckClasspathForProhibitedDependencies.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ private boolean prohibited(ModuleVersionIdentifier id) {
7979
if (group.equals("javax.money")) {
8080
return false;
8181
}
82+
if (group.equals("javax.xml.bind") && id.getName().equals("jaxb-api")) {
83+
return false;
84+
}
8285
if (group.equals("org.codehaus.groovy")) {
8386
return true;
8487
}

buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ private void integrationPrefixes(Config prefix) {
169169
prefix.accept("spring.integration");
170170
prefix.accept("spring.jms");
171171
prefix.accept("spring.kafka");
172+
prefix.accept("spring.pulsar");
172173
prefix.accept("spring.rabbitmq");
173174
prefix.accept("spring.hazelcast");
174175
prefix.accept("spring.webservices");

spring-boot-project/spring-boot-autoconfigure/build.gradle

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ dependencies {
5959
}
6060
optional("org.apache.httpcomponents.client5:httpclient5")
6161
optional("org.apache.kafka:kafka-streams")
62+
optional("org.apache.pulsar:pulsar-client-reactive-producer-cache-caffeine") {
63+
// spring-pulsar-reactive includes the pulsar-client-reactive-adapter with
64+
// problematic transitive dependencies removed
65+
exclude group: "org.apache.pulsar", module: "pulsar-client-reactive-adapter"
66+
}
6267
optional("org.apache.tomcat.embed:tomcat-embed-core")
6368
optional("org.apache.tomcat.embed:tomcat-embed-el")
6469
optional("org.apache.tomcat.embed:tomcat-embed-websocket")
@@ -175,6 +180,8 @@ dependencies {
175180
optional("org.springframework.data:spring-data-redis")
176181
optional("org.springframework.graphql:spring-graphql")
177182
optional("org.springframework.hateoas:spring-hateoas")
183+
optional("org.springframework.pulsar:spring-pulsar")
184+
optional("org.springframework.pulsar:spring-pulsar-reactive")
178185
optional("org.springframework.security:spring-security-acl")
179186
optional("org.springframework.security:spring-security-config")
180187
optional("org.springframework.security:spring-security-data") {
@@ -251,9 +258,9 @@ dependencies {
251258
testImplementation("org.testcontainers:junit-jupiter")
252259
testImplementation("org.testcontainers:mongodb")
253260
testImplementation("org.testcontainers:neo4j")
261+
testImplementation("org.testcontainers:pulsar")
254262
testImplementation("org.testcontainers:testcontainers")
255263
testImplementation("org.yaml:snakeyaml")
256-
257264
testRuntimeOnly("jakarta.management.j2ee:jakarta.management.j2ee-api")
258265
testRuntimeOnly("org.jetbrains.kotlin:kotlin-reflect")
259266
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2022-2023 the original author or authors.
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+
* https://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 org.springframework.boot.autoconfigure.pulsar;
18+
19+
import java.util.Map;
20+
import java.util.TreeMap;
21+
import java.util.regex.Pattern;
22+
import java.util.stream.Collectors;
23+
24+
import org.apache.pulsar.common.util.ObjectMapperFactory;
25+
26+
import org.springframework.util.CollectionUtils;
27+
28+
/**
29+
* Utility methods for Pulsar authentication parameters.
30+
*
31+
* @author Alexander Preuß
32+
*/
33+
final class AuthParameterUtils {
34+
35+
private static final Pattern KEBAB_CASE_PATTERN = Pattern.compile("-(.)");
36+
37+
private AuthParameterUtils() {
38+
39+
}
40+
41+
private static String convertKebabCaseToCamelCase(String kebabString) {
42+
return KEBAB_CASE_PATTERN.matcher(kebabString).replaceAll((mr) -> mr.group(1).toUpperCase());
43+
}
44+
45+
private static Map<String, String> convertWellKnownLowerCaseKeysToCamelCase(Map<String, String> params) {
46+
return params.entrySet()
47+
.stream()
48+
.collect(Collectors.toMap((entry) -> WellKnownAuthParameters.toCamelCaseKey(entry.getKey()),
49+
Map.Entry::getValue));
50+
}
51+
52+
private static Map<String, String> convertKebabCaseKeysToCamelCase(Map<String, String> params) {
53+
return params.entrySet()
54+
.stream()
55+
.collect(Collectors.toMap((entry) -> convertKebabCaseToCamelCase(entry.getKey()), Map.Entry::getValue));
56+
}
57+
58+
static String maybeConvertToEncodedParamString(Map<String, String> params) {
59+
if (CollectionUtils.isEmpty(params)) {
60+
return null;
61+
}
62+
// env vars are bound like this ISSUER_ID -> issuerid, have to be camel-cased to
63+
// work
64+
params = convertWellKnownLowerCaseKeysToCamelCase(params);
65+
params = convertKebabCaseKeysToCamelCase(params);
66+
params = new TreeMap<>(params); // sort keys for testing and readability
67+
try {
68+
return ObjectMapperFactory.create().writeValueAsString(params);
69+
}
70+
catch (Exception ex) {
71+
throw new RuntimeException("Could not convert parameters to encoded string", ex);
72+
}
73+
}
74+
75+
}

0 commit comments

Comments
 (0)