Spring Beans
The fabric can be used as a Spring remoting architecture, both as a service exporter (publishing Spring beans for access by remote clients) and a proxy generator (using Spring-generated client proxies that use the fabric proprietary transport to get the request to the fabric and invoke the correct service).
Standing up Spring Beans in the fabric.
When your application plans to expose Spring beans, you will need to let the fabric know some information about your Spring bean factory. The Spring distribution includes several types of bean factories (i.e. XmlBeanFactory, FileSystemXmlApplicationContext, and ClasspathXmlApplicationContext)). The bean factory used by the fabric is not hard-coded; rather, we leverage the Spring bean definition XML - allowing you to define the bean factory that is to be used by your application. The following example uses FileSystemXmlApplicationContext.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="myBeanFactory" class="org.springframework.context.support.FileSystemXmlApplicationContext">
<constructor-arg value="my_spring_beans.xml"/>
</bean>
</beans>
This file must be included with your application - we recommend that you add the file to one of the jar files included in the application. The file must be mentioned in your Application Definition XML. The following example tells the fabric to use the previous file when creating the bean factory for your application.
<app name="touchless_app" version='1.0'>
<spring>
<bean-factory-locator bean="myBeanFactory" resource-location="file:beanRefFactory.xml"/>
</spring>
...
</app>
In our example, we also specified an XML file containing our bean definitions that we want the fabric to expose. This file must also be included in the fabric application. This file might look something like:
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN/EN"
"https://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MapGenerator" class="...">
...
</bean>
... other beans ...
</beans>
Finally, you inform the fabric of the Spring beans that you'd like exposed by creating a component definition XML
<?xml version="1.0" encoding="UTF-8"?>
<java-components xmlns=...>
<component name="MappingServices" default-timeout="5">
<spring-bean name="MapGenerator"/>
...
</component>
</java-components>
Accessing a Spring Bean from the Client.
The client-side code for accessing an exposed Spring Bean in the fabric is pretty straightforward. An example:
...
public void callBean() throws Throwable
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("client-side.xml");
IMappingService bean = (IMappingService)context.getBean("MapGenerator");
Result result = bean.generateMap();
}
The corresponding Spring XML might look something like:
<!DOCTYPE beans PUBLIC "- "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="MapGenerator" class="com.appistry.spring.FabricProxyFactoryBean">
<property name="serviceInterface" value="IMappingService "/>
<property name="fabric"><ref local="fabric"/></property>
<property name="applicationName" value="..."/>
<property name="componentName" value="MappingServices"/>
</bean>
<bean id="fabric" class="com.appistry.fabric.Fabric">
<constructor-arg>
<props>
<prop key="fabric-address"> 239.255.1.99 </prop>
</props>
</constructor-arg>
</bean>
...
</beans>
There are a few things to note here. The first is that we need to mention the applicationName and the componentName - these two items correspond to the application and component that were deployed to the fabric in the previous section. Next, note that the MapGenerator bean is referencing the fabric bean as a property. The fabric bean defines the configuration of the Fabric interface object - setting up the transport to communicate with the fabric at 239.255.1.99. The example here is using the constructor that takes a java.util.Properties. Additional property keys are defined:
| Property Key |
Default Value |
Description |
| fabric-address |
239.255.0.1 |
The address of a running Fabric. |
| request-port |
31000 |
The port on which the fabric is listening. |
| mcast-ttl |
1 |
Socket-level time-to-live for UDP and multicast packets. Number of IP hops beyond which the packet should not be forwarded. |
| tcp-idle-connection-timeout |
15000 msecs |
How many seconds to maintain idle connections before closing them. |
| tcp-connect-timeout |
5000 msecs |
How long a connection attempt should be allowed to take before considering it failed (when attempting to connect to a failed worker, the OS can take a long time to determine that the endpoint is no longer available) |
| cache-refresh-interval |
5 secs |
How often to refresh the cache of workers' addresses. |
| cache-refresh-timeout |
1 secs |
How long after checking for new workers to flush non-responsive workers from the current cache. |
| tcp-keep-alive-interval |
10000 msecs |
How often to send "keep-alive" packets on an established TCP socket that is quiescent. |
| tcp-inactive-read-timeout |
15000 msecs |
How long to wait to receive a packet from peer over an established, quiescent TCP socket before considering it failed |