diff --git a/atdb/atdb/static/taskdatabase/style.css b/atdb/atdb/static/taskdatabase/style.css index abaa979356a70d6a40c5ffac12ca958ef50d26c4..86e9ac908dc232210c22807bcabfd36f7bd2efe7 100644 --- a/atdb/atdb/static/taskdatabase/style.css +++ b/atdb/atdb/static/taskdatabase/style.css @@ -34,7 +34,7 @@ TD { } -.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed { +.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed,.on_hold { color: red; font-weight: bold; } diff --git a/atdb/taskdatabase/models.py b/atdb/taskdatabase/models.py index 3a770aa02f4adf7425479d30d119969050e06e71..52295661a6f8d2069b216223a6c0ed51c59452a0 100644 --- a/atdb/taskdatabase/models.py +++ b/atdb/taskdatabase/models.py @@ -226,6 +226,14 @@ class LatestMonitor(models.Model): status = models.CharField(max_length=50, default="ok", null=True) metadata = models.JSONField(null=True, blank=True) + @property + def enabled(self): + try: + enabled = self.metadata['enabled'] + return enabled + except: + return None + # the representation of the value in the REST API def __str__(self): return str(self.name) + ' - ('+ self.hostname+') - '+str(self.timestamp) + ' - ' + self.status @@ -246,11 +254,20 @@ class Monitor(models.Model): # in the LatestMonitor, and update if it is newer. try: latestMonitor = LatestMonitor.objects.get(name=self.name,hostname=self.hostname) + # carry over the metadata, if possible + latest_metadata = latestMonitor.metadata latestMonitor.delete() except: pass # this combination of name and hostname didn't yet exist, create it. + metadata = self.metadata + try: + if latest_metadata: + metadata = latest_metadata + except: + pass + latestMonitor = LatestMonitor( name=self.name, type=self.type, @@ -259,7 +276,7 @@ class Monitor(models.Model): process_id = self.process_id, description = self.description, status = self.status, - metadata = self.metadata + metadata = metadata ) latestMonitor.save() diff --git a/atdb/taskdatabase/services/algorithms.py b/atdb/taskdatabase/services/algorithms.py index 0fa1fce7ed1fe033353a16efb482646959a2845c..fc31a65cafa481c043d54d1c81e3019174bd8109 100644 --- a/atdb/taskdatabase/services/algorithms.py +++ b/atdb/taskdatabase/services/algorithms.py @@ -288,19 +288,27 @@ def convert_monitor_to_html(request, monitor_data): line += "<td><b>" + link_to_service_history + "</b></td>" line += "<td>" + str(record.hostname) + "</td>" + if record.enabled=="True": + button_html = '<a href="service_hold_resume/' + str(record.pk) + '/False"' + 'class="btn btn-warning btn-sm" role="button"><i class="fas fa-pause"></i> Hold</a>' + else: + button_html = '<a href="service_hold_resume/' + str(record.pk) + '/True"' + 'class="btn btn-success btn-sm" role="button"><i class="fas fa-play"></i> Resume</a>' + # if the heartbeat is 30 minutes late, show '(late)' in red if delta.seconds > 1800: + line += '<td>' + button_html + str(record.enabled) + "</td>" line += "<td><i>unknown</i></td>" line += '<td class="error">' + str(record.timestamp.strftime(TIME_FORMAT)) + " - (late)</td>" else: + line += '<td>' + button_html + str(record.enabled) + "</td>" line += '<td class="' + record.status + '" >' + str(record.status) + "</td>" line += '<td>' + str(record.timestamp.strftime(TIME_FORMAT)) + "</td>" + line += "<td>" + str(record.process_id) + "</td>" line += "<td>" + str(record.description) + "</td>" line += "</tr>" results = results + line - except: + except Exception as e: results = "<tr><td>no data</td></tr>" return results diff --git a/atdb/taskdatabase/static/taskdatabase/style.css b/atdb/taskdatabase/static/taskdatabase/style.css index abaa979356a70d6a40c5ffac12ca958ef50d26c4..86e9ac908dc232210c22807bcabfd36f7bd2efe7 100644 --- a/atdb/taskdatabase/static/taskdatabase/style.css +++ b/atdb/taskdatabase/static/taskdatabase/style.css @@ -34,7 +34,7 @@ TD { } -.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed { +.error,.failed,.staging_failed,.staged_failed,.processed_failed,.scrubbed_failed,.stored_failed,.archived_failed,.on_hold { color: red; font-weight: bold; } diff --git a/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html b/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html index 6b85c675e86ef472209e1402525f456b39e13d76..f6b7aced89a17c8a45e41eeaca2102d6e7b8a490 100644 --- a/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html +++ b/atdb/taskdatabase/templates/taskdatabase/monitoring_page.html @@ -22,7 +22,7 @@ </p> {% endif %} <table class="table table-striped"> - <th>LDV-Service</th><th>Host</th><th>Status</th><th>Timestamp</th><th>Process id</th><th>Description</th> + <th>LDV-Service</th><th>Host</th><th>Enabled</th><th>Status</th><th>Timestamp</th><th>Process id</th><th>Description</th> <tbody> {{ monitor_results | safe }} </tbody> diff --git a/atdb/taskdatabase/urls.py b/atdb/taskdatabase/urls.py index d950d86cf0e76e08b1188b68f26d42bc2d5bd722..e55c0c0335c99b9232cddff67cd81f3287ef90ad 100644 --- a/atdb/taskdatabase/urls.py +++ b/atdb/taskdatabase/urls.py @@ -72,7 +72,7 @@ urlpatterns = [ path('monitor/<int:pk>/', views.MonitorDetailsViewAPI.as_view(),name='monitor-detail-view-api'), path('latest_monitor/', views.LatestMonitorListViewAPI.as_view(),name='latest-monitor-detail-view-api'), path('monitor/clear_inactive_services/', views.ClearInactiveServices, name='clear-inactive-services'), - + path('monitoring/service_hold_resume/<int:pk>/<enabled>', views.ServiceHoldResume, name='service-hold-resume'), # --- custom requests --- # /atdb/get_size?status__in=defined,staged @@ -108,5 +108,7 @@ urlpatterns = [ path('tasks/<int:pk>/hold/<hold_it>', views.Hold, name='task-hold-resume'), path('tasks/<int:pk>/query-hold/<hold_it>/<query_params>', views.HoldQuery, name='query-hold-resume'), + path('tasks/<int:pk>/hold/<hold_it>/<page>', views.Hold, name='service-hold-resume'), + path('hello/', views.HelloView.as_view(), name='hello'), ] diff --git a/atdb/taskdatabase/views.py b/atdb/taskdatabase/views.py index 654b8cd028f96c4d344d4015ddba8e2e1a01f3b0..22d065d23bb09681b20689e98ed757eed2b57816 100644 --- a/atdb/taskdatabase/views.py +++ b/atdb/taskdatabase/views.py @@ -41,7 +41,6 @@ from .serializers import \ PostProcessingRuleSerializer, \ MonitorSerializer, LatestMonitorSerializer - from .services import algorithms logger = logging.getLogger(__name__) @@ -156,6 +155,15 @@ class MonitorFilter(filters.FilterSet): 'timestamp': ['icontains'], } +class LatestMonitorFilter(filters.FilterSet): + class Meta: + model = LatestMonitor + + fields = { + 'name': ['exact', 'icontains', 'in'], + 'hostname': ['exact', 'icontains', 'in'], + } + # ---------- Tables2 Views (experimental) ----------- class QueryView(SingleTableMixin, FilterView): table_class = TaskTable @@ -903,7 +911,7 @@ class LatestMonitorListViewAPI(generics.ListCreateAPIView): serializer_class = LatestMonitorSerializer filter_backends = (filters.DjangoFilterBackend,) - filter_class = MonitorFilter + filter_class = LatestMonitorFilter @login_required @@ -945,6 +953,19 @@ def HoldQuery(request, pk, hold_it, query_params): current_query_params = convert_query_params_to_url(query_params) return redirect('/atdb/query/?' + current_query_params) +@login_required +def ServiceHoldResume(request, pk, enabled): + model = LatestMonitor + service = LatestMonitor.objects.get(pk=pk) + metadata = service.metadata + if not metadata: + metadata = {} + + metadata['enabled'] = enabled + service.metadata = metadata + service.save() + return redirect('/atdb/monitoring') + @login_required def TaskSetStatus(request, pk, new_status, page=0):