Using LCDS runtime configurations with CF8
Before LCDS 2.5 came out, each time we needed a new destination, we had to change one of the configuration files (data-management, remoting, messaging or proxy) and then restart the server so we could use it in our applications. In LCDS 2.5, this new feature allow us to create new destinations without having to restart the server or configure any xml file.
Unfortunately, CF8 doesn't provide any specific API to do this but, when using LCDS merged with CF8, we can use the JAVA classes to create those destinations.
Using the Tom Jordahl CRM example as reference, when we have a destination like this
<adapter ref="coldfusion-dao" />
<channels>
<channel ref="cf-rtmp"/>
<channel ref="cf-polling-amf" />
</channels>
<properties>
<component>samples.crm.EmployeeAssembler</component>
<scope>request</scope>
<metadata>
<identity property="employeeId" />
<one-to-one property="company" destination="cfcompany" lazy="true"/>
</metadata>
</properties>
</destination>
the same can be achieved at runtime this way
<cfset broker = brokerClass.getMessageBroker( javacast('null','') )>
<cfset service = broker.getService('data-service')>
<cfset destination = service.createDestination('cfemployee')>
<cfset destination.createAdapter('coldfusion-dao')>
<cfset configMap = createObject('java','flex.messaging.config.ConfigMap').init()>
<cfset configMap.addProperty('component','samples.crm.EmployeeAssembler')>
<cfset configMap.addProperty('scope','Application')>
<cfset adapter = destination.getAdapter()>
<cfset adapter.initialize('coldfusion-dao',configMap)>
<!--- start of channels --->
<cfset destination.addChannel('cf-rtmp')>
<cfset destination.addChannel('cf-polling-amf')>
<!--- end of channels --->
<!--- start of metadata --->
<cfset metadata = createObject('java','flex.data.config.MetadataSettings').init()>
<!--- Identity field --->
<cfset metadata.addIdentityPropertyName( 'employeeId' )>
<!--- Associations : one-to-one, one-to-many --->
<cfset Association = createObject('java','flex.data.config.AssociationSetting').init('one-to-one','company','cfcompany')>
<cfset Association.setLazy( true )>
<cfset Association.setCacheReferencedItems( false )>
<cfset metadata.addAssociationSetting( Association )>
<!--- end of metadata --->
<cfset destination.setMetadataSettings( metadata )>
<cfset destination.start()>
We first invoke the broker which is the responsible for all destinations. Then we get the service where we want to store our new destination. The data-service value correspond to the id in the service node in the data-management-config.xml. So if we wanted to add a new messaging destination we would use 'message-service' instead. We initialize the destination by creating a new adapter and injecting a configMap which carries that destination configuration.
We add the channels that will be available for that destination.
The metadataSettings object is where we are going to define all primary keys and relationships between destinations.
After assigning the metadata, we can start the destination and use it.
in the flex side, we just have to use this code to use the brand new destination.
cs = new ChannelSet();
cs.addChannel( new RTMPChannel('cf-rtmp','rtmp://{server.name}:2048') );
cs.addChannel( new AMFChannel('cf-polling-amf','http://{server.name}/flex2gateway/cfamfpolling') );
dsEmployee.channelSet = cs;
dsEmployee.fill( someArrayCollection [ , your arguments here ]);
One thing that you must be aware is that each destination must have an unique name so you should check first with the API if there is already a destination running under that name.


I've been looking for something like this solution for quite some time... I was really happy to find this!
However, I'm a bit confused at the instantiation of the destinations. If I have CFC assembler/DAO/VO setup to be called, at where/when would you call the CF code to create the dynamic destination.
i've got a project with 77 destinations setup right now, and I'm having a horrible time figuring out how to use those dynamically, so in the event I want to setup a second version of the app with a new database, I can simply change the datasource on the cfquery calls inside the DAO cfc's. Problem is that there is no concept of "state" when calling from Flex, so I can't just set a session or application variable with this information.
Second thought was to pass in a variable to be used as datasource through each of the fill/get calls, but I don't have any control of sync/update methods from Flex, so this idea would only work on the fill/get.
Finding your post on this was a result of the thought process of creating destination's dynamically as the Flex app loads, pointing to a different set of Assemblers/DAO CFC's depending on version. However, as per my initial question at the top of this comment, I'm not sure how this would work.
Sorry for the long-winded post, but hopefully you can offer some insight on this :-)
Thanks!
Brendan