tck-lambdas 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c61dd189f557744f188d942c50b07ea1e1c1843b
4
- data.tar.gz: 047c35b22c77f15ff2164f3e5e677f1d77c69d32
3
+ metadata.gz: 001e87d8e5dd72a88c0f00dd71add5f25d9c42b3
4
+ data.tar.gz: 3f0c00c70b605ba3fe112ca5e8ecc29f9bf3972d
5
5
  SHA512:
6
- metadata.gz: be15a18f604cf72e2efb8dad9b1d13015b15c3aeee01a0347963f9e5b9506799f5cd8801010748bd98813f84b2aee2477450dc291a5e4bc0d4041cadf211f491
7
- data.tar.gz: acd672f52eca004beee5f72fba7acb52398479c96b6118cc634f07e2f31a793e586326ab470262e42230999928dda581fee1f59ca880865659e5c689dbc8b477
6
+ metadata.gz: d96d1df1677df8fbe282b008172c2d907986ce7b536fa18f14fa89182d820c55f42d906bb8f46a276b7036a31acf1d8cac40129746fe964a4959c9988fb8da22
7
+ data.tar.gz: 72ccc188951e708880389dd7544629f2d1cd2012522078a95f525cecb26d50091dd1708ffcaead1836ee1043d36ac3bcc04232e6b99c9dcdcddce7ed8aef351c
data/README.md CHANGED
@@ -16,18 +16,49 @@ Si sólo tenemos esa _lambda_ en el proyecto, creando el _alias_ necesario en nu
16
16
 
17
17
  $ rake deploy_lambda
18
18
 
19
- Usando una _lambda_
20
- -------------------
19
+ Comandos de _tck-lambdas_
20
+ -------------------------
21
21
 
22
- Vamos a meter un _formulario de contacto_ en nuestro **proyecto Amazing** y queremos usar la *lambda contact_form*. Instalamos la _gema Tck::Lambdas_ y le indicamos que nuestro proyecto hace uso de la _lambda_ llamada *contact_form*:
22
+ Si lanzamos su ayuda nos cuenta lo siguiente:
23
+
24
+ $ tck-lambdas help
25
+ Commands:
26
+ tck-lambdas all # List all AWS Lambdas currently available in tck-lambdas.
27
+ tck-lambdas help [COMMAND] # Describe available commands or one specific command
28
+ tck-lambdas roles # List current AWS IAM roles (running 'aws iam list-roles [...]').
29
+ tck-lambdas use NAME # Use the AWS Lambda function known as NAME at The Cocktail.
30
+ tck-lambdas used # List functions currently used by this project.
31
+
32
+ **GOTCHA**: Tenemos también el *indocumentado comando* ``tck-lambdas list``, que es un _alias_ de ``tck-lambdas used``, **NO** de ``tck-lambdas all`` :)
33
+
34
+ Caso de Uso: *lambda contact_form*
35
+ ----------------------------------
36
+
37
+ Vamos a meter un _formulario de contacto_ en nuestro proyecto **Amazing** y queremos usar la *lambda contact_form*. Instalamos la _gema Tck::Lambdas_ y le indicamos que nuestro proyecto hace uso de la _lambda_ llamada *contact_form*:
23
38
 
24
39
  $ echo "gem 'tck-lambdas'" >> Gemfile # Metemos la gema en nuestro Gemfile...
25
40
  $ bundle # - la instalamos...
26
41
  $ cp Rakefile Rakefile.orig # - nos guardamos nuestro Rakefile...
27
- $ bundle exec tck-lambdas use contact_form # - y usamos la lambda:
28
- => lambdas/contact_form/ created with the lambda sources & tests.
29
- => task/lambdas/contact_form.rake created with common tasks.
30
- => .lambdas.yml created with the contact_form lambda conf.
42
+ $ tck-lambdas use contact_form # - y usamos la lambda:
43
+ /usr/lib/ruby/gems/[...]/lib/tck/lambdas/contact_form
44
+ create Rakefile
45
+ create Gemfile.example
46
+ create .lambdas.yml
47
+ create lib/tasks/lambdas.rake
48
+ create lib/tck/lambdas/aws_function.rb
49
+ create lambdas/test.rb
50
+ create lambdas/contact_form
51
+ create lambdas/contact_form/source/conf.js
52
+ create lambdas/contact_form/source/contact_form.js
53
+ create lambdas/contact_form/source/utils.js
54
+ create lambdas/contact_form/test/failed/domain_empty.json
55
+ create lambdas/contact_form/test/failed/domain_not_found.json
56
+ create lambdas/contact_form/test/failed/email_empty.json
57
+ create lambdas/contact_form/test/failed/email_format.json
58
+ create lambdas/contact_form/test/failed/message_empty.json
59
+ create lambdas/contact_form/test/succeeded/basic.json
60
+ create lambdas/contact_form/test/succeeded/with_cc.json
61
+ $
31
62
 
32
63
  Tal y como nos avisa ha creado, entre otras cosas, el fichero *.lambdas.yml* con la configuración para nuestra función _lambda_ con el siguiente contenido:
33
64
 
@@ -38,18 +69,17 @@ Tal y como nos avisa ha creado, entre otras cosas, el fichero *.lambdas.yml* con
38
69
  memory-size: 128
39
70
  runtime: nodejs4.3
40
71
  role: lambda_contact_form_role
72
+ description: Project-Name instance of the Tck's contact_form lambda
41
73
 
42
- Todos los valores por defecto deberían ser válidos excepto el nombre de la función (_function-name_), su manejador (_handler_), y su rol.
74
+ Todos los valores por defecto deberían ser válidos excepto el nombre de la función (_function-name_), su manejador (_handler_), y su rol (_role_).
43
75
 
44
76
  En el nombre de la función y su manejador tenemos que sustituir *project_name* por el nombre de nuestro proyecto (quedándonos con *amazing_contact_form* y *amazing_contact_form.handler* respectivamente).
45
77
 
46
- El rol tenemos que sustituirlo por **el _ARN_ completo** de un rol que tenga permisos para ejecutar los servicios que necesite nuestra _lambda_. El _ARN_ correspondiente lo podemos obtener desde la línea de comandos con ``aws iam list-roles``:
47
-
48
- aws iam list-roles --query "Roles[].[RoleName,Arn]"
78
+ El rol tenemos que sustituirlo por **el _ARN_ completo** de un rol que tenga permisos para ejecutar los servicios que necesite nuestra _lambda_. El comando **tck-lambdas roles** nos devuelve los _ARN_ de los distintos roles que tenemos a nuestra disposición en _AWS Lambda_.
49
79
 
50
80
  Con dichos cambios en nuestro *.lambdas.yml* ejecutamos la siguiente tarea de _rake_:
51
81
 
52
- $ bundle exec rake lambdas:contact_form:create_lambda
82
+ $ rake lambdas:contact_form:create_lambda
53
83
 
54
84
  Dicha orden nos creará, **además de la función _lambda_** necesaria para el entorno de producción, **otra con el mismo nombre terminada en *_test* para la ejecución de sus tests** (en nuestro ejemplo si lanzamos ``aws lambda list-functions`` deberíamos tener dos nuevas funciones llamadas *amazing_contact_form* y *amazing_contact_form_test*).
55
85
 
@@ -1,10 +1,11 @@
1
1
  /* Copyright 2016 The Cocktail Experience, S.L. */
2
2
  var conf = require('./conf'),
3
3
  http = require('request'),
4
- post = require('post_chistaco'),
4
+ post = require('./post_chistaco'),
5
5
  // Chistacojs modules
6
6
  refreshing_matter = require('./refreshing_matter'),
7
- chistescortos = require('./chistescortos');
7
+ chistescortos = require('./chistescortos'),
8
+ chyton = require('./chyton');
8
9
 
9
10
  exports.handler = function(event, context) {
10
11
  console.log('Received event:', JSON.stringify(event, null, 2));
@@ -19,11 +20,14 @@ exports.handler = function(event, context) {
19
20
  };
20
21
 
21
22
  switch(chistacojs_param) {
23
+ case 'refreshing':
24
+ chistacojs_module = refreshing_matter(conf.modules[0]);
25
+ break;
22
26
  case 'chistescortos':
23
- chistacojs_module = chistescortos(conf);
27
+ chistacojs_module = chistescortos(conf.modules[1]);
24
28
  break;
25
- case 'refreshing':
26
- chistacojs_module = refreshing_matter(conf);
29
+ case 'chyton':
30
+ chistacojs_module = chyton(conf.modules[2]);
27
31
  break;
28
32
  default:
29
33
  context.fail('module: not found');
@@ -1,7 +1,6 @@
1
1
  /* Copyright 2016 The Cocktail Experience, S.L. */
2
- module.exports = function(tck_lambdas_conf) {
3
- var conf = tck_lambdas_conf.modules[1], // "chistescortos"
4
- module = {
2
+ module.exports = function(conf) {
3
+ var module = {
5
4
  name: conf.name,
6
5
  conf: conf,
7
6
  call: function(request, callback) {
@@ -0,0 +1,24 @@
1
+ /* Copyright 2016 The Cocktail Experience, S.L. */
2
+ /* inspired by Ardor's Chyton lambda(*)
3
+ (*) https://gist.github.com/andor-pierdelacabeza/31509208af7b65448b4d743ae6f11035 */
4
+ module.exports = function(conf) {
5
+ var module = {
6
+ name: conf.name,
7
+ conf: conf,
8
+ call: function(request, callback) {
9
+ request(conf.url, function (error, response, body) {
10
+ if (!error && response.statusCode == 200) {
11
+ var xpath = require('xpath'),
12
+ dom = require('xmldom').DOMParser,
13
+ doc = new dom().parseFromString(body),
14
+ nodes = xpath.select(conf.xpath, doc);
15
+ callback(null, nodes[conf.index].toString());
16
+ }
17
+ else {
18
+ callback(error, response.statusCode);
19
+ }
20
+ })
21
+ }
22
+ };
23
+ return(module);
24
+ }
@@ -16,6 +16,13 @@ module.exports = {
16
16
  name: "ChistesCortos.eu",
17
17
  url: 'http://www.chistescortos.eu/random',
18
18
  selector: '.post .oldlink'
19
+ },
20
+ {
21
+ param: 'chyton',
22
+ name: 'Chyton',
23
+ url: 'http://pagina-del-dia.euroresidentes.es/chiste-del-dia/gadget-chiste-del-dia.php?modo=2',
24
+ xpath: '//td',
25
+ index: 2
19
26
  }
20
27
  ]
21
28
  }
@@ -0,0 +1,4 @@
1
+ this.addScript('dom.js',['DOMImplementation','XMLSerializer']);
2
+ this.addScript('dom-parser.js',['DOMHandler','DOMParser'],
3
+ ['DOMImplementation','XMLReader']);
4
+ this.addScript('sax.js','XMLReader');
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "xmldom",
3
+ "version": "0.1.15",
4
+ "main": "dom-parser.js",
5
+ "ignore": [
6
+ "**/.*",
7
+ "node_modules",
8
+ "components"
9
+ ]
10
+ }
@@ -0,0 +1,249 @@
1
+ function DOMParser(options){
2
+ this.options = options ||{locator:{}};
3
+
4
+ }
5
+ DOMParser.prototype.parseFromString = function(source,mimeType){
6
+ var options = this.options;
7
+ var sax = new XMLReader();
8
+ var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
9
+ var errorHandler = options.errorHandler;
10
+ var locator = options.locator;
11
+ var defaultNSMap = options.xmlns||{};
12
+ var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"}
13
+ if(locator){
14
+ domBuilder.setDocumentLocator(locator)
15
+ }
16
+
17
+ sax.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
18
+ sax.domBuilder = options.domBuilder || domBuilder;
19
+ if(/\/x?html?$/.test(mimeType)){
20
+ entityMap.nbsp = '\xa0';
21
+ entityMap.copy = '\xa9';
22
+ defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
23
+ }
24
+ defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
25
+ if(source){
26
+ sax.parse(source,defaultNSMap,entityMap);
27
+ }else{
28
+ sax.errorHandler.error("invalid document source");
29
+ }
30
+ return domBuilder.document;
31
+ }
32
+ function buildErrorHandler(errorImpl,domBuilder,locator){
33
+ if(!errorImpl){
34
+ if(domBuilder instanceof DOMHandler){
35
+ return domBuilder;
36
+ }
37
+ errorImpl = domBuilder ;
38
+ }
39
+ var errorHandler = {}
40
+ var isCallback = errorImpl instanceof Function;
41
+ locator = locator||{}
42
+ function build(key){
43
+ var fn = errorImpl[key];
44
+ if(!fn && isCallback){
45
+ fn = errorImpl.length == 2?function(msg){errorImpl(key,msg)}:errorImpl;
46
+ }
47
+ errorHandler[key] = fn && function(msg){
48
+ fn('[xmldom '+key+']\t'+msg+_locator(locator));
49
+ }||function(){};
50
+ }
51
+ build('warning');
52
+ build('error');
53
+ build('fatalError');
54
+ return errorHandler;
55
+ }
56
+
57
+ //console.log('#\n\n\n\n\n\n\n####')
58
+ /**
59
+ * +ContentHandler+ErrorHandler
60
+ * +LexicalHandler+EntityResolver2
61
+ * -DeclHandler-DTDHandler
62
+ *
63
+ * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
64
+ * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
65
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
66
+ */
67
+ function DOMHandler() {
68
+ this.cdata = false;
69
+ }
70
+ function position(locator,node){
71
+ node.lineNumber = locator.lineNumber;
72
+ node.columnNumber = locator.columnNumber;
73
+ }
74
+ /**
75
+ * @see org.xml.sax.ContentHandler#startDocument
76
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
77
+ */
78
+ DOMHandler.prototype = {
79
+ startDocument : function() {
80
+ this.document = new DOMImplementation().createDocument(null, null, null);
81
+ if (this.locator) {
82
+ this.document.documentURI = this.locator.systemId;
83
+ }
84
+ },
85
+ startElement:function(namespaceURI, localName, qName, attrs) {
86
+ var doc = this.document;
87
+ var el = doc.createElementNS(namespaceURI, qName||localName);
88
+ var len = attrs.length;
89
+ appendElement(this, el);
90
+ this.currentElement = el;
91
+
92
+ this.locator && position(this.locator,el)
93
+ for (var i = 0 ; i < len; i++) {
94
+ var namespaceURI = attrs.getURI(i);
95
+ var value = attrs.getValue(i);
96
+ var qName = attrs.getQName(i);
97
+ var attr = doc.createAttributeNS(namespaceURI, qName);
98
+ if( attr.getOffset){
99
+ position(attr.getOffset(1),attr)
100
+ }
101
+ attr.value = attr.nodeValue = value;
102
+ el.setAttributeNode(attr)
103
+ }
104
+ },
105
+ endElement:function(namespaceURI, localName, qName) {
106
+ var current = this.currentElement
107
+ var tagName = current.tagName;
108
+ this.currentElement = current.parentNode;
109
+ },
110
+ startPrefixMapping:function(prefix, uri) {
111
+ },
112
+ endPrefixMapping:function(prefix) {
113
+ },
114
+ processingInstruction:function(target, data) {
115
+ var ins = this.document.createProcessingInstruction(target, data);
116
+ this.locator && position(this.locator,ins)
117
+ appendElement(this, ins);
118
+ },
119
+ ignorableWhitespace:function(ch, start, length) {
120
+ },
121
+ characters:function(chars, start, length) {
122
+ chars = _toString.apply(this,arguments)
123
+ //console.log(chars)
124
+ if(this.currentElement && chars){
125
+ if (this.cdata) {
126
+ var charNode = this.document.createCDATASection(chars);
127
+ this.currentElement.appendChild(charNode);
128
+ } else {
129
+ var charNode = this.document.createTextNode(chars);
130
+ this.currentElement.appendChild(charNode);
131
+ }
132
+ this.locator && position(this.locator,charNode)
133
+ }
134
+ },
135
+ skippedEntity:function(name) {
136
+ },
137
+ endDocument:function() {
138
+ this.document.normalize();
139
+ },
140
+ setDocumentLocator:function (locator) {
141
+ if(this.locator = locator){// && !('lineNumber' in locator)){
142
+ locator.lineNumber = 0;
143
+ }
144
+ },
145
+ //LexicalHandler
146
+ comment:function(chars, start, length) {
147
+ chars = _toString.apply(this,arguments)
148
+ var comm = this.document.createComment(chars);
149
+ this.locator && position(this.locator,comm)
150
+ appendElement(this, comm);
151
+ },
152
+
153
+ startCDATA:function() {
154
+ //used in characters() methods
155
+ this.cdata = true;
156
+ },
157
+ endCDATA:function() {
158
+ this.cdata = false;
159
+ },
160
+
161
+ startDTD:function(name, publicId, systemId) {
162
+ var impl = this.document.implementation;
163
+ if (impl && impl.createDocumentType) {
164
+ var dt = impl.createDocumentType(name, publicId, systemId);
165
+ this.locator && position(this.locator,dt)
166
+ appendElement(this, dt);
167
+ }
168
+ },
169
+ /**
170
+ * @see org.xml.sax.ErrorHandler
171
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
172
+ */
173
+ warning:function(error) {
174
+ console.warn('[xmldom warning]\t'+error,_locator(this.locator));
175
+ },
176
+ error:function(error) {
177
+ console.error('[xmldom error]\t'+error,_locator(this.locator));
178
+ },
179
+ fatalError:function(error) {
180
+ console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
181
+ throw error;
182
+ }
183
+ }
184
+ function _locator(l){
185
+ if(l){
186
+ return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
187
+ }
188
+ }
189
+ function _toString(chars,start,length){
190
+ if(typeof chars == 'string'){
191
+ return chars.substr(start,length)
192
+ }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
193
+ if(chars.length >= start+length || start){
194
+ return new java.lang.String(chars,start,length)+'';
195
+ }
196
+ return chars;
197
+ }
198
+ }
199
+
200
+ /*
201
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
202
+ * used method of org.xml.sax.ext.LexicalHandler:
203
+ * #comment(chars, start, length)
204
+ * #startCDATA()
205
+ * #endCDATA()
206
+ * #startDTD(name, publicId, systemId)
207
+ *
208
+ *
209
+ * IGNORED method of org.xml.sax.ext.LexicalHandler:
210
+ * #endDTD()
211
+ * #startEntity(name)
212
+ * #endEntity(name)
213
+ *
214
+ *
215
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
216
+ * IGNORED method of org.xml.sax.ext.DeclHandler
217
+ * #attributeDecl(eName, aName, type, mode, value)
218
+ * #elementDecl(name, model)
219
+ * #externalEntityDecl(name, publicId, systemId)
220
+ * #internalEntityDecl(name, value)
221
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
222
+ * IGNORED method of org.xml.sax.EntityResolver2
223
+ * #resolveEntity(String name,String publicId,String baseURI,String systemId)
224
+ * #resolveEntity(publicId, systemId)
225
+ * #getExternalSubset(name, baseURI)
226
+ * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
227
+ * IGNORED method of org.xml.sax.DTDHandler
228
+ * #notationDecl(name, publicId, systemId) {};
229
+ * #unparsedEntityDecl(name, publicId, systemId, notationName) {};
230
+ */
231
+ "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
232
+ DOMHandler.prototype[key] = function(){return null}
233
+ })
234
+
235
+ /* Private static helpers treated below as private instance methods, so don't need to add these to the public API; we might use a Relator to also get rid of non-standard public properties */
236
+ function appendElement (hander,node) {
237
+ if (!hander.currentElement) {
238
+ hander.document.appendChild(node);
239
+ } else {
240
+ hander.currentElement.appendChild(node);
241
+ }
242
+ }//appendChild and setAttributeNS are preformance key
243
+
244
+ if(typeof require == 'function'){
245
+ var XMLReader = require('./sax').XMLReader;
246
+ var DOMImplementation = exports.DOMImplementation = require('./dom').DOMImplementation;
247
+ exports.XMLSerializer = require('./dom').XMLSerializer ;
248
+ exports.DOMParser = DOMParser;
249
+ }