Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrapped json support #79

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
13 changes: 12 additions & 1 deletion module/livestatus_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def __init__(self, datamgr, query_cache, db, pnp_path, return_queue, counters=No

def handle_request(self, data):
try:
outputformat='csv'
return self.handle_request_and_fail(data)
except LiveStatusQueryError as err:
# LiveStatusQueryError(404, table)
Expand All @@ -84,8 +85,18 @@ def handle_request(self, data):
logger.error("[Livestatus] Back trace of this exception: %s", trb)
code = 500
output = err
# We need the output format in order to return the error in one way or another
OUTPUT_FORMAT_HEADER = 'OutputFormat:'
outputformat = next(
(
line[len(OUTPUT_FORMAT_HEADER)+1:].strip()
for line in data.splitlines()
if line.startswith(OUTPUT_FORMAT_HEADER)
),
'csv' # Default value
)
# Ok now we can return something
response = LiveStatusResponse()
response = LiveStatusResponse(outputformat=outputformat)
response.set_error(code, output)
if 'fixed16' in data:
response.responseheader = 'fixed16'
Expand Down
28 changes: 23 additions & 5 deletions module/livestatus_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def __init__(self, responseheader='off', outputformat='csv', keepalive='off', co
self.separators = separators
self.statuscode = 200
self.output = LiveStatusListResponse()
self.error = None

def __str__(self):
output = "LiveStatusResponse:\n"
Expand All @@ -128,8 +129,13 @@ def __str__(self):
return output

def set_error(self, statuscode, data):
del self.output[:]
self.output.append( LiveStatusQueryError.messages[statuscode] % data )
msg = LiveStatusQueryError.messages[statuscode] % data
if self.outputformat == 'wrapped_json':
self.output = '[]'
self.error = msg
else:
del self.output[:]
self.output.append(msg)
self.statuscode = statuscode

def load(self, query):
Expand All @@ -143,12 +149,23 @@ def get_response_len(self, rsp=None):
else len(rsp) )

def respond(self):
if self.outputformat == 'wrapped_json':
self._generate_wrapped_json_output()

if self.responseheader == 'fixed16':
responselength = 1 + self.get_response_len() # 1 for the final '\n'
self.output.insert(0, '%3d %11d\n' % (self.statuscode, responselength))
self.output.append('\n')

return self.output, self.keepalive

def _generate_wrapped_json_output(self):
self.output = loads(reduce(lambda acc, x: acc+x, self.output))
self.output = {'data': self.output, 'failed': {}, 'total': len(self.output)}
if self.error:
self.output['errors']['shinken-error'] = self.error
self.output = LiveStatusListResponse([dumps(self.output) + '\n'])

def _format_json_python_value(self, value):
if isinstance(value, bool):
return 1 if value else 0
Expand Down Expand Up @@ -198,6 +215,7 @@ def _python_end_row(self, row, line_nr=0):
_format_2_value_handler = {
'csv': (_csv_end_row, _format_csv_value),
'json': (_json_end_row, _format_json_python_value),
'wrapped_json': (_json_end_row, _format_json_python_value),
'python': (_python_end_row, _format_json_python_value)
}
def make_live_data_generator2(self, result, columns, aliases):
Expand Down Expand Up @@ -270,15 +288,15 @@ def make_live_data_generator2(self, result, columns, aliases):


def make_live_data_generator(self, result, columns, aliases):
assert self.outputformat in ('csv', 'json', 'python')
assert self.outputformat in ('csv', 'json', 'python', 'wrapped_json')

if self.outputformat in ('json', 'python'):
if self.outputformat in ('json', 'python', 'wrapped_json'):
yield '['

for value in self.make_live_data_generator2(result, columns, aliases):
yield value

if self.outputformat in ('json', 'python'):
if self.outputformat in ('json', 'python', 'wrapped_json'):
yield ']'

def format_live_data(self, result, columns, aliases):
Expand Down