OpenShift, express.js and spark.js — A bit farther

After work­ing with git, Open­Shift, node.js and all of the oth­er stuff from my last post to final­ly have a sim­ple “Hel­lo World”, I took the next step of actu­al­ly putting more than just a page with hel­lo world in my new appli­ca­tion.

  1. First I decid­ed to go with express.js as my start­ing point. I had already installed express.js to use, but they also have an express gen­er­a­tor that builds out a stan­dard appli­ca­tion with fold­er struc­ture and oth­er sup­port­ing items. You can find the details and install stuff here: http://expressjs.com/starter/generator.html
    1. If you installed express glob­al­ly, you might also need to install it in your app node_modules also after your run the gen­er­a­tor. If you try npm install after the gen­er­a­tor and you get a ton of errors cd into myapp/node_modules and npm install express into this loca­tion. Good info here: http://blog.nodejs.org/2011/03/23/npm-1–0-global-vs-local-installation .
  2. Now that I have a skele­ton, I need­ed to put it in my git repos­i­to­ry, not in its appli­ca­tion fold­er name like it was cre­at­ed. This ensures it goes into the cor­rect loca­tion when I com­mit to Open­Shift. Make sure you leave the .git and .open­shift in your repos­i­to­ry!
  3. Since I now have a new start­ing loca­tion, it was server.js as the Open­Shift stan­dard; I need­ed to update my package.json so the app starts where I need it to.

package.json

"name": "spark",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node ./bin/www"
},
"main": "./bin/www",

"dependencies": {
"express": "~4.9.0",
"body-parser": "~1.8.1",
"cookie-parser": "~1.3.3",
"morgan": "~1.3.0",
"serve-favicon": "~2.1.3",
"debug": "~2.0.0",
"jade": "~1.6.0"
}
}

4.  Also, the stan­dard www file in the express build needs to be updat­ed so it pulls in the envi­ron­men­tal vari­ables from Open­Shift.

./bin/www

#!/usr/bin/env node
var debug = require('debug')('spark');
var app = require('../app');
app.set('port', process.env.OPENSHIFT_NODEJS_PORT || 8080);
app.set('host', process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1");
var server = app.listen(app.get('port'), app.get('host'), function() {
debug('Express server listening on port ' + server.address().port);
});

The last two steps are well doc­u­ment­ed here: https://blog.openshift.com/run-your-nodejs-projects-on-openshift-in-two-simple-steps

Once you com­mit every­thing you should now see your com­plet­ed Wel­come to Express page and now you can start build­ing out your app!

This will be my start­ing point for inter­act­ing with my Spark.IO devices and work­ing with spark.js. Hope­ful­ly I will have some work­ing exam­ples soon!

AEM Resource Mapping and Apache mod_rewrite, Teamwork!

After spend­ing a few days (or weeks!) look­ing for infor­ma­tion relat­ed to hid­ing parts of URLs with Apache Web Serv­er and Adobe Expe­ri­ence Manger, I believe I may have pulled it all togeth­er. This is my attempt at explain­ing how it works.

First, what is going on between Brows­er, Web Serv­er, Cache and AEM?
rewrite_pic1

Out of the box, every­thing works due to the full path being used from the brows­er -> web serv­er -> cache and if a page is updat­ed the Flush­ing agent is able to inval­i­date the prop­er page due to the path being the same in AEM as in the cache.

Now, since I am a devel­op­er and I have access to cre­ate my own resource map­ping, I am going to add a con­fig­u­ra­tion and point a short­ened URL to my land­ing page.

Sling:internalRedirect     string     /content/geometrixx/$1

Sling:match                         string     site.com/en(.*)$

I save it, repli­cate it to pub­lish and try it out. Click, http://site.com/en.html, sweet it works. Wow that was easy, looks good, all done! Wait a minute, when I update the page it doesn’t seem to show up prop­er­ly to the user, what is going on?

Let’s take a look.

rewrite_pic2
Ok, so my Brows­er -> Web Serv­er -> Cache is all look­ing for site.com/en.html, and the map­ping in AEM points it to /content/geometrixx/en.html, so it works from that end, but my Flush­ing agent is inval­i­dat­ing /content/geometrixx/en.html in the cache, which nev­er exists! The cache is putting my page at /en.html! Well that works the first time, but if I need to update the page I will need to clear the cache every time and my Flush­ing Agent will be doing noth­ing for me.

Well scratch that, let me try to do this on the web serv­er. I think I remem­ber some­thing about RewriteRule…

RewriteRule ^/$ /content/geometrixx/en.html [PT]

Ok, now when some­thing comes in, it goes to my land­ing page and in the cor­rect cache fold­er.
rewrite_pic3
Nice! This works, the cache looks good and the Flush­ing agent can inval­i­date the page! So I click on anoth­er link on the page and then the whole path pops up again! I guess this is good enough, who real­ly looks at the URL once they are in the site any­ways. Said no cus­tomer ever….

Well, let’s try putting them togeth­er!
rewrite_pic4
This works on the ini­tial call and all fol­low­ing calls to en.html, but why? Here is the break­down.
First, you will notice the RewriteRule is slight­ly dif­fer­ent.

RewriteRule ^/content/geometrixx/ ^/$1 [PT]

This lets site.com/en.html through with no changes because it does not match the fil­ter and the map­ping in AEM points it to /content/geometrixx/en.html. When the Flush­ing Agent fires off, it hits the fil­ter in the web serv­er and is writ­ten to /en.html, so it inval­i­dates the prop­er page. So every­thing seems to work, the only issue is the caching does not reflect the fold­er struc­ture in AEM. If cache struc­ture is not a con­sid­er­a­tion for your project, then this solu­tion could work.

You will notice we only took one page, en.html, into con­sid­er­a­tion, along with only the con­tent fold­er. A final solu­tion for all assets is more com­plex and I am work­ing on a write up for it. Also, I am look­ing into only hav­ing set­ting on the web serv­er so I can keep every­thing in one spot.

Resources
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
http://www.wemblog.com/2012/07/how-to-use-dispatcher-with-mapped.html