Skip to content

Commit 9295062

Browse files
authored
[3.x] 6262 JMS JNDI destination support (helidon-io#6301)
* 6262 JMS JNDI destination support
1 parent 22344a5 commit 9295062

16 files changed

Lines changed: 264 additions & 41 deletions

File tree

docs/mp/reactivemessaging/jms.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///////////////////////////////////////////////////////////////////////////////
22

3-
Copyright (c) 2020, 2022 Oracle and/or its affiliates.
3+
Copyright (c) 2020, 2023 Oracle and/or its affiliates.
44

55
Licensed under the Apache License, Version 2.0 (the "License");
66
you may not use this file except in compliance with the License.
@@ -76,6 +76,7 @@ Expression can only access headers and properties, not the payload.
7676
|`session-group-id` | When multiple channels share same `session-group-id`,
7777
they share same JMS session and same JDBC connection as well.
7878
|`jndi.jms-factory` | JNDI name of JMS factory.
79+
|`jndi.destination` | JNDI destination identifier.
7980
|`jndi.env-properties` | Environment properties used for creating initial context `java.naming.factory.initial`, `java.naming.provider.url` ...
8081
|`producer.someproperty` | property with producer prefix is set to producer instance (for example WLS Unit-of-Order `WLMessageProducer.setUnitOfOrder("unit-1")` can be configured as `producer.unit-of-order=unit-1`)
8182
|===

docs/mp/reactivemessaging/weblogic.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Connector name: `helidon-weblogic-jms`
7070
|`credentials` | WebLogic initial context credential(password)
7171
|`type` | Possible values are: `queue`, `topic`. Default value is: `topic`
7272
|`destination` | Queue or topic name in WebLogic CDI Syntax(CDI stands for Create Destination Identifier)
73+
|`jndi.destination` | JNDI destination identifier. When no such JNDI destination is found, falls back to `destination` with CDI syntax.
7374
|`acknowledge-mode` |Possible values are: `AUTO_ACKNOWLEDGE`- session automatically acknowledges a client’s receipt of a message,
7475
`CLIENT_ACKNOWLEDGE` - receipt of a message is acknowledged only when `Message.ack()` is called manually,
7576
`DUPS_OK_ACKNOWLEDGE` - session lazily acknowledges the delivery of messages. Default value: `AUTO_ACKNOWLEDGE`
@@ -114,7 +115,8 @@ mp:
114115
outgoing:
115116
to-wls:
116117
connector: helidon-weblogic-jms
117-
destination: ./TestJMSModule!TestQueue
118+
# JNDI identifier for the same queue
119+
jndi.destination: jms/TestQueue
118120
----
119121
120122
When configuring destination with WebLogic CDI, the following syntax needs to be applied:

examples/messaging/jms-websocket-mp/src/main/java/io/helidon/examples/messaging/mp/MsgProcessingBean.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
1616

1717
package io.helidon.examples.messaging.mp;
1818

19+
import java.util.concurrent.CompletableFuture;
20+
import java.util.concurrent.CompletionStage;
1921
import java.util.concurrent.SubmissionPublisher;
2022

2123
import io.helidon.common.reactive.Multi;
@@ -77,22 +79,26 @@ public ProcessorBuilder<String, Message<String>> multiply() {
7779
* Broadcasts an event.
7880
*
7981
* @param msg Message to broadcast
82+
* @return completed stage
8083
*/
8184
@Incoming("fromJms")
82-
public void broadcast(JmsMessage<String> msg) {
85+
public CompletionStage<Void> broadcast(JmsMessage<String> msg) {
8386
// Broadcast to all subscribers
8487
broadCaster.submit(msg.getPayload());
88+
return CompletableFuture.completedFuture(null);
8589
}
8690

8791
/**
8892
* Same JMS session, different connector.
8993
*
9094
* @param msg Message to broadcast
95+
* @return completed stage
9196
*/
9297
@Incoming("fromJmsSameSession")
93-
public void sameSession(JmsMessage<String> msg) {
98+
public CompletionStage<Void> sameSession(JmsMessage<String> msg) {
9499
// Broadcast to all subscribers
95100
broadCaster.submit(msg.getPayload());
101+
return CompletableFuture.completedFuture(null);
96102
}
97103

98104
/**

examples/messaging/weblogic-jms-mp/src/main/resources/application.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2022 Oracle and/or its affiliates.
2+
# Copyright (c) 2022, 2023 Oracle and/or its affiliates.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -38,5 +38,5 @@ mp:
3838
outgoing:
3939
to-wls:
4040
connector: helidon-weblogic-jms
41-
# Same queue is used for simplifying test case
42-
destination: ./TestJMSModule!TestQueue
41+
# JNDI identifier for the same queue
42+
jndi.destination: jms/TestQueue

messaging/connectors/jms/src/main/java/io/helidon/messaging/connectors/jms/ConnectionContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Optional<? extends ConnectionFactory> lookupFactory(String jndi) {
9393
}
9494

9595
Optional<? extends Destination> lookupDestination(String jndi) {
96-
return Optional.ofNullable((Destination) lookup(jndi))
96+
return Optional.ofNullable(lookup(jndi))
9797
.map(o -> JakartaJms.resolve(o, Destination.class));
9898
}
9999

messaging/connectors/jms/src/main/java/io/helidon/messaging/connectors/jms/JmsConnector.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import io.helidon.messaging.MessagingException;
4646
import io.helidon.messaging.NackHandler;
4747
import io.helidon.messaging.Stoppable;
48+
import io.helidon.messaging.connectors.jms.shim.JakartaJms;
4849
import io.helidon.messaging.connectors.jms.shim.JakartaWrapper;
4950

5051
import jakarta.enterprise.context.ApplicationScoped;
@@ -296,13 +297,16 @@ public class JmsConnector implements IncomingConnectorFactory, OutgoingConnector
296297
static final String SCHEDULER_THREAD_NAME_PREFIX = "jms-poll-";
297298
static final String EXECUTOR_THREAD_NAME_PREFIX = "jms-";
298299

299-
private final Instance<ConnectionFactory> connectionFactories;
300+
private final Instance<ConnectionFactory> jakartaConnectionFactories;
300301

301302
private final ScheduledExecutorService scheduler;
302303
private final ExecutorService executor;
303304
private final Map<String, SessionMetadata> sessionRegister = new HashMap<>();
304305
private final Map<String, ConnectionFactory> connectionFactoryMap;
305306

307+
@Inject
308+
private Instance<javax.jms.ConnectionFactory> javaxConnectionFactories;
309+
306310
/**
307311
* Provides a {@link JmsConnectorBuilder} for creating
308312
* a {@link io.helidon.messaging.connectors.jms.JmsConnector} instance.
@@ -334,12 +338,13 @@ public static JmsConfigBuilder configBuilder() {
334338
/**
335339
* Create new JmsConnector.
336340
*
337-
* @param connectionFactories connection factory beans
341+
* @param jakartaConnectionFactories connection factory beans
338342
* @param config root config for thread context
339343
*/
340344
@Inject
341-
protected JmsConnector(io.helidon.config.Config config, Instance<ConnectionFactory> connectionFactories) {
342-
this.connectionFactories = connectionFactories;
345+
protected JmsConnector(io.helidon.config.Config config,
346+
Instance<ConnectionFactory> jakartaConnectionFactories) {
347+
this.jakartaConnectionFactories = jakartaConnectionFactories;
343348
this.connectionFactoryMap = Map.of();
344349
scheduler = ScheduledThreadPoolSupplier.builder()
345350
.threadNamePrefix(SCHEDULER_THREAD_NAME_PREFIX)
@@ -363,7 +368,8 @@ protected JmsConnector(io.helidon.config.Config config, Instance<ConnectionFacto
363368
protected JmsConnector(Map<String, ConnectionFactory> connectionFactoryMap,
364369
ScheduledExecutorService scheduler,
365370
ExecutorService executor) {
366-
this.connectionFactories = null;
371+
this.jakartaConnectionFactories = null;
372+
this.javaxConnectionFactories = null;
367373
this.connectionFactoryMap = connectionFactoryMap;
368374
this.scheduler = scheduler;
369375
this.executor = executor;
@@ -453,20 +459,20 @@ protected Optional<? extends ConnectionFactory> getFactory(ConnectionContext ctx
453459
if (factoryName.isPresent()) {
454460
// Check SE map and MP instance for named factories
455461
return Optional.ofNullable(connectionFactoryMap.get(factoryName.get()))
456-
.or(() ->
457-
Optional.ofNullable(connectionFactories)
458-
.flatMap(s -> s.select(NamedLiteral.of(factoryName.get()))
459-
.stream()
460-
.findFirst()
461-
)
462-
);
462+
.or(() -> getConnectionFactoryBean(factoryName.get()));
463463
}
464464

465465
// Check SE map and MP instance for any factories
466466
return connectionFactoryMap.values().stream().findFirst()
467-
.or(() -> Optional.ofNullable(connectionFactories)
468-
.flatMap(s -> s.stream().findFirst())
469-
);
467+
.or(() -> getConnectionFactoryBean(factoryName.get()));
468+
}
469+
470+
private <T> Optional<ConnectionFactory> getConnectionFactoryBean(String name){
471+
NamedLiteral literal = NamedLiteral.of(name);
472+
return jakartaConnectionFactories.select(literal)
473+
.stream()
474+
.findFirst()
475+
.or(() -> javaxConnectionFactories.select(literal).stream().map(JakartaJms::create).findFirst());
470476
}
471477

472478
@Override
@@ -711,7 +717,6 @@ protected Destination createDestination(Session session, ConnectionContext ctx)
711717

712718
if (ctx.isJndi()) {
713719
Optional<? extends Destination> jndiDestination = ctx.lookupDestination();
714-
// JNDI can be used for looking up ConnectorFactory only
715720
if (jndiDestination.isPresent()) {
716721
return jndiDestination.get();
717722
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# Copyright (c) 2023 Oracle and/or its affiliates.
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+
pattern=weblogic.**;java.util.**;java.lang.**;java.io.**;java.rmi.**

tests/integration/jms/pom.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,15 @@
6868
<artifactId>helidon-microprofile-tests-junit5</artifactId>
6969
<scope>test</scope>
7070
</dependency>
71+
<dependency>
72+
<groupId>io.helidon.messaging.mock</groupId>
73+
<artifactId>helidon-messaging-mock</artifactId>
74+
<scope>test</scope>
75+
</dependency>
76+
<dependency>
77+
<groupId>org.slf4j</groupId>
78+
<artifactId>slf4j-jdk14</artifactId>
79+
<scope>test</scope>
80+
</dependency>
7181
</dependencies>
7282
</project>

tests/integration/jms/src/test/java/io/helidon/messaging/connectors/jms/AbstractJmsTest.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -28,7 +28,6 @@
2828
public class AbstractJmsTest {
2929

3030
static final String BROKER_URL = "vm://localhost?broker.persistent=false";
31-
// static final String BROKER_URL = "tcp://localhost:61616";
3231
static Session session;
3332
static ConnectionFactory connectionFactory;
3433

tests/integration/jms/src/test/java/io/helidon/messaging/connectors/jms/AbstractSampleBean.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2020, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -98,7 +98,7 @@ public static class ChannelAck extends AbstractSampleBean {
9898

9999
@Incoming("test-channel-ack-1")
100100
@Acknowledgment(Acknowledgment.Strategy.MANUAL)
101-
public CompletionStage<String> channelAck(Message<String> msg) {
101+
public CompletionStage<Void> channelAck(Message<String> msg) {
102102
LOGGER.fine(() -> String.format("Received %s", msg.getPayload()));
103103
consumed().add(msg.getPayload());
104104
if (msg.getPayload().startsWith("NO_ACK")) {

0 commit comments

Comments
 (0)