4 * Copyright 2016 RIFT.IO Inc
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 var Promise
= require('bluebird');
20 var utils
= require('../../../framework/core/api_utils/utils.js');
21 var request
= utils
.request
;
22 var constants
= require('../../../framework/core/api_utils/constants.js');
23 var _
= require('lodash');
24 var APIVersion
= '/v1';
25 var transforms
= require('./transforms.js');
34 var SysLogViewer
= {};
40 // TODO: Consolidate the build functions, provide method type as arg
42 function buildGetRequestOptions(req
, endpoint
) {
43 var headers
= _
.extend({},
44 constants
.HTTP_HEADERS
.accept
.data
, {
45 'Authorization': req
.get('Authorization')
47 var api_server
= req
.query
["api_server"];
48 var requestOptions
= {
49 url
: utils
.confdPort(api_server
) + endpoint
,
52 forever
: constants
.FOREVER_ON
,
53 rejectUnauthorized
: false
55 return requestOptions
;
58 function buildPutRequestOptions(req
, endpoint
, jsonData
) {
59 var headers
= _
.extend({},
60 constants
.HTTP_HEADERS
.accept
.data
,
61 constants
.HTTP_HEADERS
.content_type
.data
, {
62 'Authorization': req
.get('Authorization')
64 var api_server
= req
.query
["api_server"];
65 var requestOptions
= {
66 url
: utils
.confdPort(api_server
) + endpoint
,
69 forever
: constants
.FOREVER_ON
,
70 rejectUnauthorized
: false,
73 return requestOptions
;
77 function buildDeleteRequestOptions(req
, endpoint
) {
78 var headers
= _
.extend({},
79 constants
.HTTP_HEADERS
.accept
.data
,
80 constants
.HTTP_HEADERS
.content_type
.data
, {
81 'Authorization': req
.get('Authorization')
83 var api_server
= req
.query
["api_server"];
84 var requestOptions
= {
85 url
: utils
.confdPort(api_server
) + endpoint
,
88 forever
: constants
.FOREVER_ON
,
89 rejectUnauthorized
: false
91 return requestOptions
;
95 * Used for simulating latency
97 function resolve_with_delay(resolve
, data
, delay
) {
98 return setTimeout(function() {
104 * This function provides the default callback for requests
106 function requestCallback(resolve
, reject
, transformFunc
) {
107 return function(error
, response
, body
) {
108 if (utils
.validateResponse('', error
, response
, body
, resolve
, reject
)) {
110 var data
= transformFunc(response
.body
);
112 var data
= JSON
.stringify(response
.body
);
114 return resolve_with_delay(resolve
, {
115 statusCode
: response
.statusCode
,
122 function handleGetRequest(req
, endpoint
, responseTransform
) {
123 return new Promise(function(resolve
, reject
) {
125 buildGetRequestOptions(req
, endpoint
),
126 requestCallback(resolve
, reject
, responseTransform
)
134 // TODO: Add arg for transform function to transfrm req.body to json data
135 // Right now we'll just pass the request through, until we need to implement
137 function handlePutRequest(req
, endpoint
, body
) {
138 return new Promise(function(resolve
, reject
) {
140 buildPutRequestOptions(req
, endpoint
, body
||req
.body
),
141 requestCallback(resolve
, reject
)
146 function handleDeleteRequest(req
, endpoint
, body
) {
147 return new Promise(function(resolve
, reject
) {
149 buildDeleteRequestOptions(req
, endpoint
),
150 requestCallback(resolve
, reject
)
155 function handleMockResponse(req
, success
, statusCode
, data
, delay
) {
157 return new Promise(function(resolve
, reject
) {
159 resolve_with_delay(resolve
, { statusCode
: statusCode
, data
: data
}, delay
)
160 } else { reject({ statusCode
: statusCode
, data
: data
}); }
165 function handleReject(req
, statusCode
, message
) {
166 return new Promise(function(resolve
, reject
) {
167 reject({ statusCode
: statusCode
, data
: message
});
172 * Calllback function to parse the response body into an object and
173 * remove the restconf top level key if it is present.
175 function transformLoggingRootResponseCallback(responseBody
) {
176 var data
= JSON
.parse(responseBody
);
177 if (data
['rwlog-mgmt:logging']) {
178 data
= data
['rwlog-mgmt:logging'];
187 function dumpLoggingConfig(data
) {
188 console
.log("dumpLoggingconfig");
189 var logConfig
= data
['lwlog-mgmt:logging'] || data
;
191 console
.log("keys=", Object
.keys(logConfig
));
192 console
.log("stringify=", JSON
.stringify(logConfig
));
193 if (logConfig
['default-severity']) {
194 logConfig
['default-severity'].forEach(function(obj
) {
198 if (logConfig
['sink']) {
199 console
.log('sink=', JSON
.stringify(logConfig
['sink']));
201 if (logConfig
['console']) {
202 console
.log('console=', JSON
.stringify(logConfig
['console']));
204 if (logConfig
['deny']) {
205 console
.log('deny=', JSON
.stringify(logConfig
['deny']));
212 * This method should fill out the full data set
214 Aggregate
.get = function(req
) {
216 // get operational data
218 var configData
= Config
.get(req
);
219 var operationalData
= Operational
.get(req
);
221 return new Promise(function(resolve
, reject
) {
222 Promise
.all([configData
, operationalData
]).then(function(resolves
) {
223 //console.log("Resolved all request promises (config, operational logging data)");
224 // TODO: Make sure the statusCodes for each resulves is 200
225 var decoder
= new transforms
.LoggingConfigDecoder();
228 data
: decoder
.decode(resolves
[0], resolves
[1])
231 }).catch(function(error
) {
232 console
.log("Logging: Aggregate.get error: ", error
);
242 * This method expects the full data set (keys and values) for the logging
243 * config to replace the existing logging config
245 Aggregate
.set = function(req
) {
246 // NOTE: Left some debugging code remarked out
248 //console.log("Logging Aggregate.set called");
249 //console.log("data=", req.body);
251 // Do nothing to test delay in response
252 var encoder
= new transforms
.LoggingConfigEncoder();
253 var data
= encoder
.encode(req
.body
);
254 //console.log("Aggregate.set. encoded data=");
256 // dumpLoggingConfig(data);
258 return handlePutRequest(req
, APIVersion
+ '/api/config/logging', data
);
259 // if (this.mockResponse['set']) {
260 // return handleMockResponse(req, true, 201, data, delay=100);
271 * Get all currently set logging config data
273 Config
.get = function(req
) {
274 return handleGetRequest(req
, APIVersion
+ '/api/config/logging?deep',
275 transformLoggingRootResponseCallback
280 * Top level put method. Restconf cannot currently handle a global put on
281 * logging, so this method is currently for testing
283 Config
.set = function(req
) {
284 return handlePutRequest(req
, APIVersion
+ '/api/config/logging');
288 Config
.setConsole = function(req
) {
289 return handlePutRequest(req
, APIVersion
+ '/api/config/logging/console');
292 Config
.setFilter = function(req
) {
293 return handlePutRequest(req
, APIVersion
+ '/api/config/logging/console/filter');
296 Config
.setDefaultSeverity = function(req
) {
297 // TODO: verify there is one key at root of data: 'default-severity'
298 // OR just filter on the request body
299 return handlePutRequest(req
, APIVersion
+ '/api/config/logging/');
302 Config
.deleteDefaultSeverity = function(req
) {
303 // TODO: verify there is one key at root of data: 'default-severity'
304 // OR just filter on the request body
305 var Categories
= req
.body
['default-severity'];
306 return new Promise(function(resolve
, reject
) {
307 var promises
= Categories
.map(function(c
) {
308 return handleDeleteRequest(req
, APIVersion
+ '/api/config/logging/default-severity/' + c
.category
);
310 return Promise
.all(promises
).then(
326 "allowDuplicateEvents" : true
331 * TODO: Repeat delete calls (when 'allowDuplicateEvents' value is false) cause
333 * TODO: the call to handleDeleteRequest returns stringified data, but the PUT
334 * does not (This is the behavior we want)
336 * Improvement? Allos string representation of true/false
338 Config
.setAllowDuplicateEvents = function(req
) {
339 // TODO: verify there is one key at root of data: 'default-severity'
340 // OR just filter on the request body
342 if (req
.body
.hasOwnProperty('allowDuplicateEvents') &&
343 typeof req
.body
.allowDuplicateEvents
== 'boolean') {
344 if (req
.body
.allowDuplicateEvents
) {
345 return handlePutRequest(req
, APIVersion
+ '/api/config/logging/allow', {
346 "duplicate": "events"
348 } else { // false, remove entry from logging config
349 return handleDeleteRequest(req
, APIVersion
+ '/api/config/logging/allow/duplicate');
352 return handleReject(statusCode
=400,
354 "message": 'Expected key, "allowDuplicateEvents" not found',
355 "original-request" : req
.body
378 Config
.setDenyEvents = function(req
) {
381 events
: req
.body
.denyEvents
.eventIDs
.map(function(eventID
) {
382 return { "event-Id": eventID
};
386 return handlePutRequest(req
, APIVersion
+ '/api/config/logging', reqBody
);
389 Config
.setSyslogViewer = function(req
) {
390 // TODO: Verify structure of req.body
392 "syslog-viewer" : req
.body
['syslog-viewer']
394 return handlePutRequest(req
, APIVersion
+ '/api/config/logging', reqBody
);
400 Operational
.get = function(req
) {
401 return handleGetRequest(req
, APIVersion
+ '/api/operational/logging?deep',
402 transformLoggingRootResponseCallback
408 * Legacy call to get sys log viewer
411 SysLogViewer
.get = function(req
) {
412 console
.log("\n***\n SysLogViewer.get called");
413 var api_server
= req
.query
['api_server'];
414 return new Promise(function(resolve
, reject
) {
416 uri
: utils
.confdPort(api_server
) + APIVersion
+ '/api/config/logging/syslog-viewer',
418 headers
: _
.extend({},
419 constants
.HTTP_HEADERS
.accept
.data
,
421 'Authorization': req
.get('Authorization')
424 rejectUnauthorized
: false
426 function(error
, response
, body
) {
428 console
.log('Logging.get failed. Error:', error
);
430 statusCode
: response
? response
.statusCode
: 404,
431 errorMessage
: 'Issue retrieving syslog-viewer url'
436 data
= JSON
.parse(response
.body
);
438 console
.log('Logging.get failed while parsing response.body. Error:', e
);
441 errorMessage
: 'Error parsing response.body during Logging.get'
453 Test
.roundtrip = function(req
) {
454 return new Promise(function(resolve
, reject
) {
455 Aggregate
.get(req
).then(function(result
) {
456 var data
= (new transforms
.LoggingConfigEncoder()).encode(result
.data
);
460 'rwlog-mgmt:logging': data
464 console
.log('Test.get error:', err
);
474 aggregate
: Aggregate
,
476 operational
: Operational
,
477 sysLogViewer
: SysLogViewer
,