Flex Pasta » 2008 » March
Cairngorm seems to be the architecture pattern of choice for flex. If you’re new to flex it certainly is a good way to keep you organized in your code layout. As you grow your code base flex can turn into spaghetti quickly if you don’t start out with a solid framework.
Here is what your typical Cairngorm structure might look like:
- Business - Contains the various services for Remote Object calls, Web Service calls, etc
- Command - Handles the formation of the Request/Response of these service calls.
- Control - Here lives the one and only Cairngorm controller class. Home of headaches and heartbreaks, this is where you map your events to command classes. The headaches and heartbreaks come into play when you forget to add your new event and commands to this class. When you finally figure it out, your mind repeats idiot idiot idiot idiot over and over again for a few minutes. But this goes to the root of the main con I see with Cairngorm…..keep reading.
- Domain - If you are using Remote Objects, you probably want to keep the matching actionscript classes in one place.
- Event - When a user interacts with your super cool app, events are fired off that cause other layout changes based on the user request. Biggest problem with Cairngorm is that you have to implement a clone method for each event, another piece of painful overhead.
- Model - Holds the data and states for the app.
- View - All datagrids, etc, that make up the user interface.
- Vo - Stores other objects similar to domain that organize data for easy use in the view.
So this all looks like good fun right???? Well yes, until your tasked with writing an app to takeover the world!! Well ok, maybe not take over the world but the app is going to be BIG! Lets just say your going to have 100 remote methods divided into 10 different parts of your app. Which since I made the math simple means you will have 100 event classes, 100 command classes, 10 model classes, 10 business classes, and a long control class, not to mention probably hundreds more view classes.
What does this mean for me?
- Order more ram for your pc. Java can compile one class and keep trucking, but actionscript into a swf requires more chips than a game of poker. 2GB minimum RAM if you are setting out on a big project.
- Start looking at a lot of busy work, creating the 200 event/command classes needed. Some people have even created Cairngen, a code generator for all those classes. This is my main issue with the framework. If your have to write a code generator for the framework, then the framework needs to be simplified!!
How to simplify Cairngorm?
Get rid of all the command classes, and almost all of the event classes. Continuing from the theme above: 100 remote methods in 10 remote classes(10 methods per class). Here are the steps to simplify:
- Create 10 interfaces in actionscript that will match your methods in your 10 remote classes. Put these in the “business” folder.
- Create a new folder called “request”. Create 10 classes called ‘RemoteServiceRequest’, each of which implement your 10 interfaces. This replaces what would be the “execute” method of a command class.
- Create a new folder called “response”. Create 10 classes called ‘RemoteServiceResponse’, each of which implement your 10 interfaces. This replaces what would be the “result” method of a command class.
- Create a new folder called “fault”. Create 10 classes called ‘RemoteServiceFault’, each of which implement your 10 interfaces. This replaces what would be the “fault” method of a command class.
So we are now looking at 40 classes in all and far less overhead to create them, add to them, and edit them because they all implement the interface classes you created. It is also more clear what remote methods you are calling, no guessing as to what command class goes with which remote method. More importantly, your code is still clear and has and organized framework. You still use the model in this framework, storing state and data objects. When you call a remote service, and you need other view functionality changes, you can still dispatch a normal flash event for this. This approach outlined is a significant departure from Cairngorm. In fact, it deserves its own name. Let’s call it the Penne Framework. Look for more about the Penne Framework on my blog in the future(and maybe even some real live code!).
Conclusion
The Cairngorm framework is a well thought out architecture for flex applications. It provides good separation of responsibilities for your code. For larger projects, it can create a lot of overhead in the number of classes needed to support this approach. The Penne Framework provides a simplified alternative for large scale flex projects. Look for more on the Penne Framework in the future!!
You’ve just set up your flex-java project using BlazeDS AMF. You’ve got some classes in java which have matching actionscript classes that have the magic “RemoteClass” tag to tell the bean proxy where to find your class. Everything is working well and then you have a thought, how in the world can I make this flex app secure? With remote classes in actionscript, your application is more wide open then any jsp application. Someone with the right knowledge can decompile your swf and see the classes, giving out a blue print to your application’s architecture.
BlazeDS and Security
BlazeDS uses the PropertyDescriptor class when going from java to actionscript. Basically, this means for each getter and setter you have in java, BlazeDS is going to pick this up via reflection and serialize the data to AMF output to the client. If you have a getter, but no setter in java, it won’t be read by BlazeDS. Keep in mind that regardless of what is in your actionscript class, all data returned from your java service will be sent back over the wire to the client flex app.
Where do I start?
Let’s assume you have a java class called Customer. Customer.java has 3 getters and setters for id(the primary key), username, and password. You have a simple flex app that allows you to change your password. When the customer changes their password, you send off a remote call to your java service updateCustomer(). Without getting into whether you are using hibernate or some other database access method, we’ll assume that in the end your updateCustomer() method executes this following query: update customer set username=’admin’, password=’password1′ where id=1. Excellent right? Everything works. You have to assume however, that any flex app, can send any request it wants, regardless of what safeguards you have in place in actionscript. Pretend now that hacker Joe comes along and starts snooping your remote classes. He notices your actionscript class “Customer” being sent over the wire calling the updatePassword() method. Joe then modifies the customer.id to 2 and the username and password of his choice. The update query runs and now hacker Joe is able to login to another user’s account using his own username and password! UH OH!!!!! In a JSP/HTML app you might already have the customer stored in a session, so you would never be passing the customer.id over the wire and would not have to worry about this type of tampering. With actionscript and remote objects, it is all there in the open. How do you tackle securing the flex app?
1. Secure the primary keys
- Store at least the primary key in Session on the way out from java to flex. When you get the request from flex to java, check to make sure the user has access to the primary key they are trying to change.
2. Secure the foreign keys
-Other classes will probably have your customer.id as a foreign key in their class. Make sure these are secure from tampering as well.
3. Secure your remote methods that flex will be calling
-Use remoting-config.xml to exclude methods that the user should not have access to. One way to this:
<destination id=”customerService”>
<properties>
<source>customerService</source>
</properties>
<exclude-methods>
<method name=”updateCustomer” security-constraint=”admin-users”/>
</exclude-methods>
</destination>
You can read more about this in the BlazeDS dev guide.
4. Secure any other fields that are sensistive and should not be able to be changed by the end user.
Conclusion
BlazeDS does contain some features to help secure your flex app. It still lacks a strong security model for securing bean classes. Most of the work for security will need to be done by an app by app basis. Think about security during your design in the beginning. Flex is more open than many realize and it only takes one bad hacker Joe to poke a hole in your app. Have someone dedicated to specifically laying out a security design and have checkpoints to ensure standards are met.
So you’re coding up your flex app and you want to pass a url parameter into your application. Like getting the color parameter from mydomain.com?color=red. While one option is to call the built in flex option of Application.application.parameters, this will only work if your example points directly to the swf. If your url is main.swf?color=red then Application.application.parameters.color will work fine for you. However, if like most people, have the swf wrapped in an html page(main.html?color=red), this approach won’t work. I ran into this problem myself, and I didn’t want to get into the messy business of editing the flash vars, especially if I had a large number of parameters or wanted to add more on the fly later. I created a HTTPUtil class in actionscript to get the url information. The class uses javascript to get all of the url information, including host name, port, and url parameters among other things. The most helpful method you will find is getParameterValue(key:String):String which will give you back the parameter value for the given key.
Have multiple environments and need to get the full url with the host name and port in actionscript?
There are several methods to help with this:
getHostName()
getPort()
getProtocol() -such as http or https
getContext() -The path after the hostname but before the url parameters
Attached is the source. You can see that the methods are all static and use javascript to get the information back to flex. It is designed to get this information regardless of where the flex swf file lives since most people have them embeded in an html file.
Simple string manipulation is done on a daily basis in any language including flex. By using utility classes, you can reduce simple code errors and increase readability. I find the mx.utils.StringUtil could use a little more muscle than the 4 methods given out of the box. Downloadable is my own StringUtil class that beefs up the support for common string functions. The additions are based on the methods found in Apache Commons Lang open source code that includes a popular org.apache.commons.lang.StringUtils class.
Here is a summary of some of the methods you will find:
isEmpty : Checks if a String is empty (”") or null.
isNotEmpty : Checks if a String is empty (”") or null.
isBlank : Checks if a String is whitespace, empty (”") or null.
isNotBlank : Checks if a String is not whitespace, empty (”") or null.
defaultIfEmpty : Returns either the passed in String, or if the String is empty or null, the value of defaultStr.
If you have a String Utility method for flex/actionscript, post it!