Skip to content

Latest commit

 

History

History
296 lines (234 loc) · 13 KB

README.adoc

File metadata and controls

296 lines (234 loc) · 13 KB

Live application

Checkout the live application here: https://microprofile.io/

How to build and run the application locally?

Simply run mvn clean install tomee:run. Your server will be available at http://localhost:8080/

If you want to the GitHub integration to work, you will need a microprofile github access token, (Documentation on how to do this). Set the microprofile_github_atoken value in src/main/resources/base.properties. When you generate that token Github will present you with a list of 20+ possible permissions. No special permission required.

If you are making changes to the microprofile.io configuration repo, you can test that by having your local copy point to your forked version where the changes live. Simply edit src/main/resources/base.properties and change the default microprofile_config_root=microprofile/microprofile.io to the individual’s repo who filed the microprofile.io pull request. For example microprofile_config_root=ivannov/microprofile.io is how you would point to https://github.com/ivannov/microprofile.io

Example of src/main/resources/base.properties

microprofile_blog_root=microprofile/microprofile-blog
microprofile_config_root=microprofile/microprofile-site-config
microprofile_github_atoken=<your token here>

Node.js and Gulp

This application heavily depends on node.js and gulp to build all the static resources. These tools will execute tons of actions not yet available in the java world; at least not as handy as available on node.js. The good news is that we don’t need to worry about a thing. It will feel like any regular maven project. mvn clean install tomee:run will perform all the heavy lifting. It downloads the dependencies and executes node.js, gulp and the tomee server.

What about front-end development?

Front-end developers don’t need to restart servers. In fact, front-end developers don’t like to waste a single second waiting for a JS change to be reflected on a web application. This is what make web development fun.

Our application uses Jade, Sass, Autoprefixer, Sprity, Bower, JsLint, UglifyJs, SourceMaps. Obviously, we have a lot of work to do before making a static change visible in the web site.

In order to make it automatic, run mvn frontend:gulp in another terminal. It will trigger the default gulp task, which will watch for changes on src/main/static/ and updates the running tomee instance accordingly as soon as a static change is detected.

tveronezi@ubatuba:microprofile.io$ mvn frontend:gulp
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building microprofile :: IO :: Website 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- frontend-maven-plugin:0.0.26:gulp (default-cli) @ microprofile ---
[INFO] Running 'gulp.js --no-color' in /home/tveronezi/Documents/development/sources/microprofile.io/src/main/static
[INFO] [10:49:45] Using gulpfile ~/Documents/development/sources/microprofile.io/src/main/static/gulpfile.js
[INFO] [10:49:45] Starting 'sync group6:0'...
[INFO] [10:49:45] Starting 'sync group5:0'...
[INFO] [10:49:45] Starting 'clean'...
...
[INFO] [10:49:49] Finished 'default' after 43 ms

Unit testing

We have two types of tests: backend and frontend. The frontend testing is somewhat special because it uses karma. It’s transparent for the devepolers because both tests are triggered by the same mvn clean install.

Sometimes we are interested on frontend testing only. We can do it by executing 'mvn frontend:karma'.

tveronezi@ubatuba:microprofile.io$ mvn frontend:karma
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building microprofile :: IO :: Website 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- frontend-maven-plugin:0.0.26:karma (default-cli) @ microprofile ---
[INFO] Running 'karma start karma.conf.js --no-colors' in /home/tveronezi/Documents/development/sources/microprofile.io/src/main/static
[INFO] 08 10 2015 10:07:33.166:WARN [karma]: No captured browser, open http://localhost:9876/
[INFO] 08 10 2015 10:07:33.177:INFO [karma]: Karma v0.13.10 server started at http://localhost:9876/
[INFO] 08 10 2015 10:07:33.183:INFO [launcher]: Starting browser PhantomJS
[INFO] 08 10 2015 10:07:33.421:INFO [PhantomJS 1.9.8 (Linux 0.0.0)]: Connected on socket 69XcpjL1trQ7xnP6AAAA with id 41615709
       PhantomJS 1.9.8 (Linux 0.0.0): Executed 1 of 1 SUCCESS (0.039 secs / 0.009 secs)

TODO: Link below is incorrect

The default browser is PhantomJS. In order to debug with the help of a real browser, uncomment this line in karma.conf.js

// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
    // 'Chrome', // uncomment me for local unit testing [not in a headless server]
    'PhantomJS'
],

When you execute mvn frontend:karma, a browser window will popup.

How to publish content?

Some of the content of this application is based on another Github project: https://github.com/microprofile/microprofile-site-config. In order to publish a new project, simply add a new line in site.yaml. The changes will be live after 5 minutes.

Production Architecture

Summary

Clouldflare sits in front of our website as a CDN and proxy. By setting our NS records to point at Cloudflare, Clouldflare automagically handles content distribution around the world by scraping our website. If Cloudflare cannot handle the request, it will hand the request off to the Amazon ELB. The Amazon ELB points at EC2 instances created by an autoscaling group. The isntances are running the Amazon Beanstalk Agent. The autoscaling group maintains a minimum of 1 instance. If the autoscaling group notices the servers are too busy, it’ll add instances. When a new instance is launched, the Amazon Beanstalk Agent on the instance notifies the Beanstalk Cluster that it’s available to take a task. The Beanstalk Cluster will then deploy the new zip file to the instance, and notify the ELB to start sending traffic to the new instance. The ELB will start sending traffic to the new instance once the instance begins passing health checks.

Cloudflare CDN

DNS

[User Agent] -DNS Query-> [Cloudflare NS]
[User Agent] <-DNS Response to closest Cloudflare server- [Cloudflare NS]

HTTP

[User Agent] -HTTP Request-> [Cloudflare HTTP Servers]
If static asset:
[User Agent] <-HTTP Response- [Cloudflare Cache server]
If non-static asset:
[User Agent] <-HTTP Response- [Cloudflare Proxy server] <-HTTP Response- [Amazon Elastic Load Balancer]

Amazon Architecture

[Elastic Load Balancer] |-> [Active Instances Subnet0] -> [JVM Instance]
                        |-> [Active Instances Subnet1] -> [JVM Instance]

Deployment

The deploy process creates a zip file which has the executable jar, and bundles several AWS config files.

Prerequisites

  • Request an AWS Access Key ID and Secret Access Key for the Microprofile account.

  • Request the GitHub token.

Setup

You should install the amazon command line tools using your package manager. Setup your .aws directory and credentials file: http://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html

Clone the source for this project to your local drive and cd to that directory.

Run the command:

$ mvn clean package

Note: this takes a while to run and may appear to hang, but it is actually working.

Test your credentials by issuing this command:

$ eb list

If everything worked correctly, you should see:

microprofile-io-env

Build and deploy manually

Note Before running this command, one should make sure microprofile_github_atoken in src/main/resources/base.properties is set to a production value, or should override it using one of the ways afforded by the Sabot project.

mvn clean package tomee:exec assembly:single && eb deploy microprofile-io-env

Note If the contributors page is broken, it’s likely because you did not set the microprofile_github_atoken.

Config file descriptions

src/main/config/haproxy.cfg

This is a simple HAProxy installation that redirects www.microprofile.io to microprofile.io This is running on an independent instance in AWS.

src/main/config/ebextensions

This directory is filtered and copied to /.ebextensions in the root of the assembled ZIP archive. It is not part of the JAR. These files configure the Elastic Beanstalk cluster.

src/main/config/elasticbeanstalk

This directory is filtered and copied to .elasticbeanstalk in the root the maven project. It is not part of the JAR nor the ZIP. These files configure the deployment process to Elastic Beanstalk.

src/main/config/ziproot

This directory is filtered and copied to / in the root of the assembled ZIP archive.

  • Procfile tells the AWS Agent what command to run to launch your deployment. It launches the next script:

  • kill-before-run.sh ensures that all existing Java processes have been terminated before launching the new Java archive. This is sort of a hack, if someone has a better way to do this, it’d be much appreciated.

Creating a new html page

diff --git a/src/main/static/assets/scripts/_main.ts b/src/main/static/assets/scripts/_main.ts
index f6c3f60..1cb462d 100644
--- a/src/main/static/assets/scripts/_main.ts
+++ b/src/main/static/assets/scripts/_main.ts
@@ -38,6 +38,12 @@ angular.module('microprofileio-main', [
                         menu.setSelected('docs');
                     }]
                 })
+                .when('/new_page', {
+                    templateUrl: 'app/templates/page_new_page.html',
+                    controller: ['microprofileioMenuService', function (menu) {
+                        menu.setSelected('new_page');
+                    }]
+                })
                 .when('/contributors', {
                     templateUrl: 'app/templates/page_contributors.html',
                     controller: ['microprofileioMenuService', function (menu) {
diff --git a/src/main/static/assets/styles/app.sass b/src/main/static/assets/styles/app.sass
index a4ed22e..8696228 100644
--- a/src/main/static/assets/styles/app.sass
+++ b/src/main/static/assets/styles/app.sass
@@ -50,6 +50,7 @@ body
     @import "page_project"
     @import "page_documents"
     @import "page_pages"
+    @import "page_new_page"

 i[microprofileio-share-project]:hover
   color: $app-hover-color
diff --git a/src/main/static/assets/styles/page_new_page.sass b/src/main/static/assets/styles/page_new_page.sass
new file mode 100644
index 0000000..59b6256
--- /dev/null
+++ b/src/main/static/assets/styles/page_new_page.sass
@@ -0,0 +1,4 @@
+@import "variables"
+
+> div.page-body.new_page
+  background-color: blue
diff --git a/src/main/static/assets/templates/dir_menu.jade b/src/main/static/assets/templates/dir_menu.jade
index 11da079..c60584e 100644
--- a/src/main/static/assets/templates/dir_menu.jade
+++ b/src/main/static/assets/templates/dir_menu.jade
@@ -5,6 +5,8 @@ div
     li
       a(href="projects") Projects
     li
+      a(href="new_page") New Page
+    li
       a(href="presentations") Presentations
     li
       a(href="faq") Faq
diff --git a/src/main/static/assets/templates/page_new_page.jade b/src/main/static/assets/templates/page_new_page.jade
new file mode 100644
index 0000000..fed4080
--- /dev/null
+++ b/src/main/static/assets/templates/page_new_page.jade
@@ -0,0 +1,6 @@
+microprofileio-header.new_page
+    h1 New Page
+.page-body.new_page
+    div
+        p New Page content
+microprofileio-footer

You will need to add a new route entry with the .when('/new_page', {…​} line, include the new page in the menu with a(href="new_page") New Page and add the new page (Example: /src/main/static/assets/templates/page_new_page.jade).

For the styles, make sure you can identify the parts you want to apply new styles with a easy css selector. In the case above we use div.page-body.new_page as we used it in our new page_new_page.jade code. Create a new sass file (Example: /src/main/static/assets/styles/page_new_page.sass) and include it as @import in the main app.sass file.