我们需要重新评估我们当前实施的JCA TCP / IP适配器,项目负责人将新的但重要的要求传递给了我。
需要添加新的TCP连接并无需启动它们,而无需重新启动服务器。 (另外修改现有的) 当前,只有在standalone.xml中添加新属性才可能,并且这需要重新启动/重新加载服务器。
我正在看很多博客文章和有关使用MDB实现JCA的“教程”,我认为我掌握了它,但是我没有看到一种动态地,最好通过代码来创建新连接的方法。
我想了一秒钟,我可以将ActivationSpec与ResourceAdapter类结合使用,但是我不知道怎么可能。
编辑: 我们的资源适配器的实现方式绝对不正确,但我仍将其声明为双向的。它既可以侦听连接,也可以打开连接,还可以接收和发送消息。
资源适配器以未压缩的.rar格式添加到wildfly模块系统中,其中
内带有module.xmlC:\wildfly-10.0.0.Final\modules\com\company\server\TcpConnectorServerModule\5.1.0.0
module.xml的内容:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.company.server.TcpConnectorServerModule"
slot="5.1.0.0">
<resources>
<resource-root path="." />
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.resource.api"/>
</dependencies>
</module>
standalone.xml中的内容:
<subsystem xmlns="urn:jboss:domain:ee:4.0">
<global-modules>
<module name="org.infinispan.cdi.embedded" slot="ispn-8.2"/>
<module name="org.jgroups" slot="ispn-8.2"/>
<module name="com.company.server.TcpConnectorServerModule" slot="5.1.0.0" meta-inf="true"/>
</global-modules>
TL; DR:
是否可以设计JCA资源适配器,而无需重新启动服务器就可以动态地(并且希望通过代码)创建和修改连接?
如果没有在JCA中重新启动是不可能的,那么我将欣赏在Wildfly中启用TCP / IP连接到外部设备(打印机,扫描仪,磅秤等)的替代方法。我们需要能够在业务逻辑中与这些设备进行交互。
答案 0 :(得分:0)
有一个名为auto-deploy-exploded的热部署功能,并描述了here的第二种情况。在生产环境中进行测试之前,我首先会收集使用此功能的测试环境经验。我一年前写了一个资源适配器测试项目,并在github上对其进行了描述,并提供了一些有关创建和使用的其他资源。我希望这会有所帮助。
答案 1 :(得分:0)
我发现,尽管CLI不能添加新的连接,但是由于我只能重新启动整个服务器而不是子系统,因此JMX可以实现。
我可以添加与JMX的新连接,并通过“激活”操作“重新启动”子系统。如果子系统已经处于活动状态,则该操作就像重新启动一样。
然后,可以像以前一样使用应用程序中的InitialConext.listBindings()
函数来获得新连接。
这是带有Groovy的示例JMX脚本:
import java.lang.management.ManagementFactory;
import javax.management.ObjectName;
import java.lang.String;
import java.lang.Integer;
import java.lang.Boolean;
import java.lang.Long;
import javax.management.openmbean.TabularData;
import javax.management.MBeanInfo;
def mBeanServer = ManagementFactory.getPlatformMBeanServer()
def tcpConnectorMBean = new ObjectName("jboss.as:subsystem=resource-adapters,resource-adapter=TCPConnector")
def definitionMBean = new ObjectName( "jboss.as:subsystem=resource-adapters,resource-adapter=TCPConnector,connection-definitions=*" )
println 'before test creation:'
printAvailableBeans(mBeanServer,definitionMBean, 'jndiName')
//createTcpConnection(mBeanServer,tcpConnectorMBean)
//println 'After test creation:'
//printAvailableBeans(mBeanServer,definitionMBean, 'jndiName')
/*
* After adding a new Connection and configuring the needed properties, the Resource Adapter needs to be (re)activated in order to register
* the newly added connection and make it available with the JNDI
*/
//activateBean(mBeanServer,tcpConnectorMBean)
/**
* This function retrieves the Object for the given name and tries to retrieve all MBeans for it and extracts some information of it.
*/
void printAvailableBeans(def mBeanServer, ObjectName objectName, String attribute){
mBeanServer.queryMBeans( objectName, null ).each {
print 'Class name: ' + it.className
print 'Object name : ' + it.name
print ' -> '
def handler = mBeanServer.getAttribute( it.name,attribute )
println handler
}
println ''
}
void createTcpConnection(def mBeanServer,ObjectName objectName){
final String name = 'TestJMX'
final Integer allocationRetry = null
final Long allocationRertyWaitMills = null
final Boolean backgroundValidation = null
final Long backgroundValidationMills = null
final Long blockingTimeoutWaitMills = null
final String capacityDecrementerClass = null
final TabularData capacityDecrementerProperties = null
final String capacityIncrementerClass = null
final TabularData capacityIncrementerProperties = null
final String className = 'TCPManagedConnectionFactory'
final Boolean connectable = false
final Boolean enabled = true
final Boolean enlistment = true
final Boolean enlistmentTrace = null
final String flushStrategy = 'FailingConnectionOnly'
final Long idleTimeoutMinutes = null
final Integer initialPoolSize = null
final Boolean interleaving = false
final String jndiName = 'java:/tcp/TestJMX'
final Integer maxPoolSize = 20
final String mcp = null
final Integer minPoolSize = 0
final Boolean noRecovery = false
final Boolean noTxSeparatePool = false
final Boolean padXid = false
final Boolean poolFair = true
final Boolean poolPrefill = false
final Boolean poolUseStrictMin = false
final String recoveryPassword = null
final String recoveryPluginClassName = null
final TabularData recoveryPluginProperties = null
final String recoverySecurityDomain = null
final String recoveryUsername = null
final Boolean sameRmOverride = null
final Boolean securityApplication = false
final String securityDomain = null
final String securityDomainAndApplication = null
final Boolean sharable = true
final Boolean tracking = null
final Boolean useCcm = true
final Boolean useFastFail = false
final Boolean useJavaContext = true
final Boolean validateOnMatch = null
final Boolean wrapXaResource = true
final Integer xaResourceTimeout = null
Object[] opParam =[name,allocationRetry,allocationRertyWaitMills,backgroundValidation,backgroundValidationMills,blockingTimeoutWaitMills,capacityDecrementerClass,capacityDecrementerProperties,capacityIncrementerClass,capacityIncrementerProperties,className,connectable,enabled,enlistment,enlistmentTrace,flushStrategy,idleTimeoutMinutes,initialPoolSize,interleaving,jndiName,maxPoolSize,mcp,minPoolSize,noRecovery,noTxSeparatePool,padXid,poolFair,poolPrefill,poolUseStrictMin,recoveryPassword,recoveryPluginClassName,recoveryPluginProperties,recoverySecurityDomain,recoveryUsername,sameRmOverride,securityApplication,securityDomain,securityDomainAndApplication,sharable,tracking,useCcm,useFastFail,useJavaContext,validateOnMatch,wrapXaResource,xaResourceTimeout]
String[] opSig = [name.getClass().getName(),allocationRetry.getClass().getName(),allocationRertyWaitMills.getClass().getName(),backgroundValidation.getClass().getName(),backgroundValidationMills.getClass().getName(),blockingTimeoutWaitMills.getClass().getName(),capacityDecrementerClass.getClass().getName(),capacityDecrementerProperties.getClass().getName(),capacityIncrementerClass.getClass().getName(),capacityIncrementerProperties.getClass().getName(),className.getClass().getName(),connectable.getClass().getName(),enabled.getClass().getName(),enlistment.getClass().getName(),enlistmentTrace.getClass().getName(),flushStrategy.getClass().getName(),idleTimeoutMinutes.getClass().getName(),initialPoolSize.getClass().getName(),interleaving.getClass().getName(),jndiName.getClass().getName(),maxPoolSize.getClass().getName(),mcp.getClass().getName(),minPoolSize.getClass().getName(),noRecovery.getClass().getName(),noTxSeparatePool.getClass().getName(),padXid.getClass().getName(),poolFair.getClass().getName(),poolPrefill.getClass().getName(),poolUseStrictMin.getClass().getName(),recoveryPassword.getClass().getName(),recoveryPluginClassName.getClass().getName(),recoveryPluginProperties.getClass().getName(),recoverySecurityDomain.getClass().getName(),recoveryUsername.getClass().getName(),sameRmOverride.getClass().getName(),securityApplication.getClass().getName(),securityDomain.getClass().getName(),securityDomainAndApplication.getClass().getName(),sharable.getClass().getName(),tracking.getClass().getName(),useCcm.getClass().getName(),useFastFail.getClass().getName(),useJavaContext.getClass().getName(),validateOnMatch.getClass().getName(),wrapXaResource.getClass().getName(),xaResourceTimeout.getClass().getName()]
mBeanServer.invoke(objectName,'addConnectionDefinitions',opParam,opSig)
}
void activateBean(def mBeanServer, ObjectName mBean){
Object[] opParam = []
String[] opSig = []
mBeanServer.invoke(mBean, 'activate', opParam, opSig)
}
return