Merge remote-tracking branch 'pengfei/master'

This commit is contained in:
hongwei1 2019-07-03 15:14:33 +02:00
commit a06ea09733
14 changed files with 244 additions and 18 deletions

View File

@ -56,6 +56,7 @@ INSTALLED_APPS = [
'customers',
'metrics',
'config',
'webui',
]
MIDDLEWARE = [
@ -224,21 +225,7 @@ DIRECTLOGIN_PATH = '/my/logins/direct'
# Set to true if the API is connected to a core banking system
GATEWAYLOGIN_HAS_CBS = False
# Local settings can override anything in here
try:
from apimanager.local_settings import * # noqa
except ImportError:
pass
if not OAUTH_CONSUMER_KEY:
raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY')
if not OAUTH_CONSUMER_SECRET:
raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_SECRET')
# Settings here might use parts overwritten in local settings
API_ROOT = API_HOST + API_BASE_PATH + API_VERSION
# For some reason, swagger is not available at the latest API version
API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + API_VERSION + '/swagger' # noqa
CACHES = {
'default': {
@ -261,8 +248,21 @@ EXCLUDE_URL_PATTERN = []
# App Name to aggregate metrics
API_EXPLORER_APP_NAME = 'xxx'
# Local settings can override anything in here
try:
from apimanager.local_settings import * # noqa
except ImportError:
pass
# Settings here might use parts overwritten in local settings
API_ROOT = API_HOST + API_BASE_PATH + API_VERSION
# For some reason, swagger is not available at the latest API version
API_URL_SWAGGER = API_HOST + '/obp/v1.4.0/resource-docs/v' + API_VERSION + '/swagger' # noqa
VERIFY = True if API_HOST.startswith("https") else False
if not OAUTH_CONSUMER_KEY:
raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_KEY')
if not OAUTH_CONSUMER_SECRET:
raise ImproperlyConfigured('Missing settings for OAUTH_CONSUMER_SECRET')

View File

@ -35,4 +35,5 @@ urlpatterns = [
url(r'^customers/', include('customers.urls')),
url(r'^metrics/', include('metrics.urls')),
url(r'^config/', include('config.urls')),
url(r'^webui/', include('webui.urls')),
]

View File

@ -62,6 +62,8 @@
</li>
{% url "config-index" as config_index_url %}
<li{% ifequal request.path config_index_url %} class="active" {% endifequal %}><a href="{{ config_index_url }}">Config</a></li>
{% url "webui-index" as webui_props_index_url %}
<li{% ifequal request.path webui_props_index_url %} class="active" {% endifequal %}><a href="{{ webui_props_index_url }}">Webui Props</a></li>
{% if API_TESTER_URL %}
<li>
<p class="navbar-btn"><a href="{{ API_TESTER_URL }}" class="btn btn-default">Go to API Tester</a></p>

View File

@ -55,7 +55,12 @@
<div class="col-xs-6 col-sm-3">
<div class="form-group">
{{ form.include_obp_apps }} Include System Calls
{{ excluded_functions }}
{{ excluded_url_pattern }}
</div>
{% if excluded_apps %}
{{ excluded_apps }}
{% endif %}
</div>
</div>

View File

@ -818,6 +818,9 @@ class MetricsSummaryView(LoginRequiredMixin, TemplateView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@ -868,6 +871,9 @@ class YearlySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@ -922,6 +928,9 @@ class QuarterlySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@ -973,6 +982,9 @@ class WeeklySummaryView(MetricsSummaryView):
# ##'calls_per_half_day': calls_per_half_day,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@ -1026,6 +1038,9 @@ class DailySummaryView(MetricsSummaryView):
'top_apis_bar_chart': top_apis_bar_chart,
'median_time_to_first_api_call': median_time_to_first_api_call,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context
@ -1085,5 +1100,8 @@ class CustomSummaryView(MetricsSummaryView):
# ##'calls_per_day': calls_per_day,
# ##'calls_per_half_day': calls_per_half_day,
'form': form,
'excluded_apps':EXCLUDE_APPS,
'excluded_functions':EXCLUDE_FUNCTIONS,
'excluded_url_pattern':EXCLUDE_URL_PATTERN,
})
return context

View File

11
apimanager/webui/apps.py Normal file
View File

@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
"""
App config for config app
"""
from django.apps import AppConfig
class ConfigConfig(AppConfig):
"""Config for config"""
name = 'config'

14
apimanager/webui/forms.py Normal file
View File

@ -0,0 +1,14 @@
from django import forms
class WebuiForm(forms.Form):
webui_props = forms.CharField(
label='WEBUI Props',
widget=forms.Textarea(
attrs={
'class': 'form-control',
}
),
required=False
)

View File

@ -0,0 +1,10 @@
#config pre {
overflow: auto;
word-wrap: normal;
white-space: pre;
}
#config .string { color: green; }
#config .number { color: darkorange; }
#config .boolean { color: blue; }
#config .null { color: magenta; }
#config .key { color: red; }

View File

@ -0,0 +1,25 @@
$(document).ready(function($) {
function syntaxHighlight(json) {
if (typeof json != 'string') {
json = JSON.stringify(json, undefined, 2);
}
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?)/g, function (match) {
var cls = 'number';
if (/^"/.test(match)) {
if (/:$/.test(match)) {
cls = 'key';
} else {
cls = 'string';
}
} else if (/true|false/.test(match)) {
cls = 'boolean';
} else if (/null/.test(match)) {
cls = 'null';
}
return '<span class="' + cls + '">' + match + '</span>';
});
}
$('#config-json').html((syntaxHighlight(ConfigJson)));
});

View File

@ -0,0 +1,49 @@
{% extends 'base.html' %}
{% load static %}
{% block page_title %}{{ block.super }} / Users{% endblock page_title %}
{% block content %}
<div id="webui">
<div id="webui_list">
<h1>WEBUI</h1>
<form method="post">
{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
<div class="row">
<div class="col-xs-12 col-sm-4">
{% if form.webui_props.errors %}<div class="alert alert-danger">{{ form.webui_props.errors }}</div>{% endif %}
<div class="form-group">
{{ form.webui_props.label_tag }}
{{ form.webui_props }}
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 hidden-xs">
<div class="form-group">
<button type="submit" class="btn btn-primary btn-green">Submit</button>
</div>
</div>
</div>
</form>
</div>
</div>
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'webui/js/config.js' %}"></script>
{% endblock extrajs %}
{% block extracss %}
<link href="{% static 'webui/css/webui.css' %}" rel="stylesheet">
{% endblock extracss %}

14
apimanager/webui/urls.py Normal file
View File

@ -0,0 +1,14 @@
# -*- coding: utf-8 -*-
"""
URLs for config app
"""
from django.conf.urls import url
from .views import IndexView
urlpatterns = [
url(r'^$',
IndexView.as_view(),
name='webui-index'),
]

76
apimanager/webui/views.py Normal file
View File

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
"""
Views of config app
"""
import json
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import FormView
from obp.api import API, APIError
from .forms import WebuiForm
from django.urls import reverse_lazy
def error_once_only(request, err):
"""
Just add the error once
:param request:
:param err:
:return:
"""
storage = messages.get_messages(request)
if str(err) not in [str(m.message) for m in storage]:
messages.error(request, err)
class IndexView(LoginRequiredMixin, FormView):
"""Index view for config"""
template_name = "webui/index.html"
form_class = WebuiForm
success_url = reverse_lazy('webui_list')
def dispatch(self, request, *args, **kwargs):
self.api = API(request.session.get('obp'))
return super(IndexView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
return context
def get_form(self, *args, **kwargs):
form = super(IndexView, self).get_form(*args, **kwargs)
# Cannot add api in constructor: super complains about unknown kwarg
fields = form.fields
form.api = self.api
try:
fields['webui_props'].initial = ""
except APIError as err:
messages.error(self.request, err)
except:
messages.error(self.request, "Unknown Error")
return form
def form_valid(self, form):
try:
data = form.cleaned_data
urlpath = '/management/webui_props'
payload = {
"name":"webui_api_explorer_url",
"value" : str(data["webui_props"]).replace("\n", "\\n").replace("\"", '\\"')
}
result = self.api.post(urlpath, payload=payload)
except APIError as err:
error_once_only(self.request, err)
return super(IndexView, self).form_invalid(form)
except Exception as err:
error_once_only(self.request, "Unknown Error")
return super(IndexView, self).form_invalid(form)
if 'code' in result and result['code']>=400:
error_once_only(self.request, result['message'])
return super(IndexView, self).form_valid(form)
msg = 'Submission successfully!'
messages.success(self.request, msg)
return super(IndexView, self).form_valid(form)

View File

@ -8,4 +8,5 @@ gunicorn==19.6.0
matplotlib
django-bootstrap-datepicker-plus
django-mathfilters
django-bootstrap3
django-bootstrap3
psycopg2