Skip to content
This repository was archived by the owner on Oct 10, 2026. It is now read-only.

Commit ce41dac

Browse files
author
Luis Gonzalez
committed
Adding stem.js example
1 parent 18f6d56 commit ce41dac

9 files changed

Lines changed: 851 additions & 0 deletions

File tree

‎P01_stem/README.md‎

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
THIS PROJECT IS JUST A PROTOTYPE (but it fully works, including all examples explained here).!!
2+
3+
Name is inspired in the stem cells which can convert them selfs into any other specialized cells (just like stem server templates :)).
4+
5+
Stem.js its a command line interface tool, written in node.js to dynamically create/define/clone templates of other node.js servers. This means that you configure several templates applyting configuration files to them, and you can generate a nodejs server file which is launched with Forever!
6+
7+
## Installation
8+
9+
Just clone this git repo, I recommend youto add a simbolic link to the stem main program, to be in the PATH so you can execute it anywhere on your machine.
10+
11+
```ruby
12+
luis@boxita:~/git/stem.js$ ls -la /usr/local/bin/stem
13+
lrwxrwxrwx 1 root root 27 abr 4 15:27 /usr/local/bin/stem -> /home/luis/git/stem.js/stem
14+
```
15+
Also you require the following node.js packages (installed from NPM), including node.js itself which is not covered on this wiki.
16+
17+
```ruby
18+
npm install sqlite3 commander colors
19+
npm install -g forever
20+
```
21+
22+
## Current commands implemented
23+
```ruby
24+
luis@boxita:~/git/stem.js$ stem -h
25+
Usage: stem [options]
26+
Options:
27+
-h, --help output usage information
28+
-V, --version output the version number
29+
list Get the list of all registered servers.
30+
create [server] [core_template] Create [server] with [core_template].
31+
destroy [server] Destroy [server] with specified name.
32+
add [server] [template] Add the [template] to the existing [server].
33+
remove [server] [template] Given a [template] ID (int) remove it from the [server].
34+
describe [server] Show the details of a particular [server].
35+
stop [server] Stop an active running server.
36+
start [server] Start a server.
37+
setconf [conf_id] [value] Given a [config] ID (int) of a conf, change the its value.
38+
applyconf [server] [conf_file] Apply a [configuration] file to a [server].
39+
compile [server] Generate the physical NODEJS file as stem_<id>.js
40+
clone [source_server] [new_server] Tool to fully clone a server including templates and configs.
41+
```
42+
43+
## HOW IT (SHOULD) WORKS
44+
45+
A simple workflow should be:
46+
47+
1. add a server (stem create).
48+
2. add X additionally templates to that server (stem add).
49+
3. apply a configuration file (stem applyconf) and/or change individual configuration params (stem setconf).
50+
4. compile the server to generate the .js file (stem compile).
51+
5. start/stop the server (stem start, stem stop).
52+
53+
## AN EXAMPLE
54+
55+
Lets suppose you have the following 3 templates.
56+
57+
1. templates/server_http.js, which contains the main server listeners, not all <! !> are the params that will be replaced later.
58+
59+
```ruby
60+
// Load the http module to create an http server.
61+
var http = require('http');
62+
// Configure our HTTP server to respond with a message to all requests.
63+
var server = http.createServer(<!CONNECTION_LISTENER!>);
64+
// Listen on port <!CONF_PORT!> on localhost
65+
server.listen(<!CONF_PORT!>, "localhost");
66+
console.log("Server running at http://localhost:<!CONF_PORT!>/");
67+
```
68+
69+
2. templates/action_helloworld.js, which is the action that will be emmbedded inside the server template
70+
```ruby
71+
function connection_listener(request, response) {
72+
response.writeHead(200, {"Content-Type": "text/plain"});
73+
response.end("<!MESSAGE!>\n");
74+
}
75+
```
76+
3. config/basic.json which is the json file that contains the configuration params that will be replaced into the server templates
77+
```ruby
78+
{
79+
"CONF_FILENAME": "counter.txt",
80+
"CONNECTION_LISTENER": "connection_listener",
81+
"CONF_PORT": 8080,
82+
"MESSAGE": "Hola mundito!"
83+
}
84+
```
85+
86+
So in order to use Stem, you first create the server name "tango", and check it was created with the command list.
87+
```ruby
88+
luis@boxita:~/git/stem.js$ stem create tango templates/server_http.js
89+
Added server <tango> with id <1>
90+
Added template <templates/server_http.js> to server <1>
91+
Found 4 parameters in the template:
92+
- CONNECTION_LISTENER
93+
- CONF_PORT
94+
- CONF_PORT
95+
- CONF_PORT
96+
97+
luis@boxita:~/git/stem.js$ stem list
98+
List of SERVERS:
99+
ID STATE NAME
100+
1 STOPPED tang
101+
```
102+
103+
You can check the structure of any "server template" with the command "describe".
104+
```ruby
105+
luis@boxita:~/git/stem.js$ stem describe tango
106+
STRUCTURE
107+
1---- tango is STOPPED
108+
|
109+
1---- templates/server_http.js
110+
|
111+
1---- CONNECTION_LISTENER = UNDEFINED
112+
|
113+
2---- CONF_PORT = UNDEFINED
114+
115+
```
116+
117+
Now you should add the second template, which is the action inside that will be replaced inside the listener of the server:
118+
```ruby
119+
luis@boxita:~/git/stem.js$ stem add tango templates/action_helloworld.js
120+
Added template <templates/action_helloworld.js> to server <1>
121+
Found 1 parameters in the template:
122+
- MESSAGE
123+
124+
luis@boxita:~/git/stem.js$ stem describe tango
125+
STRUCTURE
126+
1---- tango is STOPPED
127+
|
128+
1---- templates/server_http.js
129+
| |
130+
| 1---- CONNECTION_LISTENER = UNDEFINED
131+
| |
132+
| 2---- CONF_PORT = UNDEFINED
133+
|
134+
2---- templates/action_helloworld.js
135+
|
136+
3---- MESSAGE = UNDEFINED
137+
```
138+
139+
As you probably noticed, there are some UNDEFINED fields, which should change either with applyconf (which will change all the confs from the json file, or setconf which allow you to change a single and particular param.
140+
```ruby
141+
luis@boxita:~/git/stem.js$ stem applyconf tango config/basic.json
142+
Configuration applied! Total changed items: 3
143+
144+
luis@boxita:~/git/stem.js$ stem describe tango
145+
146+
STRUCTURE
147+
1---- tango is STOPPED
148+
|
149+
1---- templates/server_http.js
150+
| |
151+
| 1---- CONNECTION_LISTENER = connection_listener
152+
| |
153+
| 2---- CONF_PORT = 8080
154+
|
155+
2---- templates/action_helloworld.js
156+
|
157+
3---- MESSAGE = Hola mundito!
158+
```
159+
160+
161+
162+
Now that you have all the params set, you should "compile" the server template, which will generate a local file named "server_XXX.js" where XXX is the ID of the server:
163+
```ruby
164+
luis@boxita:~/git/stem.js$ stem compile tango
165+
Server created on file server_1.js
166+
167+
168+
luis@boxita:~/git/stem.js$ cat server_1.js
169+
170+
/***** FROM TEMPLATE templates/action_helloworld.js******/
171+
172+
function connection_listener(request, response) {
173+
response.writeHead(200, {"Content-Type": "text/plain"});
174+
response.end("Hola mundito!\n");
175+
}
176+
177+
178+
/***** FROM TEMPLATE templates/server_http.js******/
179+
// Load the http module to create an http server.
180+
var http = require('http');
181+
182+
// Configure our HTTP server to respond with a message to all requests.
183+
var server = http.createServer(connection_listener);
184+
185+
// Listen on port 8080 on localhost
186+
server.listen(8080, "localhost");
187+
188+
console.log("Server running at http://localhost:8080/");
189+
```
190+
191+
And now you can start your new server and if it works (with curl in this case).
192+
```ruby
193+
luis@boxita:~/git/stem.js$ stem start tango
194+
info: Forever processing file: server_1.js
195+
Server started succesfully
196+
197+
luis@boxita:~/git/stem.js$ curl localhost:8080
198+
Hola mundito!
199+
```
200+
201+
You can also make other insteresting operations like clone a server, and start it into another port.
202+
```ruby
203+
luis@boxita:~/git/stem.js$ stem clone tango romeo
204+
luis@boxita:~/git/stem.js$ stem describe romeo
205+
STRUCTURE
206+
2---- romeo is STOPPED
207+
|
208+
3---- templates/server_http.js
209+
| |
210+
| 4---- CONNECTION_LISTENER = connection_listener
211+
| |
212+
| 5---- CONF_PORT = 8080
213+
|
214+
4---- templates/action_helloworld.js
215+
|
216+
6---- MESSAGE = Hola mundito!
217+
luis@boxita:~/git/stem.js$ stem setconf 5 8888
218+
luis@boxita:~/git/stem.js$ stem start romeo
219+
```

‎P01_stem/bin/stem.sh‎

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
3+
appname="stem";
4+
5+
start ()
6+
{
7+
echo "starting $appname";
8+
}
9+
10+
11+
stop ()
12+
{
13+
echo "stopping $appname";
14+
}
15+
16+
execute_command ()
17+
{
18+
if [ ! $1 ] ; then echo "no params"; return; fi
19+
case "$1" in
20+
"start")
21+
start
22+
;;
23+
"stop")
24+
stop
25+
;;
26+
"?")
27+
echo "Unknown option $1"
28+
;;
29+
":")
30+
echo "No argument value for execute option $1"
31+
;;
32+
*)
33+
# Should not occur
34+
echo "Unknown error while processing options"
35+
;;
36+
esac
37+
}
38+
39+
40+
while getopts ":x:v:" optname
41+
do
42+
case "$optname" in
43+
"v")
44+
echo "Option $optname (verbose) is active"
45+
;;
46+
"x")
47+
echo "Option $optname (command) has value $OPTARG"
48+
execute_command $OPTARG;
49+
;;
50+
"?")
51+
echo "Unknown option $OPTARG"
52+
;;
53+
":")
54+
if [[ "$OPTARG" == "x" ]] ; then echo "No argument value for option $OPTARG" ; fi
55+
;;
56+
*)
57+
# Should not occur
58+
echo "Unknown error while processing options"
59+
;;
60+
esac
61+
done

‎P01_stem/config/basic.json‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"CONF_FILENAME": "counter.txt",
3+
"CONNECTION_LISTENER": "connection_listener",
4+
"CONF_PORT": 8080,
5+
"MESSAGE": "Hola mundito!"
6+
}

‎P01_stem/noth.ing‎

Whitespace-only changes.

0 commit comments

Comments
 (0)