Chapter 13. Configuration Properties

SwitchYard supports configuration properties that can be injected into configuration or into service implementations.

13.1. Switchyard Model Configuration

SwitchYard allows you to replace any attribute or element value in the switchyard.xml file with a property from the runtime environment. The syntax for a replaced token is:
${varname}
Here, varname is the property name. The configuration layer in SwitchYard is configured with instances of PropertyResolver, which are used to resolve the value of a property based on its name.
Property values are resolved from the following locations:
  • System properties passed by -D option of Java VM. For example:
    -Dproperty.name=property.value
  • System environment variables, referenced with an env. prefix. For example:
    env.PATH
  • Unit test properties
  • JBoss EAP properties, including access into the SecurityVault
  • Domain properties in switchyard.xml file
  • SCA property definitions in the composite or component
The priority in resolving a property is from top to bottom. So a property defined as a System property always takes precedence over a property defined at domain or composite, and a property at domain level always takes precedence over a property defined at component level.

13.2. Injecting Properties Into Service Implementation

Implementation properties allow you to inject one or more property values into a service implementation. This is based on the property support in the SCA assembly specification. Since the property is injected into service implementation logic, the injection mechanism itself is unique to each implementation type. Here are the details for each implementation type:
  • Java: Injected using @Property into a CDI bean
  • Camel: Wired into Camel properties component and accessible in a Camel route using Camel’s own varName property notation
  • BPEL: Mapped into process variables using <assign> with using resolveProperty() XPath custom function
  • BPMN 2: Inserted into process variables by data input associations
  • Drools: Available in a global map

13.2.1. Injecting Properties in Java Bean Implementations

Implementation properties represent environmental properties that you have defined in the SwitchYard application descriptor (switchyard.xml) for your bean implementation. Implementation properties in SwitchYard are the properties that you can configure on a specific service implementation. That is, you can make the property value available to service logic executing inside an implementation container. Here is an example:
<sca:component name="SimpleServiceBean">
      <bean:implementation.bean class="com.example.switchyard.switchyard_example.SimpleServiceBean"/>
      <sca:service name="SimpleService">
        <sca:interface.java interface="com.example.switchyard.switchyard_example.SimpleService">
          <properties>
            <property name="userName" value="${user.name}"/>
          </properties>
        </sca:interface.java>
      </sca:service>
</sca:component>
To access the Implementation Properties, add an @Property annotation to your bean class identifying the property you want to inject:
@Service(SimpleService.class)
public class SimpleServiceBean implements SimpleService {

  @Property(name="userName")
  private String name;

  @Override
  public String sayHello(String message) {
        return "Hello " + name + ", I got a message: " + message;
    }

}

13.2.2. Injecting Implementation Properties in Camel Routes

SwitchYard integrates with the Properties Component in Camel to make system and application properties available inside your route definitions. You can inject properties into your camel route using {{propertyname}} expression, where propertyName is the name of the property. For example, the following camel route expects the user.name property to be injected in the last <Log> statement:
<route xmlns="http://camel.apache.org/schema/spring" id="CamelTestRoute">
    <log message="ItemId [${body}]"/>
    <to uri="switchyard://WarehouseService?operationName=hasItem"/>
    <log message="Title Name [${body}]"/>
    <log message="Properties [{{user.name}}]"/>
</route>

13.2.3. Injecting Implementation Properties in BPEL

You can inject properties into your BPEL process definition with using SwitchYardPropertyFunction.resolveProperty() XPath custom function. In the example below, bpel:copy section copies Greeting property value into the ReplySayHelloVar variable:
<bpel:copy> 
 <bpel:from xmlns:property="java:org.switchyard.component.bpel.riftsaw.SwitchYardPropertyFunction"
                expressionLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath2.0"> 
  	<![CDATA[concat(property:resolveProperty('Greeting'), $ReceiveSayHelloVar.parameters/tns:input)]]>
  	<bpel:from>
  	 	<bpel:to part="parameters" variable="ReplySayHelloVar">
  	  	<bpel:query queryLanguage="urn:oasis:names:tc:wsbpel:2.0:sublang:xpath1.0">
  	   	<![CDATA[tns:result]]>
  	</bpel:query>
 </bpel:to>
</bpel:copy> 

13.3. Invocation Properties

While it is a best practice to write your service logic to the data that is defined in the contract (the input and output message types), there can be situations where you need to access contextual information like message headers (such as, received file name in your implementation). To facilitate this, the Bean component allows you to access the SwitchYard Exchange Context instance associated with a given Bean Service Operation invocation. Invocation properties represent the contextual information (like message headers) in your bean implementation.
To enable access to the invocation properties, add a Context property to your bean and annotate it with the CDI @Inject annotation:
@Service(SimpleService.class)
public class SimpleServiceBean implements SimpleService {

@Inject
private Context context;

public String sayHello(String message) {
        System.out.println("*** Funky Context Property Value: " + context.getPropertyValue("funkyContextProperty"));
        return "Hi there!!";
    }
}
Here, the Context interface allows your bean logic to get and set properties in the context.

Note

You can invoke the Context instance only within the scope of one of the Service Operation methods. If you invoke it outside this scope, it results in an UnsupportedOperationException error.

13.4. Configuration Tips and Tricks

13.4.1. Defining Default Value for a Property

When you define a property, you can provide a default value for it. To define this default value, append the default value to the property name, separated by a colon (:). For example:
${server.port:8080}

13.4.2. Defining Environment Properties

13.4.2.1. Environment Properties as Component Properties

You can define properties as component properties. This way of defining properties is not dynamic, but you can override each property defined here, by properties defined in a prioritized scope.
<sy:switchyard ...>
  <sca:composite ...>
    <sca:component ...>
      ...
      <sca:property value="test" name="MY_PROPERTY"/>
    </sca:component>
    <sca:service...>
      ...
    </sca:service>
    <sca:reference ...>
      ...
    </sca:reference>

  </sca:composite>
  ...
</sy:switchyard>

13.4.2.2. Environment Properties as Composite Properties

You can define properties as composite properties. This way of defining properties is not dynamic, but you can override every property defined here, by properties defined in a prioritized scope.
<sy:switchyard ...>
  <sca:composite ...>
    <sca:component ...>
      ...
    </sca:component>
    <sca:service...>
      ...
    </sca:service>
    <sca:reference ...>
      <sca:interface.java .../>
      <file:binding.file name="FileBinding">
        <file:directory>/tmp</file:directory>
        <file:fileName>${MY_FILENAME}</file:fileName>
        <file:produce/>
      </file:binding.file>
    </sca:reference>
    <sca:property value="test.txt" name="MY_FILENAME"/>
  </sca:composite>
  ...
</sy:switchyard>

13.4.2.3. Environment Properties as Domain Properties

You can define properties as composite properties. This way of defining properties is not dynamic, but you can override each property defined here, by properties defined in a prioritized scope.
<sy:switchyard ...>
  <sca:composite ...>
    <sca:component ...>
      ...
    </sca:component>
    <sca:service...>
      ...
    </sca:service>
    <sca:reference ...>
      ...
    </sca:reference>
  </sca:composite>
  ...
  <sca:domain>
    <sca:property value="test.txt" name="MY_FILENAME"/>
  </sca:domain>
 </sy:switchyard>

13.4.2.4. Environment Properties in a Static or Dynamic Module

You can externalize properties from the SwitchYard application by defining them outside the switchyard.xml file. For example, inside a module. For this to work, you need to define your module as shown below:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<module xmlns="urn:jboss:module:1.0" name="com.examples.switchyard.properties">
    <properties>
        <property name="ftp_server.host" value="localhost"/>
        <property name="ftp_server.port" value="22"/>
    </properties>
</module>
Once you define your module, use these properties in your SwitchYard application as shown below:
<ftp:binding.sftp>
    <ftp:host>${ftp_server.host}</ftp:host>
    <ftp:port>${ftp_server.port}</ftp:port>
   ....
</ftp:binding.sftp>

13.4.2.5. Environment Properties as OS Environment Properties

You can load properties from OS environment properties. Every environment property is accessible by prefixing it with env. For example, in bash, you can use a property defined as export MY_PROPERTY=test, in your SwitchYard application as shown below:
<ftp:binding.sftp>
    <ftp:host>${env.MY_PROPERTY}</ftp:host>
   ....
</ftp:binding.sftp>

13.4.2.6. Environment Properties as Application Server Properties from AS Configuration

Application server has the ability to define properties directly in its configuration either by file or with the console. This configuration is dynamically updated and persisted.
Add the configuration to the server definition as shown below:

<server name="xyz.home" xmlns="urn:jboss:domain:1.0">
    <extensions>
        <extension module="org.jboss.as.clustering.infinispan"/>
        <extension module="org.jboss.as.clustering.jgroups"/>
        <extension module="org.jboss.as.connector"/>
        ....
    </extensions>
    <system-properties>
        <property name="MY_PROPERTY" value="test"/>
    </system-properties>
This property is used in your SwitchYard application as:

<ftp:binding.sftp>
    <ftp:host>${MY_PROPERTY}</ftp:host>
   ....
</ftp:binding.sftp>

13.4.2.7. Environment Properties as Application Server Properties from File

You can pass a properties file as an argument to JBoss Application Server (AS) startup script to load all the properties in the file and make them accessible. You can start the AS as shown below:
$./standalone.sh -P file:///data/production.properties
Here are some alternatives:
  • -P=<url>: Load system properties from the given URL
  • -P<url>: Load system properties from the given URL
  • --properties=<url>: Load system properties from the given URL
In your SwitchYard application, you can use these properties as:

<ftp:binding.sftp>
    <ftp:host>${env.MY_PROPERTY}</ftp:host>
   ....
</ftp:binding.sftp>

13.4.3. Loading Properties for Test

In tests, you can add and resolve properties at the top level. The PropertyMixIn eases working with properties:

   private PropertyMixIn pmi;

   ...
   pmi.set("test.property.name", "test");
   pmi.set("test.property.name", Integer.valueOf(100));
   ...
   pmi.get("test.property.name");
   ...
In case you need access to the PropertyResolver for tests, where a MixIn is not applicable, you can use TestPropertyResolver.INSTANCE and avoid setting command line parameters as shown below:
TestPropertyResolver.INSTANCE.getMap().put("name","value");