Skip to content

Commit b4e6b6a

Browse files
igarashitmrcernich
authored andcommitted
SWITCHYARD-2137 [camel] Support locating TransactionManager/EntityManagerFactory in a OSGi way
1 parent e50c8e9 commit b4e6b6a

File tree

9 files changed

+295
-6
lines changed

9 files changed

+295
-6
lines changed

camel/camel-jpa/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@
4848
<artifactId>camel-jpa</artifactId>
4949
<scope>compile</scope>
5050
</dependency>
51+
<dependency>
52+
<groupId>org.hibernate.javax.persistence</groupId>
53+
<artifactId>hibernate-jpa-2.0-api</artifactId>
54+
<scope>compile</scope>
55+
</dependency>
5156
<dependency>
5257
<groupId>org.switchyard.components</groupId>
5358
<artifactId>switchyard-component-camel-test</artifactId>
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
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+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.switchyard.component.camel.jpa.deploy;
15+
16+
import javax.xml.namespace.QName;
17+
18+
import org.switchyard.common.camel.SwitchYardCamelContext;
19+
import org.switchyard.component.camel.common.composer.CamelComposition;
20+
import org.switchyard.component.camel.common.deploy.BaseBindingActivator;
21+
import org.switchyard.component.camel.common.handler.InboundHandler;
22+
import org.switchyard.component.camel.common.handler.OutboundHandler;
23+
import org.switchyard.component.camel.common.model.CamelBindingModel;
24+
import org.switchyard.component.camel.jpa.model.CamelJpaBindingModel;
25+
26+
/**
27+
* Camel jpa activator.
28+
*/
29+
public class CamelJpaActivator extends BaseBindingActivator {
30+
31+
/**
32+
* Creates new activator instance.
33+
*
34+
* @param context Camel context.
35+
* @param types Activation types.
36+
*/
37+
public CamelJpaActivator(SwitchYardCamelContext context, String[] types) {
38+
super(context, types);
39+
}
40+
41+
@SuppressWarnings("unchecked")
42+
@Override
43+
protected InboundHandler<CamelJpaBindingModel> createInboundHandler(QName serviceName, CamelBindingModel binding) {
44+
return new CamelJpaInboundHandler((CamelJpaBindingModel)binding, getCamelContext(), serviceName, getServiceDomain());
45+
}
46+
47+
@Override
48+
protected OutboundHandler createOutboundHandler(CamelBindingModel binding) {
49+
return new CamelJpaOutboundHandler((CamelJpaBindingModel)binding, getCamelContext(), CamelComposition.getMessageComposer(binding), getServiceDomain());
50+
}
51+
}

camel/camel-jpa/src/main/java/org/switchyard/component/camel/jpa/deploy/CamelJpaComponent.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
*/
1414
package org.switchyard.component.camel.jpa.deploy;
1515

16+
import org.switchyard.common.camel.SwitchYardCamelContext;
17+
import org.switchyard.component.camel.common.deploy.BaseBindingActivator;
1618
import org.switchyard.component.camel.common.deploy.BaseBindingComponent;
1719
import org.switchyard.component.camel.jpa.model.v1.V1CamelJpaBindingModel;
1820

@@ -28,4 +30,8 @@ public CamelJpaComponent() {
2830
super("CamelJpaComponent", V1CamelJpaBindingModel.JPA);
2931
}
3032

33+
@Override
34+
protected BaseBindingActivator createActivator(SwitchYardCamelContext context, String... types) {
35+
return new CamelJpaActivator(context, types);
36+
}
3137
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
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+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.switchyard.component.camel.jpa.deploy;
15+
16+
import java.util.HashMap;
17+
18+
import javax.persistence.EntityManagerFactory;
19+
import javax.xml.namespace.QName;
20+
21+
import org.apache.camel.model.RouteDefinition;
22+
import org.switchyard.ServiceDomain;
23+
import org.switchyard.common.camel.SwitchYardCamelContext;
24+
import org.switchyard.component.camel.common.handler.InboundHandler;
25+
import org.switchyard.component.camel.jpa.model.CamelJpaBindingModel;
26+
27+
/**
28+
* Inbound handler for JPA binding. Resolve EntityManagerFactory instance in case it runs on OSGi container.
29+
*/
30+
public class CamelJpaInboundHandler extends InboundHandler<CamelJpaBindingModel> {
31+
32+
/**
33+
* Sole constructor.
34+
*
35+
* @param camelBindingModel The CamelBindingModel.
36+
* @param camelContext The camel context instance.
37+
* @param serviceName The target service name.
38+
* @param domain the service domain.
39+
*/
40+
public CamelJpaInboundHandler(CamelJpaBindingModel camelBindingModel,
41+
SwitchYardCamelContext camelContext, QName serviceName, ServiceDomain domain) {
42+
super(camelBindingModel, camelContext, serviceName, domain);
43+
}
44+
45+
@Override
46+
protected RouteDefinition createRouteDefinition() {
47+
CamelJpaBindingModel bindingModel = getBindingModel();
48+
EntityManagerFactory emf = EntityManagerFactoryLocator.locateEntityManagerFactory(bindingModel.getPersistenceUnit(), new HashMap<String,String>());
49+
if (emf != null) {
50+
getSwitchYardCamelContext().getWritebleRegistry().put(EntityManagerFactory.class.getName(), emf);
51+
}
52+
53+
return super.createRouteDefinition();
54+
}
55+
56+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
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+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.switchyard.component.camel.jpa.deploy;
15+
16+
import java.util.HashMap;
17+
18+
import javax.persistence.EntityManagerFactory;
19+
20+
import org.apache.camel.ProducerTemplate;
21+
import org.switchyard.ServiceDomain;
22+
import org.switchyard.common.camel.SwitchYardCamelContext;
23+
import org.switchyard.component.camel.common.composer.CamelBindingData;
24+
import org.switchyard.component.camel.common.handler.OutboundHandler;
25+
import org.switchyard.component.camel.jpa.model.CamelJpaBindingModel;
26+
import org.switchyard.component.common.composer.MessageComposer;
27+
28+
/**
29+
* Outbound handler for JPA binding. Resolve EntityManagerFactory instance in case it runs on OSGi container.
30+
*/
31+
public class CamelJpaOutboundHandler extends OutboundHandler {
32+
33+
/**
34+
* A constructor. @see OutboundHandler#OutboundHandler(CamelBindingModel, SwitchYardCamelContext, MessageComposer, ProducerTemplate, ServiceDomain)
35+
* @param binding binding model
36+
* @param context camel context
37+
* @param messageComposer message composer
38+
* @param producerTemplate producer template
39+
* @param domain service domain
40+
*/
41+
public CamelJpaOutboundHandler(CamelJpaBindingModel binding,
42+
SwitchYardCamelContext context,
43+
MessageComposer<CamelBindingData> messageComposer,
44+
ProducerTemplate producerTemplate, ServiceDomain domain) {
45+
super(binding, context, messageComposer, producerTemplate, domain);
46+
47+
EntityManagerFactory emf = EntityManagerFactoryLocator.locateEntityManagerFactory(binding.getPersistenceUnit(), new HashMap<String,String>());
48+
if (emf != null) {
49+
context.getWritebleRegistry().put(EntityManagerFactory.class.getName(), emf);
50+
}
51+
}
52+
53+
/**
54+
* A constructor. @see OutboundHandler#OutboundHandler(CamelBindingModel, SwitchYardCamelContext, MessageComposer, ServiceDomain)
55+
* @param binding binding
56+
* @param context camel context
57+
* @param messageComposer message composer
58+
* @param domain service domain
59+
*/
60+
public CamelJpaOutboundHandler(CamelJpaBindingModel binding,
61+
SwitchYardCamelContext context,
62+
MessageComposer<CamelBindingData> messageComposer,
63+
ServiceDomain domain) {
64+
this(binding, context, messageComposer, null, domain);
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright 2013 Red Hat Inc. and/or its affiliates and other contributors.
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+
* http://www.apache.org/licenses/LICENSE-2.0
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package org.switchyard.component.camel.jpa.deploy;
15+
16+
import java.util.Map;
17+
18+
import javax.naming.InitialContext;
19+
import javax.persistence.EntityManagerFactory;
20+
import javax.persistence.spi.PersistenceProvider;
21+
22+
import org.jboss.logging.Logger;
23+
24+
/**
25+
* EntityManagerFactory locator for Camel JPA component.
26+
*/
27+
public final class EntityManagerFactoryLocator {
28+
29+
private static Logger _logger = Logger.getLogger(EntityManagerFactoryLocator.class);
30+
31+
/**
32+
* OSGi specific PersistenceProvider JNDI name.
33+
*/
34+
public static final String OSGI_PERSISTENCE_PROVIDER_JNDI_NAME = "osgi:service/javax.persistence.spi.PersistenceProvider";
35+
36+
/**
37+
* OSGi specific EntityManagerFactory JNDI name.
38+
*/
39+
public static final String OSGI_ENTITY_MANAGER_FACTORY_JNDI_NAME = "osgi:service/javax.persistence.EntityManagerFactory";
40+
41+
private EntityManagerFactoryLocator() {
42+
}
43+
44+
/**
45+
* Lookup EntityManagerFactory from JNDI.
46+
* @param unitName JPA unit name.
47+
* @param props A Map of properties for use by the persistence provider.
48+
* @return EntityManagerFactory
49+
*/
50+
public static EntityManagerFactory locateEntityManagerFactory(String unitName, Map<?,?> props) {
51+
InitialContext ic = null;
52+
try {
53+
ic = new InitialContext();
54+
} catch (Exception e) {
55+
_logger.debug(e);
56+
return null;
57+
}
58+
59+
try {
60+
EntityManagerFactory emf = (EntityManagerFactory) lookupInJndi(ic, OSGI_ENTITY_MANAGER_FACTORY_JNDI_NAME);
61+
if (emf != null) {
62+
return emf;
63+
}
64+
65+
PersistenceProvider pp = (PersistenceProvider) lookupInJndi(ic, OSGI_PERSISTENCE_PROVIDER_JNDI_NAME);
66+
if (pp != null) {
67+
return pp.createEntityManagerFactory(unitName, props);
68+
}
69+
} finally {
70+
try {
71+
ic.close();
72+
} catch (Exception e) {
73+
_logger.debug(e);
74+
}
75+
}
76+
return null;
77+
}
78+
79+
private static Object lookupInJndi(InitialContext ic, String name) {
80+
try {
81+
return ic.lookup(name);
82+
} catch (Exception e) {
83+
_logger.debug(e);
84+
return null;
85+
}
86+
}
87+
}

common/camel/src/main/java/org/switchyard/component/camel/common/CommonCamelMessages.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,12 @@ public interface CommonCamelMessages {
130130
/**
131131
* couldNotCreateAJtaTransactionManagerAsNoTransactionManagerWasFoundJBOSSUSERTRANSACTION method definition.
132132
* @param userTransaction userTransaction
133+
* @param osgitm OSGi TransactionManager name
133134
* @param defaultUserTransaction defaultUserTransaction
134135
* @return SwitchYardException
135136
*/
136-
@Message(id = 34318, value = "Could not create a JtaTransactionManager as no TransactionManager was found in JNDI. Tried [%s, %s]")
137-
SwitchYardException couldNotCreateAJtaTransactionManagerAsNoTransactionManagerWasFoundJBOSSUSERTRANSACTION(String userTransaction, String defaultUserTransaction);
137+
@Message(id = 34318, value = "Could not create a JtaTransactionManager as no TransactionManager was found in JNDI. Tried [%s, %s, %s]")
138+
SwitchYardException couldNotCreateAJtaTransactionManagerAsNoTransactionManagerWasFoundJBOSSUSERTRANSACTION(String userTransaction, String osgitm, String defaultUserTransaction);
138139

139140
/**
140141
* unexpectedExceptionRetrieving method definition.

common/camel/src/main/java/org/switchyard/component/camel/common/deploy/BaseBindingActivator.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,15 +42,19 @@ public ServiceHandler activateBinding(QName serviceName, BindingModel config) {
4242
if (binding.isServiceBinding()) {
4343
return createInboundHandler(serviceName, binding);
4444
} else {
45-
return new OutboundHandler(binding, getCamelContext(), CamelComposition
46-
.getMessageComposer(binding), getServiceDomain());
45+
return createOutboundHandler(binding);
4746
}
4847
}
4948

5049
protected <T extends CamelBindingModel> InboundHandler<T> createInboundHandler(QName serviceName, T binding) {
5150
return new InboundHandler<T>(binding, getCamelContext(), serviceName, getServiceDomain());
5251
}
5352

53+
protected <T extends CamelBindingModel> OutboundHandler createOutboundHandler(T binding) {
54+
return new OutboundHandler(binding, getCamelContext(), CamelComposition
55+
.getMessageComposer(binding), getServiceDomain());
56+
}
57+
5458
@Override
5559
public void deactivateBinding(QName name, ServiceHandler handler) {
5660
// anything to do here?

common/camel/src/main/java/org/switchyard/component/camel/common/transaction/TransactionManagerFactory.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import javax.naming.InitialContext;
1717
import javax.naming.NamingException;
18+
import javax.transaction.TransactionManager;
1819

1920
import org.springframework.transaction.PlatformTransactionManager;
2021
import org.springframework.transaction.jta.JtaTransactionManager;
@@ -42,6 +43,11 @@ public final class TransactionManagerFactory {
4243
*/
4344
public static final String JBOSS_TRANSACTION_SYNC_REG = "java:jboss/TransactionSynchronizationRegistry";
4445

46+
/**
47+
* OSGi specific TransactionManager JNDI name.
48+
*/
49+
public static final String OSGI_TRANSACTION_MANAGER = "osgi:service/javax.transaction.TransactionManager";
50+
4551
/**
4652
* Configuration name for the JtaTransactionManager.
4753
*/
@@ -67,16 +73,23 @@ public static TransactionManagerFactory getInstance() {
6773
* @return {@link PlatformTransactionManager} the created PlatformTransactionManager.
6874
*/
6975
public PlatformTransactionManager create() {
70-
final JtaTransactionManager transactionManager = new JtaTransactionManager();
76+
JtaTransactionManager transactionManager;
7177

7278
if (isBound(JBOSS_USER_TRANSACTION)) {
79+
transactionManager = new JtaTransactionManager();
7380
transactionManager.setUserTransactionName(JBOSS_USER_TRANSACTION);
7481
transactionManager.setTransactionManagerName(JBOSS_TRANSACTION_MANANGER);
7582
transactionManager.setTransactionSynchronizationRegistryName(JBOSS_TRANSACTION_SYNC_REG);
83+
} else if (isBound(OSGI_TRANSACTION_MANAGER)) {
84+
transactionManager = new JtaTransactionManager((TransactionManager)lookupInJndi(OSGI_TRANSACTION_MANAGER));
7685
} else if (isBound(JtaTransactionManager.DEFAULT_USER_TRANSACTION_NAME)) {
86+
transactionManager = new JtaTransactionManager();
7787
transactionManager.setUserTransactionName(JtaTransactionManager.DEFAULT_USER_TRANSACTION_NAME);
7888
} else {
79-
throw CommonCamelMessages.MESSAGES.couldNotCreateAJtaTransactionManagerAsNoTransactionManagerWasFoundJBOSSUSERTRANSACTION(JBOSS_USER_TRANSACTION, JtaTransactionManager.DEFAULT_USER_TRANSACTION_NAME);
89+
throw CommonCamelMessages.MESSAGES.couldNotCreateAJtaTransactionManagerAsNoTransactionManagerWasFoundJBOSSUSERTRANSACTION(
90+
JBOSS_USER_TRANSACTION,
91+
OSGI_TRANSACTION_MANAGER,
92+
JtaTransactionManager.DEFAULT_USER_TRANSACTION_NAME);
8093
}
8194

8295
// Initialize the transaction manager.

0 commit comments

Comments
 (0)