Skip to content

Commit 56cda47

Browse files
feature/Implemented a GUI for the
`/obp/v6.0.0/management/consumers/CONSUMER_ID/consumer/current-usage` endpoint with the
1 parent 5f10a42 commit 56cda47

2 files changed

Lines changed: 85 additions & 48 deletions

File tree

apimanager/consumers/templates/consumers/detail.html

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -182,62 +182,55 @@ <h4 class="panel-title">{% trans "Existing Rate Limits" %}</h4>
182182
</div>
183183
</div>
184184

185-
{% if consumer.current_state %}
186185
<div class="row">
187186
<div class="col-xs-12">
188187
<h2>{% trans "Current Usage" %}
189188
<button type="button" id="refreshUsageBtn" class="btn btn-sm btn-info pull-right" onclick="refreshUsageStats()">
190-
<span class="glyphicon glyphicon-refresh"></span> {% trans "Refresh (10s)" %}
189+
<span class="glyphicon glyphicon-refresh"></span> {% trans "Auto Refresh (5s)" %}
191190
</button>
192191
</h2>
193192
<div class="panel panel-info" id="usageStatsPanel">
194193
<div class="panel-body" id="usageStatsContent">
195-
{% if consumer.current_state.per_hour %}
196194
<div class="row" id="usageStatsRow">
197-
{% if consumer.current_state.per_second %}
198195
<div class="col-xs-6 col-sm-2" data-period="per_second">
199196
<strong>{% trans "Per Second" %}</strong><br>
200-
<span class="text-info usage-calls">{{ consumer.current_state.per_second.calls_made }} calls made</span><br>
201-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_second.reset_in_seconds }} seconds</small>
197+
<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>
198+
<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>
202199
</div>
203-
{% endif %}
204-
{% if consumer.current_state.per_minute %}
205200
<div class="col-xs-6 col-sm-2" data-period="per_minute">
206201
<strong>{% trans "Per Minute" %}</strong><br>
207-
<span class="text-info usage-calls">{{ consumer.current_state.per_minute.calls_made }} calls made</span><br>
208-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_minute.reset_in_seconds }} seconds</small>
202+
<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>
203+
<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>
209204
</div>
210-
{% endif %}
211205
<div class="col-xs-6 col-sm-2" data-period="per_hour">
212206
<strong>{% trans "Per Hour" %}</strong><br>
213-
<span class="text-info usage-calls">{{ consumer.current_state.per_hour.calls_made }} calls made</span><br>
214-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_hour.reset_in_seconds }} seconds</small>
207+
<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>
208+
<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>
215209
</div>
216210
<div class="col-xs-6 col-sm-2" data-period="per_day">
217211
<strong>{% trans "Per Day" %}</strong><br>
218-
<span class="text-info usage-calls">{{ consumer.current_state.per_day.calls_made }} calls made</span><br>
219-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_day.reset_in_seconds }} seconds</small>
212+
<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>
213+
<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>
220214
</div>
221215
<div class="col-xs-6 col-sm-2" data-period="per_week">
222216
<strong>{% trans "Per Week" %}</strong><br>
223-
<span class="text-info usage-calls">{{ consumer.current_state.per_week.calls_made }} calls made</span><br>
224-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_week.reset_in_seconds }} seconds</small>
217+
<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>
218+
<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>
225219
</div>
226220
<div class="col-xs-6 col-sm-2" data-period="per_month">
227221
<strong>{% trans "Per Month" %}</strong><br>
228-
<span class="text-info usage-calls">{{ consumer.current_state.per_month.calls_made }} calls made</span><br>
229-
<small class="text-muted usage-reset">Resets in {{ consumer.current_state.per_month.reset_in_seconds }} seconds</small>
222+
<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>
223+
<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>
230224
</div>
231225
</div>
232-
{% endif %}
233226
<div id="refreshProgress" class="progress" style="display: none; margin-top: 15px;">
234227
<div class="progress-bar progress-bar-info progress-bar-striped active" id="progressBar" style="width: 0%"></div>
235228
</div>
229+
236230
</div>
237231
</div>
238232
</div>
239233
</div>
240-
{% endif %}
241234
<div class="row">
242235
<div class="col-xs-12">
243236
<div id="consumers-detail-consumer_id">
@@ -352,6 +345,14 @@ <h2>{% trans "Current Usage" %}
352345
{% if consumer.to_date %}
353346
$('body').attr('data-to-date', '{{ consumer.to_date }}');
354347
{% endif %}
348+
349+
// Debug: Log basic debugging info
350+
console.log('Current usage data available:', {% if current_usage %}true{% else %}false{% endif %});
351+
352+
// Initial load of usage data
353+
setTimeout(function() {
354+
fetchUsageData();
355+
}, 1000);
355356
});
356357

357358
// Global functions for CRUD operations - attached to window for global access
@@ -469,17 +470,17 @@ <h2>{% trans "Current Usage" %}
469470
// Global variables for refresh functionality
470471
let refreshInterval = null;
471472
let refreshCount = 0;
472-
const MAX_REFRESH_COUNT = 10;
473+
const MAX_REFRESH_COUNT = 5;
473474

474475
// Function to refresh usage statistics
475-
function refreshUsageStats() {
476+
window.refreshUsageStats = function() {
476477
const button = document.getElementById('refreshUsageBtn');
477478
const progressDiv = document.getElementById('refreshProgress');
478479
const progressBar = document.getElementById('progressBar');
479480

480481
// Disable button and show progress
481482
button.disabled = true;
482-
button.innerHTML = '<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> Refreshing...';
483+
button.innerHTML = '<span class="glyphicon glyphicon-refresh glyphicon-spin"></span> Auto Refreshing...';
483484
progressDiv.style.display = 'block';
484485

485486
// Reset counters
@@ -488,13 +489,15 @@ <h2>{% trans "Current Usage" %}
488489
// Start refresh cycle
489490
refreshInterval = setInterval(fetchUsageData, 1000);
490491
fetchUsageData(); // Initial fetch
491-
}
492+
};
492493

493494
// Function to fetch usage data via AJAX
494495
function fetchUsageData() {
495496
const consumerId = '{{ consumer.consumer_id }}';
496497
const panel = document.getElementById('usageStatsPanel');
497498

499+
console.log('Fetching usage data for consumer:', consumerId);
500+
498501
// Add refreshing effect to panel
499502
panel.classList.add('panel-refreshing');
500503

@@ -507,6 +510,7 @@ <h2>{% trans "Current Usage" %}
507510
},
508511
timeout: 5000, // 5 second timeout
509512
success: function(data) {
513+
console.log('Usage data received:', data);
510514
updateUsageDisplay(data);
511515
refreshCount++;
512516

@@ -516,15 +520,15 @@ <h2>{% trans "Current Usage" %}
516520
progressBar.style.width = progress + '%';
517521
progressBar.textContent = refreshCount + '/' + MAX_REFRESH_COUNT;
518522

519-
// Stop after 10 seconds
523+
// Stop after 5 seconds
520524
if (refreshCount >= MAX_REFRESH_COUNT) {
521525
clearInterval(refreshInterval);
522526
resetRefreshButton();
523527
panel.classList.remove('panel-refreshing');
524528
}
525529
},
526530
error: function(xhr, status, error) {
527-
console.error('Error fetching usage data:', error);
531+
console.error('Error fetching usage data:', error, xhr.responseText);
528532
showRefreshError(error);
529533

530534
refreshCount++;
@@ -562,26 +566,27 @@ <h2>{% trans "Current Usage" %}
562566

563567
// Function to update usage display with new data
564568
function updateUsageDisplay(data) {
565-
if (data && data.current_state) {
566-
const currentState = data.current_state;
569+
console.log('Updating display with data:', data);
570+
if (data) {
567571
const periods = ['per_second', 'per_minute', 'per_hour', 'per_day', 'per_week', 'per_month'];
568572

569573
periods.forEach(function(period) {
570-
const periodData = currentState[period];
574+
const periodData = data[period];
571575
if (periodData) {
572576
const periodDiv = document.querySelector('[data-period="' + period + '"]');
573577
if (periodDiv) {
574578
const callsSpan = periodDiv.querySelector('.usage-calls');
575579
const resetSpan = periodDiv.querySelector('.usage-reset');
576580

577581
if (callsSpan) {
578-
const oldCalls = callsSpan.textContent.match(/\d+/);
582+
const oldCalls = callsSpan.textContent.match(/-?\d+/);
579583
const newCalls = periodData.calls_made;
584+
const displayCalls = newCalls === -1 ? 'Not tracked' : newCalls + ' calls made';
580585

581586
// Check if calls increased
582-
const callsIncreased = oldCalls && parseInt(oldCalls[0]) < newCalls;
587+
const callsIncreased = oldCalls && parseInt(oldCalls[0]) < newCalls && newCalls !== -1;
583588

584-
callsSpan.textContent = newCalls + ' calls made';
589+
callsSpan.textContent = displayCalls;
585590

586591
// Add visual feedback
587592
callsSpan.classList.add('updating');
@@ -604,7 +609,8 @@ <h2>{% trans "Current Usage" %}
604609
}
605610

606611
if (resetSpan) {
607-
resetSpan.textContent = 'Resets in ' + periodData.reset_in_seconds + ' seconds';
612+
const resetText = periodData.reset_in_seconds === -1 ? 'Not tracked' : 'Resets in ' + periodData.reset_in_seconds + ' seconds';
613+
resetSpan.textContent = resetText;
608614
// Add subtle animation to reset timer
609615
resetSpan.style.opacity = '0.7';
610616
setTimeout(function() {
@@ -621,7 +627,7 @@ <h2>{% trans "Current Usage" %}
621627
}
622628

623629
// Function to update last refresh time
624-
function updateLastRefreshTime() {
630+
window.updateLastRefreshTime = function() {
625631
let timeDiv = document.getElementById('lastRefreshTime');
626632
if (!timeDiv) {
627633
timeDiv = document.createElement('small');
@@ -638,13 +644,12 @@ <h2>{% trans "Current Usage" %}
638644
}
639645

640646
// Function to reset refresh button
641-
function resetRefreshButton() {
647+
window.resetRefreshButton = function() {
642648
const button = document.getElementById('refreshUsageBtn');
643649
const progressDiv = document.getElementById('refreshProgress');
644-
const panel = document.getElementById('usageStatsPanel');
645650

646651
button.disabled = false;
647-
button.innerHTML = '<span class="glyphicon glyphicon-refresh"></span> {% trans "Refresh (10s)" %}';
652+
button.innerHTML = '<span class="glyphicon glyphicon-refresh"></span> Auto Refresh (5s)';
648653
progressDiv.style.display = 'none';
649654
document.getElementById('progressBar').style.width = '0%';
650655
document.getElementById('progressBar').textContent = '';
@@ -654,7 +659,7 @@ <h2>{% trans "Current Usage" %}
654659
if (errorDiv && errorDiv.parentNode) {
655660
errorDiv.parentNode.removeChild(errorDiv);
656661
}
657-
}
662+
};
658663
</script>
659664
{% endblock extrajs %}
660665

apimanager/consumers/views.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,15 @@ def get_context_data(self, **kwargs):
455455
api = API(self.request.session.get("obp"))
456456
consumer = {}
457457
call_limits = {}
458+
# Initialize current_usage with default values
459+
current_usage = {
460+
"per_second": {"calls_made": -1, "reset_in_seconds": -1},
461+
"per_minute": {"calls_made": -1, "reset_in_seconds": -1},
462+
"per_hour": {"calls_made": -1, "reset_in_seconds": -1},
463+
"per_day": {"calls_made": -1, "reset_in_seconds": -1},
464+
"per_week": {"calls_made": -1, "reset_in_seconds": -1},
465+
"per_month": {"calls_made": -1, "reset_in_seconds": -1},
466+
}
458467

459468
try:
460469
urlpath = "/management/consumers/{}".format(self.kwargs["consumer_id"])
@@ -477,6 +486,19 @@ def get_context_data(self, **kwargs):
477486
call_limits_urlpath, version=settings.API_VERSION["v510"]
478487
)
479488

489+
# Get current usage data using v6.0.0 API
490+
current_usage_urlpath = (
491+
"/management/consumers/{}/consumer/current-usage".format(
492+
self.kwargs["consumer_id"]
493+
)
494+
)
495+
current_usage = api.get(
496+
current_usage_urlpath, version=settings.API_VERSION["v600"]
497+
)
498+
if "code" in current_usage and current_usage["code"] >= 400:
499+
# If current usage fails, keep the default values already set
500+
pass
501+
480502
if "code" in call_limits and call_limits["code"] >= 400:
481503
messages.error(self.request, "{}".format(call_limits["message"]))
482504
call_limits = {"limits": []}
@@ -541,29 +563,39 @@ def get_context_data(self, **kwargs):
541563
except Exception as err:
542564
messages.error(self.request, "{}".format(err))
543565
finally:
544-
context.update({"consumer": consumer, "call_limits": call_limits})
566+
# Ensure current_usage always has the expected structure
567+
if not current_usage or "per_second" not in current_usage:
568+
current_usage = {
569+
"per_second": {"calls_made": -1, "reset_in_seconds": -1},
570+
"per_minute": {"calls_made": -1, "reset_in_seconds": -1},
571+
"per_hour": {"calls_made": -1, "reset_in_seconds": -1},
572+
"per_day": {"calls_made": -1, "reset_in_seconds": -1},
573+
"per_week": {"calls_made": -1, "reset_in_seconds": -1},
574+
"per_month": {"calls_made": -1, "reset_in_seconds": -1},
575+
}
576+
context.update({"consumer": consumer, "call_limits": call_limits, "current_usage": current_usage})
545577
return context
546578

547579

548580
class UsageDataAjaxView(LoginRequiredMixin, TemplateView):
549-
"""AJAX view to return usage data for real-time updates"""
581+
"""AJAX view to return current usage data for real-time updates"""
550582

551583
def get(self, request, *args, **kwargs):
552584
api = API(self.request.session.get("obp"))
553585
try:
554-
call_limits_urlpath = (
555-
"/management/consumers/{}/consumer/rate-limits".format(
586+
current_usage_urlpath = (
587+
"/management/consumers/{}/consumer/current-usage".format(
556588
self.kwargs["consumer_id"]
557589
)
558590
)
559-
call_limits = api.get(
560-
call_limits_urlpath, version=settings.API_VERSION["v510"]
591+
current_usage = api.get(
592+
current_usage_urlpath, version=settings.API_VERSION["v600"]
561593
)
562594

563-
if "code" in call_limits and call_limits["code"] >= 400:
564-
return JsonResponse({"error": call_limits["message"]}, status=400)
595+
if "code" in current_usage and current_usage["code"] >= 400:
596+
return JsonResponse({"error": current_usage["message"]}, status=400)
565597

566-
return JsonResponse(call_limits)
598+
return JsonResponse(current_usage)
567599
except APIError as err:
568600
return JsonResponse({"error": str(err)}, status=500)
569601
except Exception as err:

0 commit comments

Comments
 (0)