Affichage des articles dont le libellé est wisdom. Afficher tous les articles
Affichage des articles dont le libellé est wisdom. Afficher tous les articles

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 !

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 !