vendredi 7 novembre 2014

How to deploy wisdom application to AWS Beanstalk using Docker


Today I'd like to demonstrate how to deploy a wisdom application on AWS BeanStalk using Docker. The goal is to be able to update your current deployed app in one maven command. Maybe you want first to check some points 

Create your Wisdom app

In order to create a new app just do :
mvn org.wisdom-framework:wisdom-maven-plugin:0.6.5:create \
-DgroupId=YOUR_GROUPID \
 -DartifactId=YOUR_ARTIFACTID \
 -Dversion=1.0-SNAPSHOT
congratulation you have now a cool app ! You can try it :
mvn wisdom:run
To package your application run :
mvn clean package
It packages your app inside a zip into target/yourApp-version.zip, this is the zip to deploy in the server.

Add a Dockerfile

If you want to use Docker, there is no magic trick, create a Dockerfile at the root directory of your app (next to your pom.xml).
FROM dockerfile/java:oracle-java8

# Add the wisdom distribution
ADD . /root/wisdom

# Expose the port 9000
EXPOSE 9000

# Volumes
VOLUME /root/wisdom/logs
VOLUME /root/wisdom/application

# Change workdir.
WORKDIR /root/wisdom

RUN touch /root/wisdom.log

# For easier handling, we dump the log, so `docker logs containerId` displays
# the log.
CMD chmod +x chameleon.sh; ./chameleon.sh stop;./chameleon.sh start; tail -F logs/wisdom.log
To include the Dockerfile inside the .zip of your packaged app you have to add the following resources tag inside your pom.xml between the build tag :
<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>${project.basedir}</directory>
            <includes>
                <include>Dockerfile</include>
            </includes>
            <targetPath>${project.build.directory}/wisdom</targetPath>
        </resource>
    </resources>
    ...
</build>
run again
mvn clean package
If you open the zip file the Dockerfile is now present.

Create a cool Beanstalk application

From here I suppose you already have a AWS access and you are able to create a BeanStalk app.
  • From AWS console go to Elastic Beanstalk
  • Create a new application and fill the name and click next
  • Environment type
    • Environment tier > Web server
    • Predefined configuration > Docker
    • Environment type > single instance
  • Application version > Upload your own > select the zip file of your packaged app
  • Environment information > put what you want
  • Additional resources > just click next (or configure following your requierments)
  • Configuration details > just click next (or configure following your requierments)
  • Environment tags > just click next (or configure following your requierments)
  • And LAUNCH
That it ! Wait a moment while beanstalk creates your application. Once it's done just check your app and you should see the wisdom sample page ! If not... Sorry you probably missed something

BUT WAIT !! I DON'T WANT TO UPLOAD MY ZIP BY HAND EACH TIME !!!

I know ! As I promised, it's time to reduce the heavy uploading step by a single maven command. Take a look at Beanstalker maven plugin it does all the boring part for you.
First, follow the Setting Up Credential part to configue your access and secret key.
next add the following profile to your pom.xml
<profiles>
    <profile>
        <id>deploy</id>
        <properties>
            <beanstalker-serverId>aws.amazon.com</beanstalker-serverId>
            <beanstalker.region>eu-west-1</beanstalker.region>
            <maven.install.skip>true</maven.install.skip>
            <maven.deploy.skip>true</maven.deploy.skip>
            <beanstalk.applicationName>test</beanstalk.applicationName>
            <beanstalk.cnamePrefix>test-env</beanstalk.cnamePrefix>    //This is the first part of your env url  test-env.elasticbeanstalk.com
            <beanstalk.environmentName>Test-env</beanstalk.environmentName>
            <maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
            <beanstalk.s3Bucket>application-version</beanstalk.s3Bucket>  // The name of your S3 bucket which will contain every version uploaded
            <beanstalk.s3Key>${project.build.finalName}.zip</beanstalk.s3Key>  //The name of the zip to upload
            <beanstalk.multipartUpload>false</beanstalk.multipartUpload>
            <beanstalk.useLatestVersion>false</beanstalk.useLatestVersion>
        </properties>
        <build>
            <defaultGoal>deploy</defaultGoal>
            <finalName>${project.name}-${project.version}</finalName>
            <plugins>
                <plugin>
                    <groupId>br.com.ingenieux</groupId>
                    <artifactId>beanstalk-maven-plugin</artifactId>
                    <version>1.3.5</version>
                    <executions>
                        <execution>
                            <id>default-deploy</id>
                            <phase>deploy</phase>
                            <goals>
                                <goal>upload-source-bundle</goal>
                                <goal>delete-application-version</goal>  //delete the application version on beanstalk if it already exist (useful for snapshot)
                                <goal>create-application-version</goal>
                                <goal>update-environment</goal>
                            </goals>
                            <configuration>
                                <artifactFile>${project.build.directory}/${project.name}-${project.version}.zip
                                </artifactFile>
                                <skipExisting>false</skipExisting>
                                <environmentRef>cloudtest-env.elasticbeanstalk.com</environmentRef>
                                <optionSettings>                           //This part does nothing but I get NulPointer if I don't put anything here
                                    <setting>
                                        <namespace>aws:elasticbeanstalk:application</namespace>
                                        <optionName>Application Healthcheck URL</optionName>
                                        <value>/ping</value>
                                    </setting>
                                </optionSettings>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>
Now you just have to run :
mvn -Pdeploy
Wait and... Voila !

vendredi 3 octobre 2014

JavaFX persistence made easy with JCROMfx

Persisting model classes with JavaFX properties using hibernate is not impossible but requires some efforts. You can either use the "property access" (as described here) or map and bind all JavaFX fields to good old java fields. Both approaches have major drawbacks. Persisting JavaFX collections is almost impossible with the first approach and the second approach involve writing a lot a boiler code and to register tons of listeners to maintain the state between the JavaFX fields and their corresponding Java fields.

We recently decided to test a new persistence solution: Java Content Repository and especially the ModeShape implementation. Java Content Repository are designed to store content and metadata about this content. It looks like they are a good solution to persist application data, especially if you are manipulating lot of files and binary data.

The tree structure of a Java Content Repository allow a pretty simple mapping of graphs of Java objects. Mapping can be done either manually or using an object mapping framework. It looks like that one of the most used JCR mapping framework is JCROMJCROM is described as a lightweight framework for mapping Java objects to/from a Java Content Repository (JCR). 

JCROM was initially designed to handle most basic Java types but it was in 2008 when JavaFX did not exist! So we forked this excellent project and tried to extend it to support JavaFX properties...and it turned out to be pretty easy, even for JavaFX collections.

So we are pleased to announce that you can use JCROMfx to map your Java objects with JavaFX properties directly to/from a JCR repository! Just annotate your JavaFX properties and you are ready to persist them. This include all basic JavaFX properties (StringProperty, IntegerProperty,...), collections (ListProperty, MapProperty) and object properties of enum or of other objects (using @JcrChildNode)

Just to give you an overview of how a bean looks like with JCROM annotation & JavaFX properties : 

Feedback is welcome :)

mardi 23 septembre 2014

FXForm2 sampler

We are pleased to announce that we provide now some FXForm2 samples using the FXSampler.

These samples were designed to help you using FXForm2 and to discover all of its features. FXForm2 can be highly customized to generate most of the forms you need; this sampler should help you to understand which features you need and how to configure your form.

We have covered some frequent cases we use here at dooApp, but feel free to ask for more examples!

How to test it?

  • Clone the FXForm2 repo
  • Run mvn exec:java in the samples directory
  • Enjoy
There is some capture




jeudi 24 juillet 2014

Wisdom framework with apache shiro

Today, we'll see how to use Wisdom framework with apache shiro to manage users authentication.

First, what is Wisdom ?

Wisdom is a young but promising Java web framework, to develope quickcly modular and dynamic web applications. You can check Wisdom website for more informations.

Unfortunaly it does not include yet users management. That's why I decided to try to embed apache shiro inside my project.

The goal is to manage multiple users with different roles and to be able to authenticate them and display different template according to their roles.

In this example I create some users during shiro initialisation, but in the next article I'll use a real database.

The sample project is available here

Now let's take a look at the code.

First the ShiroActivator class used to initialize shiro

This is just basic stuff here, it create 2 roles and 2 users. Just with this, you're done ! you can use shiro now.

Then when you submit your form login this route will be called.

As you can see it's really simple, in 3 lines of codes you're authenticated. The exceptions here will display a flash message on the view in case of error like wrong password.

Once you're logged you'll be redirected to the protected page which displays different content whether you are admin or not.

But how is the route protected if you're not logged ?
Here I do a combination of wisdom and shiro features. This is my protected route :

As you can see there is an annotation @Authenticated. It comes from wisdom. You have to specify the name of your authenticator implementation. This is mine

So in the getUsername() method, I simply use shiro to retrieve the current user, if it returns null, so you're not logged and the onUnauthorized method will be called. Otherwise the controller route will be executed correctly.

Once you're logged, you'll have a different message if you're admin or guest. To achieve this I add some if statements in my template.

As you can see on the ProtectedController, on method return we have a new UserHelper in our parameters. that mean you will be able to call methods of this class on our template to check the role of the current user.
So your template will know which statement to use depending of the user role.
This is everything you need. I let you check by yourself on the sample project the logout method cause it's not really complicated.

Have fun with this great framework !