Append default namespace to non-qualified rule params.

Fixes 18.
diff --git a/README.md b/README.md
index 8146a55..6b596ec 100644
--- a/README.md
+++ b/README.md
@@ -147,8 +147,12 @@
 ow.rules.update({ruleName: '...', action: '...', trigger: '...'})
 ```
 
+`trigger` and `action` identifiers will have the default namespace (`/_/`)
+appended in the request, unless a fully qualified name is passed in
+(`/custom_ns/action_or_trigger_name`).
+
 The following optional parameters are supported:
-- `namespace` - set custom namespace for endpoint
+- `namespace` - set namespace for rule 
 
 ### enable & disable rule
 
diff --git a/lib/rules.js b/lib/rules.js
index c9849a5..f3b074a 100644
--- a/lib/rules.js
+++ b/lib/rules.js
@@ -32,12 +32,22 @@
     }
 
     const params = this.rule('PUT', options)
-    params.body = {action: options.action, trigger: options.trigger}
+    params.body = {action: this.convert_to_fqn(options.action), trigger: this.convert_to_fqn(options.trigger)}
     params.qs = this.qs(options, ['overwrite'])
 
     return this.request(params)
   }
 
+  // Convert resource identifier to fully qualified name (namespace + id).
+  // Returns default namespace if resource name is missing namespace.
+  convert_to_fqn (identifier) {
+    if (identifier.startsWith('/')) {
+      return identifier
+    }
+
+    return `/_/${identifier}`
+  }
+
   update (options) {
     options.overwrite = true
     return this.create(options)
diff --git a/test/integration/rules.test.js b/test/integration/rules.test.js
index 9473e2d..abc1c17 100644
--- a/test/integration/rules.test.js
+++ b/test/integration/rules.test.js
@@ -61,11 +61,11 @@
   }
 
   const rules = new Rules(params)
-  return rules.create({ruleName: 'random_rule_test', action: 'hello', trigger: 'sample'}).then(result => {
+  return rules.create({ruleName: 'random_rule_test', action: `/${NAMESPACE}/hello`, trigger: `/${NAMESPACE}/sample`}).then(result => {
     t.is(result.name, 'random_rule_test')
     t.is(result.namespace, NAMESPACE)
-    t.is(result.action, 'hello')
-    t.is(result.trigger, 'sample')
+    t.deepEqual(result.action, {path: NAMESPACE, name: 'hello'})
+    t.deepEqual(result.trigger, {path: NAMESPACE, name: 'sample'})
     return rules.get({ruleName: result.name}).then(rule_result => {
       t.is(rule_result.name, result.name)
       t.is(rule_result.namespace, NAMESPACE)
@@ -84,14 +84,14 @@
   }
 
   const rules = new Rules(params)
-  return rules.create({ruleName: 'random_update_test', action: 'hello', trigger: 'sample'}).then(result => {
+  return rules.create({ruleName: 'random_update_test', action: `/${NAMESPACE}/hello`, trigger: `/${NAMESPACE}/sample`}).then(result => {
     t.is(result.name, 'random_update_test')
     t.is(result.namespace, NAMESPACE)
-    t.is(result.action, 'hello')
-    t.is(result.trigger, 'sample')
+    t.deepEqual(result.action, {path: NAMESPACE, name: 'hello'})
+    t.deepEqual(result.trigger, {path: NAMESPACE, name: 'sample'})
     return rules.disable({ruleName: 'random_update_test'}).then(() => {
       return rules.update({ruleName: 'random_update_test', action: 'tests', trigger: 'sample'}).then(update_result => {
-        t.is(update_result.action, 'tests')
+        t.deepEqual(update_result.action, {path: NAMESPACE, name: 'tests'})
         t.pass()
         return rules.delete({ruleName: 'random_update_test'}).catch(errors)
       })
diff --git a/test/unit/rules.test.js b/test/unit/rules.test.js
index a71f1e6..72cbfc7 100644
--- a/test/unit/rules.test.js
+++ b/test/unit/rules.test.js
@@ -176,7 +176,7 @@
     t.is(req.url, `${params.api}namespaces/${params.namespace}/rules/${rule_name}`)
     t.is(req.headers.Authorization, `Basic ${new Buffer(params.api_key).toString('base64')}`)
     t.is(req.method, 'PUT')
-    t.deepEqual(req.body, {action: rule.action, trigger: rule.trigger})
+    t.deepEqual(req.body, {action: '/_/' + rule.action, trigger: '/_/' + rule.trigger})
     t.deepEqual(req.qs, {})
     return Promise.resolve()
   }
@@ -197,6 +197,27 @@
     t.is(req.url, `${params.api}namespaces/${namespace}/rules/${rule_name}`)
     t.is(req.headers.Authorization, `Basic ${new Buffer(params.api_key).toString('base64')}`)
     t.is(req.method, 'PUT')
+    t.deepEqual(req.body, {action: '/_/' + rule.action, trigger: '/_/' + rule.trigger})
+    t.deepEqual(req.qs, {overwrite: true})
+    return Promise.resolve()
+  }
+
+  t.plan(5)
+
+  const rules = new Rules(params)
+  return rules.create({ruleName: rule_name, namespace: 'provided', action: rule.action, trigger: rule.trigger, overwrite: true})
+})
+
+test('create a rule with fully qualifing action and trigger namespace', t => {
+  const params = {api: 'https://openwhisk.ng.bluemix.net/api/v1/', api_key: 'user_authorisation_key', namespace: 'default'}
+  const rule_name = 'rule_name'
+  const namespace = 'provided'
+  const rule = {version: '1.0.0', publish: true, trigger: '/a/trigger', action: '/b/action'}
+
+  stub.request = req => {
+    t.is(req.url, `${params.api}namespaces/${namespace}/rules/${rule_name}`)
+    t.is(req.headers.Authorization, `Basic ${new Buffer(params.api_key).toString('base64')}`)
+    t.is(req.method, 'PUT')
     t.deepEqual(req.body, {action: rule.action, trigger: rule.trigger})
     t.deepEqual(req.qs, {overwrite: true})
     return Promise.resolve()
@@ -261,7 +282,7 @@
     t.is(req.url, `${params.api}namespaces/${params.namespace}/rules/${rule_name}`)
     t.is(req.headers.Authorization, `Basic ${new Buffer(params.api_key).toString('base64')}`)
     t.is(req.method, 'PUT')
-    t.deepEqual(req.body, {action: rule.action, trigger: rule.trigger})
+    t.deepEqual(req.body, {action: '/_/' + rule.action, trigger: '/_/' + rule.trigger})
     t.deepEqual(req.qs, {overwrite: true})
     return Promise.resolve()
   }