mirror of
https://github.com/OpenBankProject/API-Manager.git
synced 2026-02-06 14:16:46 +00:00
feature/Implemented a GUI for the
`/obp/v6.0.0/management/consumers/CONSUMER_ID/consumer/current-usage` endpoint with the
This commit is contained in:
parent
5f10a42dac
commit
56cda47af8
@ -182,62 +182,55 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if consumer.current_state %}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h2>{% trans "Current Usage" %}
|
||||
<button type="button" id="refreshUsageBtn" class="btn btn-sm btn-info pull-right" onclick="refreshUsageStats()">
|
||||
<span class="glyphicon glyphicon-refresh"></span> {% trans "Refresh (10s)" %}
|
||||
<span class="glyphicon glyphicon-refresh"></span> {% trans "Auto Refresh (5s)" %}
|
||||
</button>
|
||||
</h2>
|
||||
<div class="panel panel-info" id="usageStatsPanel">
|
||||
<div class="panel-body" id="usageStatsContent">
|
||||
{% if consumer.current_state.per_hour %}
|
||||
<div class="row" id="usageStatsRow">
|
||||
{% if consumer.current_state.per_second %}
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_second">
|
||||
<strong>{% trans "Per Second" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_second.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_second.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_second.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_second.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_second.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_second.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if consumer.current_state.per_minute %}
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_minute">
|
||||
<strong>{% trans "Per Minute" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_minute.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_minute.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_minute.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_minute.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_minute.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_minute.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_hour">
|
||||
<strong>{% trans "Per Hour" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_hour.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_hour.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_hour.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_hour.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_hour.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_hour.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_day">
|
||||
<strong>{% trans "Per Day" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_day.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_day.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_day.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_day.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_day.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_day.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_week">
|
||||
<strong>{% trans "Per Week" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_week.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_week.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_week.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_week.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_week.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_week.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-2" data-period="per_month">
|
||||
<strong>{% trans "Per Month" %}</strong><br>
|
||||
<span class="text-info usage-calls">{{ consumer.current_state.per_month.calls_made }} calls made</span><br>
|
||||
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_month.reset_in_seconds }} seconds</small>
|
||||
<span class="text-info usage-calls">{% if current_usage.per_month.calls_made|add:"0" == -1 %}Not tracked{% else %}{{ current_usage.per_month.calls_made }} calls made{% endif %}</span><br>
|
||||
<small class="text-muted usage-reset">{% if current_usage.per_month.reset_in_seconds|add:"0" == -1 %}Not tracked{% else %}Resets in {{ current_usage.per_month.reset_in_seconds }} seconds{% endif %}</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="refreshProgress" class="progress" style="display: none; margin-top: 15px;">
|
||||
<div class="progress-bar progress-bar-info progress-bar-striped active" id="progressBar" style="width: 0%"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div id="consumers-detail-consumer_id">
|
||||
@ -352,6 +345,14 @@
|
||||
{% if consumer.to_date %}
|
||||
$('body').attr('data-to-date', '{{ consumer.to_date }}');
|
||||
{% endif %}
|
||||
|
||||
// Debug: Log basic debugging info
|
||||
console.log('Current usage data available:', {% if current_usage %}true{% else %}false{% endif %});
|
||||
|
||||
// Initial load of usage data
|
||||
setTimeout(function() {
|
||||
fetchUsageData();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// Global functions for CRUD operations - attached to window for global access
|
||||
@ -469,17 +470,17 @@
|
||||
// Global variables for refresh functionality
|
||||
let refreshInterval = null;
|
||||
let refreshCount = 0;
|
||||
const MAX_REFRESH_COUNT = 10;
|
||||
const MAX_REFRESH_COUNT = 5;
|
||||
|
||||
// Function to refresh usage statistics
|
||||
function refreshUsageStats() {
|
||||
window.refreshUsageStats = function() {
|
||||
const button = document.getElementById('refreshUsageBtn');
|
||||
const progressDiv = document.getElementById('refreshProgress');
|
||||
const progressBar = document.getElementById('progressBar');
|
||||
|
||||
// Disable button and show progress
|
||||
button.disabled = true;
|
||||
button.innerHTML = '<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> Refreshing...';
|
||||
button.innerHTML = '<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> Auto Refreshing...';
|
||||
progressDiv.style.display = 'block';
|
||||
|
||||
// Reset counters
|
||||
@ -488,13 +489,15 @@
|
||||
// Start refresh cycle
|
||||
refreshInterval = setInterval(fetchUsageData, 1000);
|
||||
fetchUsageData(); // Initial fetch
|
||||
}
|
||||
};
|
||||
|
||||
// Function to fetch usage data via AJAX
|
||||
function fetchUsageData() {
|
||||
const consumerId = '{{ consumer.consumer_id }}';
|
||||
const panel = document.getElementById('usageStatsPanel');
|
||||
|
||||
console.log('Fetching usage data for consumer:', consumerId);
|
||||
|
||||
// Add refreshing effect to panel
|
||||
panel.classList.add('panel-refreshing');
|
||||
|
||||
@ -507,6 +510,7 @@
|
||||
},
|
||||
timeout: 5000, // 5 second timeout
|
||||
success: function(data) {
|
||||
console.log('Usage data received:', data);
|
||||
updateUsageDisplay(data);
|
||||
refreshCount++;
|
||||
|
||||
@ -516,7 +520,7 @@
|
||||
progressBar.style.width = progress + '%';
|
||||
progressBar.textContent = refreshCount + '/' + MAX_REFRESH_COUNT;
|
||||
|
||||
// Stop after 10 seconds
|
||||
// Stop after 5 seconds
|
||||
if (refreshCount >= MAX_REFRESH_COUNT) {
|
||||
clearInterval(refreshInterval);
|
||||
resetRefreshButton();
|
||||
@ -524,7 +528,7 @@
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error('Error fetching usage data:', error);
|
||||
console.error('Error fetching usage data:', error, xhr.responseText);
|
||||
showRefreshError(error);
|
||||
|
||||
refreshCount++;
|
||||
@ -562,12 +566,12 @@
|
||||
|
||||
// Function to update usage display with new data
|
||||
function updateUsageDisplay(data) {
|
||||
if (data && data.current_state) {
|
||||
const currentState = data.current_state;
|
||||
console.log('Updating display with data:', data);
|
||||
if (data) {
|
||||
const periods = ['per_second', 'per_minute', 'per_hour', 'per_day', 'per_week', 'per_month'];
|
||||
|
||||
periods.forEach(function(period) {
|
||||
const periodData = currentState[period];
|
||||
const periodData = data[period];
|
||||
if (periodData) {
|
||||
const periodDiv = document.querySelector('[data-period="' + period + '"]');
|
||||
if (periodDiv) {
|
||||
@ -575,13 +579,14 @@
|
||||
const resetSpan = periodDiv.querySelector('.usage-reset');
|
||||
|
||||
if (callsSpan) {
|
||||
const oldCalls = callsSpan.textContent.match(/\d+/);
|
||||
const oldCalls = callsSpan.textContent.match(/-?\d+/);
|
||||
const newCalls = periodData.calls_made;
|
||||
const displayCalls = newCalls === -1 ? 'Not tracked' : newCalls + ' calls made';
|
||||
|
||||
// Check if calls increased
|
||||
const callsIncreased = oldCalls && parseInt(oldCalls[0]) < newCalls;
|
||||
const callsIncreased = oldCalls && parseInt(oldCalls[0]) < newCalls && newCalls !== -1;
|
||||
|
||||
callsSpan.textContent = newCalls + ' calls made';
|
||||
callsSpan.textContent = displayCalls;
|
||||
|
||||
// Add visual feedback
|
||||
callsSpan.classList.add('updating');
|
||||
@ -604,7 +609,8 @@
|
||||
}
|
||||
|
||||
if (resetSpan) {
|
||||
resetSpan.textContent = 'Resets in ' + periodData.reset_in_seconds + ' seconds';
|
||||
const resetText = periodData.reset_in_seconds === -1 ? 'Not tracked' : 'Resets in ' + periodData.reset_in_seconds + ' seconds';
|
||||
resetSpan.textContent = resetText;
|
||||
// Add subtle animation to reset timer
|
||||
resetSpan.style.opacity = '0.7';
|
||||
setTimeout(function() {
|
||||
@ -621,7 +627,7 @@
|
||||
}
|
||||
|
||||
// Function to update last refresh time
|
||||
function updateLastRefreshTime() {
|
||||
window.updateLastRefreshTime = function() {
|
||||
let timeDiv = document.getElementById('lastRefreshTime');
|
||||
if (!timeDiv) {
|
||||
timeDiv = document.createElement('small');
|
||||
@ -638,13 +644,12 @@
|
||||
}
|
||||
|
||||
// Function to reset refresh button
|
||||
function resetRefreshButton() {
|
||||
window.resetRefreshButton = function() {
|
||||
const button = document.getElementById('refreshUsageBtn');
|
||||
const progressDiv = document.getElementById('refreshProgress');
|
||||
const panel = document.getElementById('usageStatsPanel');
|
||||
|
||||
button.disabled = false;
|
||||
button.innerHTML = '<span class="glyphicon glyphicon-refresh"></span> {% trans "Refresh (10s)" %}';
|
||||
button.innerHTML = '<span class="glyphicon glyphicon-refresh"></span> Auto Refresh (5s)';
|
||||
progressDiv.style.display = 'none';
|
||||
document.getElementById('progressBar').style.width = '0%';
|
||||
document.getElementById('progressBar').textContent = '';
|
||||
@ -654,7 +659,7 @@
|
||||
if (errorDiv && errorDiv.parentNode) {
|
||||
errorDiv.parentNode.removeChild(errorDiv);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
{% endblock extrajs %}
|
||||
|
||||
|
||||
@ -455,6 +455,15 @@ class DetailView(LoginRequiredMixin, FormView):
|
||||
api = API(self.request.session.get("obp"))
|
||||
consumer = {}
|
||||
call_limits = {}
|
||||
# Initialize current_usage with default values
|
||||
current_usage = {
|
||||
"per_second": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_minute": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_hour": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_day": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_week": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_month": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
}
|
||||
|
||||
try:
|
||||
urlpath = "/management/consumers/{}".format(self.kwargs["consumer_id"])
|
||||
@ -477,6 +486,19 @@ class DetailView(LoginRequiredMixin, FormView):
|
||||
call_limits_urlpath, version=settings.API_VERSION["v510"]
|
||||
)
|
||||
|
||||
# Get current usage data using v6.0.0 API
|
||||
current_usage_urlpath = (
|
||||
"/management/consumers/{}/consumer/current-usage".format(
|
||||
self.kwargs["consumer_id"]
|
||||
)
|
||||
)
|
||||
current_usage = api.get(
|
||||
current_usage_urlpath, version=settings.API_VERSION["v600"]
|
||||
)
|
||||
if "code" in current_usage and current_usage["code"] >= 400:
|
||||
# If current usage fails, keep the default values already set
|
||||
pass
|
||||
|
||||
if "code" in call_limits and call_limits["code"] >= 400:
|
||||
messages.error(self.request, "{}".format(call_limits["message"]))
|
||||
call_limits = {"limits": []}
|
||||
@ -541,29 +563,39 @@ class DetailView(LoginRequiredMixin, FormView):
|
||||
except Exception as err:
|
||||
messages.error(self.request, "{}".format(err))
|
||||
finally:
|
||||
context.update({"consumer": consumer, "call_limits": call_limits})
|
||||
# Ensure current_usage always has the expected structure
|
||||
if not current_usage or "per_second" not in current_usage:
|
||||
current_usage = {
|
||||
"per_second": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_minute": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_hour": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_day": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_week": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
"per_month": {"calls_made": -1, "reset_in_seconds": -1},
|
||||
}
|
||||
context.update({"consumer": consumer, "call_limits": call_limits, "current_usage": current_usage})
|
||||
return context
|
||||
|
||||
|
||||
class UsageDataAjaxView(LoginRequiredMixin, TemplateView):
|
||||
"""AJAX view to return usage data for real-time updates"""
|
||||
"""AJAX view to return current usage data for real-time updates"""
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
api = API(self.request.session.get("obp"))
|
||||
try:
|
||||
call_limits_urlpath = (
|
||||
"/management/consumers/{}/consumer/rate-limits".format(
|
||||
current_usage_urlpath = (
|
||||
"/management/consumers/{}/consumer/current-usage".format(
|
||||
self.kwargs["consumer_id"]
|
||||
)
|
||||
)
|
||||
call_limits = api.get(
|
||||
call_limits_urlpath, version=settings.API_VERSION["v510"]
|
||||
current_usage = api.get(
|
||||
current_usage_urlpath, version=settings.API_VERSION["v600"]
|
||||
)
|
||||
|
||||
if "code" in call_limits and call_limits["code"] >= 400:
|
||||
return JsonResponse({"error": call_limits["message"]}, status=400)
|
||||
if "code" in current_usage and current_usage["code"] >= 400:
|
||||
return JsonResponse({"error": current_usage["message"]}, status=400)
|
||||
|
||||
return JsonResponse(call_limits)
|
||||
return JsonResponse(current_usage)
|
||||
except APIError as err:
|
||||
return JsonResponse({"error": str(err)}, status=500)
|
||||
except Exception as err:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user