diff --git a/SAS/TMSS/src/tmss/settings.py b/SAS/TMSS/src/tmss/settings.py index 97b14e0609ec957a3553493dec1a668033b7a841..84b03966e8e201c27685d55e7754a1c75afa8ef8 100644 --- a/SAS/TMSS/src/tmss/settings.py +++ b/SAS/TMSS/src/tmss/settings.py @@ -347,3 +347,9 @@ SWAGGER_SETTINGS = { }, } + +# TODO Do I need distinguish more between Test and Production Environment?? +# maybe a local file in Development environment for test purposes +SCU = "http://scu199" if isDevelopmentEnvironment() or isTestEnvironment() else "http://scu001" +PIPELINE_SUBTASK_LOG_URL = SCU + ".control.lofar:7412/tasks/%s/log.html" +OBSERVATION_SUBTASK_LOG_URL = "https://proxy.lofar.eu/inspect/%s/rtcp-%s.errors" diff --git a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py index c5c077d71df048a7d92c371c92b3f6887f5a0c75..a6932d705e358db231d0fe22f47496a970591b29 100644 --- a/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py +++ b/SAS/TMSS/src/tmss/tmssapp/models/scheduling.py @@ -21,7 +21,8 @@ from lofar.messaging.messagebus import ToBus, DEFAULT_BROKER, DEFAULT_BUSNAME from lofar.messaging.messages import EventMessage from lofar.sas.tmss.client.tmssbuslistener import DEFAULT_TMSS_SUBTASK_NOTIFICATION_PREFIX from lofar.common.util import single_line_with_single_spaces - +from django.conf import settings +from lofar.sas.resourceassignment.resourceassignmentservice.rpc import RADBRPC # # I/O # @@ -224,6 +225,32 @@ class Subtask(BasicCommon): # update the previous state value self.__original_state_id = self.state_id + @property + def log_url(self): + """ + Return the link to the pipeline log in case of pipeline or + link to COBALT error log in case of an observation + otherwise just an empty string + """ + if self.specifications_template.type.value == SubtaskType.Choices.OBSERVATION.value: + url = settings.OBSERVATION_SUBTASK_LOG_URL % (self.id, self.id) + elif self.specifications_template.type.value == SubtaskType.Choices.PIPELINE.value: + # Get RADBID, subtask must be at least 'scheduled' to exist in radb + # If RA is not started don't wait longer than 10 seconds + with RADBRPC.create(timeout=10) as radbrpc: + try: + radb_id = radbrpc.getTask(tmss_id=self.id) + except: + radb_id = None + if radb_id is None: + url = "not available (missing radbid)" + else: + url = settings.PIPELINE_SUBTASK_LOG_URL % radb_id['id'] + else: + url = "" + return url + + class SubtaskStateLog(BasicCommon): """ History of state changes on subtasks diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py b/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py index 8df71d216ab8367835050fade5cbba341b7cbc7d..091a2352b42ec6cea116152462769e62cdd624c7 100644 --- a/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py +++ b/SAS/TMSS/src/tmss/tmssapp/serializers/scheduling.py @@ -85,7 +85,7 @@ class SubtaskSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.Subtask fields = '__all__' - extra_fields = ['cluster_value'] + extra_fields = ['cluster_value', 'log_url'] class SubtaskInputSerializer(RelationalHyperlinkedModelSerializer): diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py index 242f06d05a6084ad6f0aa64a46eec8ce75ac164d..6e292b61afa714df6356cf528da69ebc18a555f3 100644 --- a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py +++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py @@ -21,6 +21,7 @@ from drf_yasg.openapi import Parameter from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet, LOFARNestedViewSet, AbstractTemplateViewSet, LOFARCopyViewSet from lofar.sas.tmss.tmss.tmssapp import models from lofar.sas.tmss.tmss.tmssapp import serializers +from django.http import JsonResponse from datetime import datetime from lofar.common.json_utils import get_default_json_object_for_schema @@ -629,6 +630,20 @@ class SchedulingUnitBlueprintViewSet(LOFARViewSet): return Response(serializers.SchedulingUnitBlueprintSerializer(scheduling_unit_blueprint, context={'request':request}).data, status=status.HTTP_201_CREATED) + @swagger_auto_schema(responses={200: 'The available logging urls for all Subtasks of this SchedulingUnitBlueprint.', + 403: 'forbidden'}, + operation_description="Get the subtask logging urls of this schedulingunit blueprint.") + @action(methods=['get'], detail=True, url_name='get_all_subtasks_log_urls') + def get_all_subtasks_log_urls(self, request, pk=None): + subtasks = models.Subtask.objects.filter(task_blueprint__scheduling_unit_blueprint_id=pk) + result = [] + for subtask in subtasks: + if subtask.log_url != "": + result.append({"subtaskid": subtask.id, "type": subtask.specifications_template.type.value, "log_url": subtask.log_url}) + # TypeError: In order to allow non-dict objects to be serialized set the safe parameter to False. + # result is list of dict so thats why + return JsonResponse(result, safe=False) + class SchedulingUnitBlueprintNestedViewSet(LOFARNestedViewSet): queryset = models.SchedulingUnitBlueprint.objects.all() diff --git a/SAS/TMSS/test/CMakeLists.txt b/SAS/TMSS/test/CMakeLists.txt index 769fce231ac3bc18470ae3c974456d4ec089ff68..716469c7ca9294350badc60448fc92870eb6be8e 100644 --- a/SAS/TMSS/test/CMakeLists.txt +++ b/SAS/TMSS/test/CMakeLists.txt @@ -38,5 +38,5 @@ if(BUILD_TESTING) file(COPY testdata DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) set_tests_properties(t_tmssapp_scheduling_REST_API PROPERTIES TIMEOUT 300) - set_tests_properties(t_tmssapp_specification_REST_API PROPERTIES TIMEOUT 300) + set_tests_properties(t_tmssapp_specification_REST_API PROPERTIES TIMEOUT 360) endif() diff --git a/SAS/TMSS/test/t_subtasks.py b/SAS/TMSS/test/t_subtasks.py index 8d80cb4b2cd6a652d54506ca3fcc1c5a1174e153..7e024d6b143a6483c1bfcdaedceb428cd44ae281 100755 --- a/SAS/TMSS/test/t_subtasks.py +++ b/SAS/TMSS/test/t_subtasks.py @@ -325,6 +325,23 @@ class SettingTest(unittest.TestCase): with self.assertRaises(SubtaskSchedulingException): schedule_observation_subtask(obs_st) + def test_links_to_log_files(self): + """ + Test if the links to logging of a subtasks is correct: + For an observation the subtaskid is in the logging url + For a pipeline the radbid of the subtaskid is in the link, BUT because RA is not started is should + return "not available" + All other subtask types (like qa) should have an empty string (no logging) + """ + subtask_pipeline = create_subtask_object_for_testing("pipeline", "defined") + subtask_qa_plots = create_subtask_object_for_testing("qa_plots", "defined") + subtask_observation = create_subtask_object_for_testing("observation", "defined") + + self.assertIn("proxy.lofar.eu", subtask_observation.log_url) + self.assertIn("rtcp-%s.errors" % subtask_observation.id, subtask_observation.log_url) + self.assertIn("not available", subtask_pipeline.log_url) + self.assertEqual("", subtask_qa_plots.log_url) + if __name__ == "__main__": os.environ['TZ'] = 'UTC'