- Prerequisites
- Creating the Project Structure
- Connecting to the Platform
- Creating a Service
- Sending Requests to Another Service
- Posting Events when the Job is Submitted and Completed
- Subscribing to Service Events
- Sending REST Requests to Your Service
- Delivering the Service as an RPM on CentOS 6.x/RedHat 6.x
- Daemonizing the Service On CentOS 6.x/RedHat 6.x
Prerequisites
Before proceeding with the tutorial, please install the following software:
- Oracle VM VirtualBox
- HashiCorp Vagrant
- Avid Platform Virtual Machine
For instructions on setting up VirtualBox, Vagrant, and the Avid Platform Virtual Machine, see the README included in the Avid Platform Virtual Machine download file (avid-platform-vagrant-vm-YYYY-MM-DD-XXXX.zip).
In addtion, make sure the node
and npm
commands are available in your shell.
If running on Windows, ensure that Python 2.7
is installed and the PYTHON environment variable is set (needed for npm
to install packages correctly).
Creating the Project Structure
Make sure you are in the root directory of the unzipped avid-connector-api-node. Create a directory for your project. We will use the name
node-service
in this tutorial. Then createmodule
subfolder inside.1
2mkdir node-service
mkdir node-service/moduleMake
node-service/module
directory current1
cd node-service/module
Create a
package.json
file1
touch package.json
Add the following content to this file:
1
2
3
4
5
6
7
8
9
10
11
12{
"name": "node-service",
"description": "Tutorial service based on Avid Connector API for Node.js.",
"version": "0.0.1",
"devDependencies": {
"proxy-bal": "../../node_modules/proxy-bal.tgz"
},
"main": "./index.js",
"engines": {
"node": ">= 0.12.0"
}
}Create
lib
andbin
directories:1
2mkdir lib
mkdir binInstall NPM dependencies:
1
npm install
Congratulations! A simple project layout and core dependencies are now ready.
Connecting to the Platform
Create a
bin/node-service.js
file:1
touch bin/node-service.js
Add the following content to
bin/node-service.js
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var bal = require('proxy-bal');
var access = bal.createAccess();
access.on('connected', function() {
bal.logger.info("Connected to platform")
});
access.connect();
access.on('disconnected', function () {
process.exit(0);
});
process.on('SIGTERM', function() {
access.disconnect();
});Set environment variables to use a websocket connection with a protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the service you just created:
1
node bin/node-service.js
You should see following logs output in the shell:
1
22016-02-11T23:26:56,390-0500 - info: Node Proxy BAL v3.5.2
2016-02-11T23:26:56,586-0500 - info: Connected to platformPress
Ctrl+C
to terminate the service.
Congratulations! You have successfully connected to Platform as a client.
Creating a Service
Create
index.js
,lib/node-service.json
andlib/node-service.js
files:1
2
3touch index.js
touch lib/node-service.json
touch lib/node-service.jsAdd the following content to
lib/node-service.json
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44{
"serviceType": "avid.tutorial.node.service",
"serviceRealm": "global",
"serviceVersion": 1,
"description": "Tutorial service based on Avid Connector API for Node.js.",
"ops": {
"submitJob": {
"description": "Submit job for execution. Returns response back with information whether job submitted successfully or not",
"examples": {
"Submit valid job": {
"jobId": 1,
"execTime": 1000
},
"Submit invalid jobId": {
"jobId": -1,
"execTime": 1000
},
"Submit invalid execTime": {
"jobId": 2,
"execTime": 10
}
},
"rest": {
"path": "jobs/{jobId}",
"queryParams": ["execTime"],
"method": "POST"
}
}
},
"errorCodes": {
"INVALID_JOB_ID": {
"status": 500,
"severity": "ERROR",
"messageTemplate": "Invalid jobId: %{jobId}",
"origin": "SERVICE"
},
"INVALID_EXECUTION_TIME": {
"status": 500,
"severity": "ERROR",
"messageTemplate": "Invalid execution time: %{execTime}",
"origin": "SERVICE"
}
}
}Add the following content to
lib/node-service.js
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54var util = require('util');
var bal = require('proxy-bal');
var node_service = require('./node-service.json');
var NodeService = function(bus_access, options) {
NodeService.super_.call(
this,
bus_access,
node_service,
options);
this.on('configured', function(config, service, configurationUpdate, err) {
this.logger.info("GOT CONFIGURATION");
if (config) {
this.config = config;
}
});
return this;
};
util.inherits(NodeService, bal.Service);
NodeService.prototype.submitJob = function(m, responder) {
var jobId = parseInt(m.paramSet.jobId);
var execTime = parseInt(m.paramSet.execTime);
if (isNaN(jobId) || jobId < 1) {
return responder.error({
code: "INVALID_JOB_ID",
params: {
jobId: m.paramSet.jobId
},
details: "Invalid jobId was provided. Must be integer > 0."
});
}
if (isNaN(execTime) || execTime < 100) {
return responder.error({
code: "INVALID_EXECUTION_TIME",
params: {
execTime: m.paramSet.execTime
},
details: "Invalid execution time provided. Must be integer >= 100."
});
}
responder.reply({
jobStatus: "submitted"
});
};
module.exports = function (ctrl, options) {
return new NodeService(ctrl, options);
}Add the following content to the
index.js
file:1
module.exports = require('./lib/node-service.js');
Update the
bin/node-service.js
file:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var bal = require('proxy-bal');
var Service = require('../index');
var access = bal.createAccess();
access.on('connected', function() {
bal.logger.info("Connected to platform")
var service = new Service(access);
var onRegistered = function(err, service) {
if (err) {
bal.logger.info("Failed to register service. Error message: " + err.errorMessage);
} else {
bal.logger.info("Service is registered successfully");
}
};
access.registerService(service, {}, onRegistered)
});
access.connect();
access.on('disconnected', function () {
process.exit(0);
});
process.on('SIGTERM', function() {
access.disconnect();
});Set environment variables to use a websocket connection with protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the service:
1
node bin/node-service.js
You should see logs output in the shell.
Test that the service is working:
- Open the ACS Monitor. Filter the services list by entering
node\.service
in the Service Types Filter field and clicking the Apply button. The list is reduced toavid.tutorial.node.service
. - Expand the Service Operations List for the service. The list should include the
submitJob
operation. - Click on the
Submit valid job
link. Its corresponding message should appear in the code editor area, under theRequest to
field. - Click the
Query
button. Your service’s response appears in theResponse
field.
- Open the ACS Monitor. Filter the services list by entering
Press
Ctrl+C
in the shell to terminate the service.
Congratulations! You have successfully registered your service on the Platform.
Sending Requests to Another Service
In this procedure you modify the
NodeService.prototype.submitJob
method inlib/node-service.js
, and add two new methods,NodeService.prototype.setNumberOfSubmittedJjobs
andNodeService.prototype.getNumberOfSubmittedJobs
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130NodeService.prototype.submitJob = function(m, responder) {
var self = this;
var jobId = parseInt(m.paramSet.jobId);
var execTime = parseInt(m.paramSet.execTime);
if (isNaN(jobId) || jobId < 1) {
return responder.error({
code: "INVALID_JOB_ID",
params: {
jobId: m.paramSet.jobId
},
details: "Invalid jobId was provided. Must be integer > 0."
});
}
if (isNaN(execTime) || execTime < 100) {
return responder.error({
code: "INVALID_EXECUTION_TIME",
params: {
execTime: m.paramSet.execTime
},
details: "Invalid execution time provided. Must be integer >= 100."
});
}
var sendResponse = function(number) {
responder.reply({
jobStatus: "submitted",
numberOfSubmittedJobs: number
});
};
self.getNumberOfSubmittedJobs(function(err, number) {
var newNumber = number;
if (!err) {
self.setNumberOfSubmittedJobs(++newNumber, function(err) {
if (err) {
sendResponse(number);
} else {
sendResponse(newNumber);
}
});
} else if (err instanceof Array && err[0] && err[0].code === 'avid.acs.attributes/NOT_FOUND') {
newNumber = 1;
self.setNumberOfSubmittedJobs(newNumber, function(err) {
if (err) {
sendResponse(null);
} else {
sendResponse(newNumber);
}
});
} else {
sendResponse(null);
}
});
};
NodeService.prototype.getNumberOfSubmittedJobs = function(callback) {
var self = this;
var message = {
serviceType: 'avid.acs.attributes',
serviceRealm: 'global',
serviceVersion: '3',
op: 'fetch',
paramSet: {
name: 'node.service.store'
}
};
var options = {
timeout: 2000
};
self.bus.advancedQuery(message, options, function(reply) {
if (reply.errorSet) {
self.logger.info("Error received trying get number of submitted jobs: %s", JSON.stringify(reply.errorSet));
callback(reply.errorSet, null);
} else {
var numberOfSubmittedJobs = reply.resultSet.value.numberOfSubmittedJobs;
self.logger.info("Nubmer of submitted jobs: %d", numberOfSubmittedJobs);
callback(null, numberOfSubmittedJobs);
}
}, function() {
self.logger.info("Timeout occurred");
callback("Timeout", null);
}, function(error) {
self.logger.info("Error occurred. Error message: " + err.errorMessage);
callback("Error", null);
});
}
NodeService.prototype.setNumberOfSubmittedJobs = function(number, callback) {
var self = this;
var message = {
serviceType: 'avid.acs.attributes',
serviceRealm: 'global',
serviceVersion: '3',
op: 'store',
paramSet: {
name: 'node.service.store',
value: {
numberOfSubmittedJobs: number
}
}
};
var options = {
timeout: 2000
};
self.bus.advancedQuery(message, options, function(reply) {
if (reply.errorSet) {
self.logger.info("Error received trying update nubmer of submitted jobs: %s", JSON.stringify(reply.errorSet));
callback(reply.errorSet);
} else {
self.logger.info("Number of submitted jobs updated to %d", number);
callback(null);
}
}, function() {
self.logger.info("Timeout occurred");
callback("Timeout", null);
}, function(error) {
self.logger.info("Error occurred. Error message: " + err.errorMessage);
callback("Error", null);
});
}Set environment variables to use a websocket connection with a protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the service:
1
node bin/node-service.js
You should see logs output in the shell.
Test that the service is working. Open ACS Monitor, and send several
submitJob
requests to your service. Each time you send a new request, you should see the number of submitted jobs incrementing in the response:1
2
3
4
5
6{
"resultSet": {
"jobStatus": "submitted",
"numberOfSubmittedJobs": 2
}
}Press
Ctrl+C
in the shell to terminate the service.
Congratulations! You have successfully sent a request to another service, and received a response from it.
Posting Events when the Job is Submitted and Completed
Edit
lib/node-service.js
file. Here, we modify theNodeService.prototype.submitJob
method:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89NodeService.prototype.submitJob = function(m, responder) {
var self = this;
var jobId = parseInt(m.paramSet.jobId);
var execTime = parseInt(m.paramSet.execTime);
if (isNaN(jobId) || jobId < 1) {
return responder.error({
code: "INVALID_JOB_ID",
params: {
jobId: m.paramSet.jobId
},
details: "Invalid jobId was provided. Must be integer > 0."
});
}
if (isNaN(execTime) || execTime < 100) {
return responder.error({
code: "INVALID_EXECUTION_TIME",
params: {
execTime: m.paramSet.execTime
},
details: "Invalid execution time provided. Must be integer >= 100."
});
}
var sendResponse = function(number) {
responder.reply({
jobStatus: "submitted",
numberOfSubmittedJobs: number
});
};
var submittedMsg = {
channel: 'node.service.jobs',
subject: 'submit',
dataSet: {
jobId: jobId
}
};
var callback = function(err) {
if (err) {
console.err("Error message: " + err.errorMessage);
console.err("Error type: " + err.errorType);
} else {
console.log("Successfully post to channel");
}
};
self.bus.postToChannel(submittedMsg, callback);
setTimeout(function() {
var completeMsg = {
channel: 'node.service.jobs',
subject: 'complete',
dataSet: {
jobId: jobId
}
};
self.bus.postToChannel(completeMsg, callback);
}, execTime);
self.getNumberOfSubmittedJobs(function(err, number) {
var newNumber = number;
if (!err) {
self.setNumberOfSubmittedJobs(++newNumber, function(err) {
if (err) {
sendResponse(number);
} else {
sendResponse(newNumber);
}
});
} else if (err instanceof Array && err[0] && err[0].code === 'avid.acs.attributes/NOT_FOUND') {
newNumber = 1;
self.setNumberOfSubmittedJobs(newNumber, function(err) {
if (err) {
sendResponse(null);
} else {
sendResponse(newNumber);
}
});
} else {
sendResponse(null);
}
});
};Set environment variables to use a websocket connection with a protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the service:
1
node bin/node-service.js
You should see logs output in the shell.
Press
Ctrl+C
in the shell to terminate the service.
Congratulations! You have successfully published events to the Platform.
At this point, service behavior in the ACS Monitor is unchanged. Next, we create a consumer of our service events.
Subscribing to Service Events
Other services and clients may wish to listen on the channel to which our service posts, so they can receive event information. We demonstrate this functionality by creating a new client that listens on the channel.
Create a
bin/node-client.js
file:Add the following content to the file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
var bal = require('proxy-bal');
var access = bal.createAccess();
access.on('connected', function() {
bal.logger.info("Connected to platform")
access.subscribeToChannel('node.service.jobs', [ 'submit' ],
function(err, message) {
if (!err) {
bal.logger.info("Job %d is submitted", message.dataSet.jobId);
}
},
function(err, subscriberId) {
if (err) {
bal.logger.info("Failed to subscribe to node.service.jobs - submit. Error message: " + err.errorMessage);
} else {
bal.logger.info("Subscribed to node.service.jobs - submit");
}
});
access.subscribeToChannel('node.service.jobs', [ 'complete' ],
function(err, message) {
if (!err) {
bal.logger.info("Job %d is completed", message.dataSet.jobId);
}
},
function(err, subscriberId) {
if (err) {
bal.logger.info("Failed to subscribe to node.service.jobs - complete. Error message: " + err.errorMessage);
} else {
bal.logger.info("Subscribed to node.service.jobs - complete");
}
});
});
access.connect();
access.on('disconnected', function () {
process.exit(0);
});
process.on('SIGTERM', function() {
access.disconnect();
});Set environment variables to use a websocket connection with a protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the service:
1
node bin/node-service.js
Open a new shell in the same location. Set environment variables to use a websocket connection with a protobuf payload:
1
export ACS_GATEWAY_HOST=avid-platform-zone1
Run the client:
1
node bin/node-client.js
Test that the service and client are working:
- Open ACS Monitor, and filter the services list by entering the
node\.service
regular expression in the box. You should see now only one service in the list:avid.tutorial.node.service
. - Send multiple
submitJob
messages to your service with different values. Examine the logs of your client. The logs ought to contain each “job submit” and “job complete” event.
- Open ACS Monitor, and filter the services list by entering the
Congratulations! You have created a client that subscribes to the events being posted by your service.
Sending REST Requests to Your Service
Log in to
avid-platform-zone1
with ssh (username: root; password: vagrant):1
ssh root@avid-platform-zone1
Send a POST request to your service using the
curl
command. Use the avidAccessToken generated previously:1
2
3curl -H "Content-Type: application/json" --data '{"execTime":15000}' "http://avid-platform-zone1:8080/apis/avid.tutorial.node.service;version=1/jobs/10?_avidAccessToken=ZWEwZDhlOTItYmJhZS00YTQ5LWFiN2QtNTAyYWMwZjhjZjJj"
#NOTE: The request should be routed via NGINX and use the HTTPS protocol: https://avid-platform-zone1/apis/...Given HTTP request will send following message to your service:
1
2
3
4
5
6
7
8
9
10{
"serviceType": "avid.tutorial.node.service",
"serviceRealm": "global",
"serviceVersion": 1,
"op": "submitJob",
"paramSet": {
"jobId": 10,
"execTime": 15000
}
}Press
Ctrl+C
in the shells to terminate both the service and client.
Delivering the Service as an RPM on CentOS 6.x/RedHat 6.x
For this tutorial and the next one, you need a CentOS 6.x/RedHat 6.x system. You may use your VM (created on the first steps of this tutorial) with the host name avid-platform-zone1
. The following steps assume you are using this VM to test the RPM.
At this point your current directory should be
node-service/module
. Go up one level. Your current directory must benode-service
:1
cd ..
Create a
node-service.spec
file:1
touch node-service.spec
Add the following content to the file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42%global debug_package %{nil}
Name: node-service
Version: 1
Release: 1
Summary: Tutorial service based on Avid Connector API for Node.js
License: Avid EULA
Vendor: Avid Technology Inc.
URL: http://avid.com
Source: %{name}-src.tgz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Prefix: /opt/avid
AutoReqProv: no
Requires: avid-acs-proxybal-node >= 3.5.0, avid-acs-proxybal-node < 4.0.0
%description
Tutorial service based on Avid Connector API for Node.js
%build
cd module
npm install --production
cd ..
%prep
%setup -c -n %{name}
%install
mkdir -p "${RPM_BUILD_ROOT}/opt/avid/sbin"
mkdir -p "${RPM_BUILD_ROOT}/opt/avid/lib/node_modules"
mv module "${RPM_BUILD_ROOT}/opt/avid/lib/node_modules/%{name}"
ln -s /opt/avid/lib/node_modules/%{name}/bin/%{name}.js "${RPM_BUILD_ROOT}/opt/avid/sbin/%{name}"
# Exit clean
exit 0
%files
%attr(755, root, root) /opt/avid/lib/node_modules/%{name}/bin/%{name}.js
/opt/avid/sbin/%{name}
/opt/avid/lib/node_modules/%{name}Create a
create-rmp.sh
file:1
touch create-rpm.sh
Add the following content to the file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# Print usage if we have no args
if [ $# -eq 0 ]; then
echo 'Usage:'
echo ' create-rpm <spec-file>'
echo 'Description:'
echo ' Used by jenkins jobs to create rpms. Specify'
echo ' the spec file and this script will tar the'
echo ' directory containing that file and run rpmbuild'
echo ' in the parent dir. See source for details.'
echo 'Examples:'
echo ' ./create-rpm.sh controllers/registry/avid-acs-registry.spec'
echo ' Creates ./rpmbuild/RPMS/x86_64/<rpm-name>.rpm'
exit 0
fi
RPM_VERSION=${RPM_VERSION-"0.0.0_DEV"}
if [ -f ./VERSION ]; then
# file generated by jenkins job
RPM_VERSION="$(cat ./VERSION)"
fi
ORIGINAL_DIR="$(pwd)"
# The directory that we are going to tar
SOURCE_DIR="$(dirname $1)"
# The base name of the spec file. This name will be used
# for the tar file.
SPEC_NAME="$(basename $1 .spec)"
# Set up rpmbuild tree
mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
pushd "$SOURCE_DIR"
# Compress sources and move into rpmbuild tree
tar -czf "$SPEC_NAME-src.tgz" ./* --exclude=.acignore --exclude=node_modules --exclude=*.swp --exclude=*~
mv "$SPEC_NAME-src.tgz" "$ORIGINAL_DIR/rpmbuild/SOURCES/"
# Copy spec into rpmbuild tree
cp "$SPEC_NAME.spec" "$ORIGINAL_DIR/rpmbuild/SPECS/"
popd
# Build rpm
rpmbuild --define "_rpmversion $RPM_VERSION" --define "_topdir `pwd`/rpmbuild" -bb "rpmbuild/SPECS/$SPEC_NAME.spec"Make the script executable:
1
chmod 777 create-rpm.sh
Remove the
node-modules
folder, to avoid duplicate copies of the NPM modules, which installed automatically when you issued thenpm install command
. Your current directory should benode-service
:1
rm -rf module/node_modules
Copy the project to
avid-platform-zone1
using ssh (username: root; password: vagrant). Your current directory should benode-service
:1
scp -r ../node-service root@avid-platform-zone1:/root/
Log in to
acs-zone-black
using ssh (username: root; password: vagrant):1
ssh root@avid-platform-zone1
In the
ssh
shell switch the current directory:1
cd /root/node-service
If you created files on Windows, make sure to use the LF line separator for bash scripts; if not, convert CRLF to LF with the following command:
1
sed -i 's/\r//' create-rpm.sh
Or, you can use vi or vim editor to change the file format by opening the file in the editor and then use
:set ff=unix
and then save the file.Install the needed RPM development tools:
1
yum install rpm-devel
Create the RPM:
1
./create-rpm.sh node-service.spec
Install your RPM:
1
yum install rpmbuild/RPMS/x86_64/node-service-1-1.x86_64.rpm
Run the installed service:
1
node /opt/avid/sbin/node-service
Test how service is working in the ACS Monitor
Press
Ctrl+C
to terminate service.
Congratulations! You have successfully created an RPM for your service, installed and started it.
Daemonizing the Service On CentOS 6.x/RedHat 6.x
In this section we daemonize the service, provide a default configuration for it, output logs into a file and add log rotation. If you are still in the ssh shell from the previous step, exit and return to your project directory. Your current directory must be node-service
Modify the
module/lib/node-service.js
file. Add the following method, afterutil.inherits(NodeService, bal.Service);
:1
2
3
4
5
6
7
8
9
10
11
12
13
14NodeService.prototype.onInitialize = function (onInitialized) {
var self = this;
onInitialized();
var lockFile = process.env['AVID_SERVICE_LOCK_FILE'];
if (lockFile) {
var fs = require("fs");
fs.openSync(lockFile, 'w');
fs.closeSync(fs.openSync(lockFile, 'w'));
} else {
self.logger.info("Lock file is not provided");
}
};Create
etc
,etc/init.d
,etc/syconfig
andetc/logrotate.d
directories:1
2
3
4mkdir etc
mkdir etc/init.d
mkdir etc/sysconfig
mkdir etc/logrotate.dCreate a
node-service
file in each of theetc/init.d
,etc/syconfig
andetc/logrotate.d
directories:1
2
3touch etc/init.d/node-service
touch etc/sysconfig/node-service
touch etc/logrotate.d/node-serviceAdd the following content to
etc/sysconfig/node-service
:1
2
3
4#export ACS_GATEWAY_HOST=127.0.0.1
#export ACS_GATEWAY_PORT=9900
#export ACS_BUS_QUERY_TIMEOUT=10000
#export ACS_LOG_LEVEL=infoAdd the following content to
etc/logrotate.d/node-service
:1
2
3
4
5
6
7
8
9/var/log/avid/node-service/node-service.log {
size 100M
rotate 10
copytruncate
missingok
notifempty
compress
delaycompress
}Add the following content to
etc/init.d/node-service
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#
# node-service Tutorial Node.js service
#
# chkconfig: - 86 15
# description: Tutorial service based on Avid Connector API for Node.js
#
### BEGIN INIT INFO
# Provides: node-service
# Required-Start: $local_fs $network $remote_fs
# Required-Stop: $local_fs $network $remote_fs
# Short-Description: Tutorial Node.js service
# Description: Tutorial service based on Avid Connector API for Node.js
#
### END INIT INFO
AVID_SERVICE_NAME="node-service"
AVID_SERVICE_PID_FILE="/var/run/avid/${AVID_SERVICE_NAME}/${AVID_SERVICE_NAME}.pid"
AVID_SERVICE_START_CMD="/opt/avid/sbin/${AVID_SERVICE_NAME}"
AVID_SERVICE_STDOUT_FILE="/var/log/avid/${AVID_SERVICE_NAME}/${AVID_SERVICE_NAME}.log"
AVID_SERVICE_STDERR_FILE="/var/log/avid/${AVID_SERVICE_NAME}/${AVID_SERVICE_NAME}.err"
AVID_SERVICE_LOCK_FILE="/var/lock/avid/${AVID_SERVICE_NAME}/${AVID_SERVICE_NAME}.lock"
# Source service config file if it exists
[ -e /etc/sysconfig/$AVID_SERVICE_NAME ] && . /etc/sysconfig/$AVID_SERVICE_NAME
# Source function library.
. /opt/avid/share/avid-daemonizer/avid-daemonizer.sh
# Call into the generic case statement in acs-functions
avid_svc_ctrl "$@"Modify
node-service.spec
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65%global debug_package %{nil}
Name: node-service
Version: 2
Release: 1
Summary: Tutorial service based on Avid Connector API for Node.js
License: Avid EULA
Vendor: Avid Technology Inc.
URL: http://avid.com
Source: %{name}-src.tgz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
Prefix: /opt/avid
AutoReqProv: no
Requires: avid-daemonizer >= 3.0.0, avid-daemonizer < 3.1.0
Requires: avid-acs-proxybal-node >= 3.5.0, avid-acs-proxybal-node < 4.0.0
%description
Tutorial service based on Avid Connector API for Node.js
%build
cd module
npm install --production
cd ..
%prep
%setup -c -n %{name}
%install
mkdir -p "${RPM_BUILD_ROOT}/opt/avid/sbin"
mkdir -p "${RPM_BUILD_ROOT}/opt/avid/lib/node_modules"
mv etc "${RPM_BUILD_ROOT}/"
mv module "${RPM_BUILD_ROOT}/opt/avid/lib/node_modules/%{name}"
ln -s /opt/avid/lib/node_modules/%{name}/bin/%{name}.js "${RPM_BUILD_ROOT}/opt/avid/sbin/%{name}"
%post
chkconfig --add %{name}
# Exit clean
exit 0
%preun
service %{name} stop ||:
# If uninstalling, remove chkconfig entry
if [ $1 -eq 0 ]; then
chkconfig --del %{name}
fi
%postun
# If upgrading, restart the service if it was already running
if [ $1 -eq 1 ]; then
chkconfig %{name} off
service %{name} condrestart ||:
fi
%files
%attr(755, root, root) /etc/init.d/%{name}
%attr(644, root, root) /etc/logrotate.d/%{name}
%attr(644, root, root) /etc/sysconfig/%{name}
%attr(755, root, root) /opt/avid/lib/node_modules/%{name}/bin/%{name}.js
/opt/avid/sbin/%{name}
/opt/avid/lib/node_modules/%{name}Copy your project to
avid-platform-zone1
using ssh (username: root; password: vagrant). Your current directory should benode-service
:1
scp -r ../node-service root@avid-platform-zone1:/root/
Log in to
acs-zone-black
using ssh (username: root; password: vagrant):1
ssh root@avid-platform-zone1
In the
ssh
shell switch current directory:1
cd /root/node-service
If you created files on Windows, make sure to use the LF line separator for bash scripts; if not, convert CRLF to LF with the following command:
1
2
3sed -i 's/\r//' create-rpm.sh
sed -i 's/\r//' etc/init.d/node-service
sed -i 's/\r//' module/bin/node-service.jsOr, you can use vi or vim editor to change the file format by opening the file in the editor and then use
:set ff=unix
and then save the file.Create the RPM:
1
./create-rpm.sh node-service.spec
Install your RPM:
1
yum install rpmbuild/RPMS/x86_64/node-service-2-1.x86_64.rpm
Run the installed service:
1
service node-service start
Test that the service is working, using the ACS Monitor
Monitor the service logs:
1
2
3service node-service logs
#or
tail -f /var/log/avid/node-service/node-service.log
Congratulations! You have successfully completed this tutorial.