Skip to main content

Subskrypcje pull do katalogu EODATA na NSIS Cloud

Jak działają subskrypcje pull

Subskrypcja pull to sposób na „monitorowanie” katalogu EODATA bez konieczności jego ciągłego przeszukiwania.

Tworząc ją, określasz dwie rzeczy:

  • Zakres: które produkty mają być monitorowane (opcjonalnie za pomocą FilterParam).

  • Zdarzenia: które zmiany są istotne (created, modified, deleted lub ich kombinacja).

Usługa tworzy następnie dla twojego konta kolejkę po stronie serwera i umieszcza w niej pasujące powiadomienia w miarę ich pojawiania się.

O czym należy pamiętać:

  • Kolejka jest utrzymywana na platformie, więc jest dostępna z każdego klienta, którego używasz (przeglądarki, curl, Pythona itd.).

  • Read jest operacją nieniszczącą: wyświetla powiadomienia, ale ich nie usuwa.

  • API zwraca powiadomienia od najstarszego do najnowszego, maksymalnie 20 w jednym żądaniu odczytu.

  • Ack usuwa wybrane powiadomienie oraz wszystkie starsze powiadomienia. Zobacz Potwierdzanie powiadomień.

  • Kolejka ma maksymalny rozmiar (100000 powiadomień); jeśli się zapełni, najstarsze wpisy mogą zostać usunięte.

  • Treść powiadomień jest ograniczona czasowo: po 3 dniach platforma może usunąć pola takie jak value i ProductName, nawet jeśli nigdy nie wykonałeś ack.

Ack jest operacją niszczącą

Potwierdzenie powiadomienia (acking) usuwa je z kolejki, a także usuwa wszystkie powiadomienia starsze od niego.

Możesz myśleć o ack jak o przesuwaniu kursora: po potwierdzeniu powiadomienia wszystko przed nim znika z tej kolejki.

Ostrzeżenie

Jeśli wykonasz ack przed zapisaniem potrzebnych danych, możesz bezpowrotnie utracić informacje.

Bezpieczny sposób potwierdzania powiadomień

Ten sposób działania pozwala zachować przewidywalność:

  1. Wykonaj Read partii powiadomień (na przykład $top=20).

  2. Zapisz potrzebne dane (co najmniej: ProductId, AckId i NotificationDate; ProductName, jeśli występuje).

  3. Wykonaj Ack najnowszego powiadomienia z tej partii (ostatniego elementu na zwróconej liście).

Dzięki temu uzyskujesz czytelny „punkt kontrolny”, który pozwala kontynuować odczyt bez pomijania wiadomości.

Jak często wykonywać poll i ack?

Częstotliwość odpytywania zależy od przypadku użycia:

  • Jeśli używasz powiadomień jako wyzwalacza automatyzacji, odpytywanie powinno być regularne, a kolejka nie powinna rosnąć bez kontroli.

  • Jeśli potrzebujesz tylko okazjonalnej informacji o zmianach, możesz odpytywać rzadziej, ale unikaj długich przerw, aby nie ryzykować przepełnienia kolejki.

Wymagania wstępne

Nr 1 Konto

Potrzebujesz aktywnego konta NSIS Cloud https://tm.nsiscloud.polsa.gov.pl/login.

Nr 2 Możliwość wysyłania żądań HTTP

Aby wykonać kroki opisane w tym artykule, potrzebujesz metody wysyłania żądań GET, POST, PATCH i DELETE, wraz z nagłówkami oraz — tam, gdzie to wymagane — treścią JSON.

Możesz użyć dowolnego klienta, na przykład:

Nr 3 Wiedza, jak filtrować produkty

Jeśli chcesz otrzymywać powiadomienia tylko dla podzbioru produktów, musisz umieć tworzyć filtry.

Filtry używane w subskrypcjach mają taką samą strukturę jak filtry używane w Podręcznik API katalogu EOData na NSIS Cloud.

  • Dla powiadomień created i/lub modified filtry odpowiadają tym, których użyłbyś dla punktu końcowego Products.

  • Dla powiadomień deleted filtry odpowiadają tym, których użyłbyś dla punktu końcowego DeletedProducts.

Products i DeletedProducts nie udostępniają identycznych pól, więc filtr działający na jednym punkcie końcowym może nie być poprawny dla drugiego.

Nr 4 Wygenerowany token Keycloak

Subskrypcje pull wymagają uwierzytelnienia za pomocą tokenu Keycloak. Informacje o generowaniu tokenu znajdziesz w Użycie curl i wget do pobierania produktów EODATA z NSIS Cloud.

Tokeny wygasają, więc wygeneruj nowy, jeśli twoje żądania zaczną zwracać 401 lub 403.

Jeśli używasz Bash lub Pythona i masz włączone 2FA, możesz zautomatyzować generowanie tokenu:

Interfejs API subskrypcji pull

Gdy masz już ważny token Keycloak oraz jasno określoną definicję subskrypcji (typy zdarzeń i opcjonalnie FilterParam), możesz zarządzać subskrypcjami pull wyłącznie za pomocą API subskrypcji.

Szybka mapa API

  • Tworzenie subskrypcji: POST /Subscriptions

  • Lista subskrypcji: GET /Subscriptions/Info

  • Odczyt kolejki: GET /Subscriptions(<<subscription_id>>)/Read?$top=20

  • Ack: POST /Subscriptions(<<subscription_id>>)/Ack?$ackid=<<ack_id>>

  • Aktualizacja statusu: PATCH /Subscriptions(<<subscription_id>>)

  • Usuwanie subskrypcji: DELETE /Subscriptions(<<subscription_id>>) (alternatywnie: PATCH statusu na cancelled)

Co powinno zawierać żądanie HTTP?

Subskrypcje pull możesz tworzyć i nimi zarządzać, wysyłając żądania HTTP. Muszą one zawierać trzy wymagane części żądania HTTP:

  • Typ żądania (GET, POST, PATCH lub DELETE)

  • Nagłówki

  • URL

Niektóre żądania HTTP muszą również zawierać treść JSON.

Nagłówki

Żądania opisane w tym artykule powinny zawierać następujące nagłówki:

{
    "Content-Type": "application/json",
    "Authorization": "Bearer YOUR_ACCESS_TOKEN_HERE"
}

gdzie YOUR_ACCESS_TOKEN_HERE należy zastąpić tokenem Keycloak z Wymagania wstępnego nr 4. Ten token będzie używany do potwierdzenia twojej tożsamości.

Będziemy je nazywać obowiązkowymi nagłówkami i w ten sposób odnosić się do nich w całym artykule.

Ważne

Zawsze dołączaj obowiązkowe nagłówki!

Dane JSON w odpowiedziach

Niektóre żądania opisane w tym artykule zwracają dane JSON. Na potrzeby tego artykułu sformatowaliśmy je w wielu wierszach, aby były bardziej czytelne.

Opis jednostki subskrypcji pull

Nazwa właściwości Typ Opis
Id Guid Jest to uniwersalny unikalny identyfikator (UUID). Id jest lokalnym identyfikatorem instancji Subscription w obrębie Katalogu, przypisywanym w momencie utworzenia subskrypcji.

Przykład
9249dde5-4838-4a34-8925-bac8c1d53f09c
SubscriptionType Subscription Type enumeration Typ utworzonej subskrypcji:
  • pull
  • push

Wartość musi być wpisana małymi literami.

Przykład
pull
Status Subscription Status enumeration Dozwolone wartości statusu subskrypcji to:
  • running (subskrypcja jest aktywna i umieszcza powiadomienia w twojej kolejce po stronie serwera)
  • paused (subskrypcja jest nieaktywna i nie umieszcza nowych powiadomień w kolejce)
  • cancelled (ustawienie tego statusu usuwa subskrypcję i jej kolejkę)

Domyślną wartością pola Status, jeśli użytkownik go nie poda, jest running.

Działająca subskrypcja może zostać automatycznie ustawiona na paused po dłuższym okresie nieaktywności. Po jeszcze dłuższej nieaktywności może zostać ustawiona na cancelled i trwale usunięta.

Przykład
running
SubscriptionEvent Subscription Event enumeration Typy zdarzeń, które chcesz monitorować i dla których chcesz otrzymywać powiadomienia. Dozwolone wartości to:
  • created
  • modified
  • deleted
Możesz subskrybować jedno lub więcej zdarzeń, wysyłając tablicę, na przykład:
  • "SubscriptionEvent": ["created"]
  • "SubscriptionEvent": ["created","modified"]

Przykład
created
FilterParam String Parametry filtra subskrypcji.

Jeśli SubscriptionEvent zawiera created lub modified, to zapytanie odnosi się do parametru $filter= dowolnego zapytania typu Products?.

Jeśli SubscriptionEvent zawiera deleted, to zapytanie odnosi się do parametru $filter= dowolnego zapytania typu DeletedProducts.

Dostępne są te same parametry filtrowania, które opisano dla katalogu EOData — więcej szczegółów znajdziesz w Wymaganiu wstępnym nr 3.

Przykład
Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any (att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')
SubmissionDate DateTimeOffset Data i godzina, w której subskrypcja została odebrana przez Katalog. Czas jest w formacie ISO 8601 (UTC+0): YYYY-MMDDThh:mm:ss.sssZ

Przykład
2024-01-17T09:13:04.654Z
LastNotificationDate DateTimeOffset Data i godzina odpowiadająca ostatniemu momentowi, w którym powiadomienie z tej subskrypcji zostało potwierdzone przez ack. Czas jest w formacie ISO 8601 (UTC+0) YYYY-MMDDThh:mm:ss.sssZ

Przykład
2024-01-17T09:50:10.654Z
StageOrder Boolean Automatycznie zleca staging produktów spełniających warunki subskrypcji.

Używane tylko wtedy, gdy SubscriptionEvent zawiera created.

W zależności od aktualnego zachowania platformy ta opcja może być ignorowana, jeśli produkty są już od razu dostępne.

Przykład
true
Priority Int64 Priorytet zleceń wynikających z subskrypcji.

W zależności od aktualnego zachowania platformy ta wartość może być zarządzana systemowo i może być ignorowana.

Przykład
1

Ograniczenia subskrypcji

Twoje konto może mieć maksymalnie 2 (dwie) subskrypcje w statusie running jednocześnie. Mogą to być

Maksymalna łączna liczba subskrypcji powiązanych z kontem NSIS Cloud wynosi 10. Obejmuje to subskrypcje wszystkich typów:

  • running i paused

  • push i pull

Polityka nieaktywności:

Ważne

  • Subskrypcja w stanie running jest automatycznie ustawiana na paused po 60 dniach nieaktywności.

  • Po 365 dniach od ostatniego powiadomienia subskrypcja jest ustawiana na cancelled i trwale usuwana.

Jeśli polegasz na subskrypcji w automatyzacji, monitoruj ją i utrzymuj aktywny proces poll/ack.

Tworzenie subskrypcji pull

Podczas tworzenia subskrypcji musisz podać SubscriptionType.

Dozwolone wartości zapisane małymi literami to: pull i push. Ponieważ ten artykuł dotyczy subskrypcji pull, zawsze ustaw:

  • "SubscriptionType": "pull"

Typowa treść żądania tworzącego subskrypcję pull wygląda tak:

{
    "SubscriptionType": "pull",
    "StageOrder": true,
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created"
    ]
}

Ustaw własne wartości dla następujących kluczy w tej treści JSON:

SubscriptionType

Typ tworzonej subskrypcji. Ponieważ ten artykuł dotyczy subskrypcji pull, ustaw tutaj pull. Wartość musi być wpisana małymi literami.

SubscriptionEvent

Wartością tego klucza jest tablica zawierająca jeden lub więcej ciągów znaków. Za pomocą tych ciągów określasz, o jakich typach zdarzeń chcesz otrzymywać powiadomienia. Może zawierać następujące wartości:

  • created

  • modified

  • deleted

Możesz łączyć zdarzenia, wysyłając tablicę, na przykład: "SubscriptionEvent": ["created", "modified"].

FilterParam

Zmień wartość klucza FilterParam na zapytanie definiujące podzbiór produktów, o których chcesz otrzymywać powiadomienia. Więcej informacji znajdziesz w Wymaganiu wstępnym nr 3.

Aby uzyskać informacje

  • o produktach utworzonych i/lub zmodyfikowanych, użyj tego samego zapytania, jakie wysłałbyś do punktu końcowego Products

  • o produktach usuniętych, użyj tego samego zapytania, jakie wysłałbyś do punktu końcowego DeletedProducts

Możesz również otrzymywać powiadomienia o wybranych typach zdarzeń dotyczących wszystkich produktów z katalogu, a nie tylko ich podzbioru. W tym celu możesz

  • pozostawić wartość klucza FilterParam pustą, lub

  • w ogóle nie dołączać tego klucza do żądania.

Pominięta lub pusta wartość FilterParam oznacza subskrybuj zdarzenia wybranych typów dla wszystkich produktów.

Status

Jeśli ustawisz wartość tego klucza na running, utworzona subskrypcja natychmiast zacznie otrzymywać powiadomienia. Jeśli jednak chcesz utworzyć subskrypcję w stanie wstrzymania (nieaktywną) i aktywować ją później, ustaw tę wartość na paused.

Jeśli nie dodasz tego klucza do żądania, utworzona subskrypcja będzie miała status running.

Jeśli masz już 2 subskrypcje w statusie running i spróbujesz utworzyć kolejną subskrypcję z tym samym statusem, operacja zakończy się niepowodzeniem. Więcej informacji znajdziesz w sekcji Ograniczenia subskrypcji powyżej.

Aby rozwiązać ten problem, możesz

  • wstrzymać jedną z aktualnych subskrypcji, a następnie utworzyć nową subskrypcję, lub

  • utworzyć nową subskrypcję ze statusem paused.

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

To jest adres URL, na który należy wysłać to żądanie:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions

Kod odpowiedzi na to żądanie powinien mieć wartość 201 Created. Odpowiedź powinna zawierać dane JSON podobne do poniższych:

{
    "Id": "991c4730-cf6f-432a-9f6c-47be0230ff45",
    "SubscriptionType": "pull",
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "StageOrder": true,
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created"
    ],
    "SubmissionDate": "2024-03-13T09:39:49.404Z",
    "@odata.context": "$metadata#Subscriptions/$entity"
}

Typowe błędy i sposoby ich naprawy

  • 400 Bad Request — twój FilterParam jest niepoprawny (najczęściej przez literówkę).

    Najpierw zweryfikuj filtr, uruchamiając to samo zapytanie wobec API katalogu (na przykład testując je na punkcie końcowym Products lub DeletedProducts), a następnie popraw nazwę pola lub składnię.

  • 401 Unauthorized / 403 Forbidden — problem z uwierzytelnieniem.

    Zwykle oznacza to jedno z poniższych:

    • twój token Keycloak wygasł,

    • używasz tokenu z niewłaściwego realm/identity provider,

    • nagłówek Authorization: Bearer <token> jest nieobecny lub niepoprawnie sformatowany.

    Wygeneruj nowy token i potwierdź, że do żądania dołączone są obowiązkowe nagłówki.

  • 429 Too Many Requests / limit reached — zbyt wiele subskrypcji w stanie running.

    Możesz mieć maksymalnie 2 running subscriptions jednocześnie. Wstrzymaj jedną z działających subskrypcji (lub ją anuluj), a następnie ponów próbę utworzenia lub włączenia kolejnej subskrypcji.

  • 404 Not Found — subskrypcja nie istnieje.

    Zwykle dzieje się tak, gdy subskrypcja została ustawiona na cancelled (subskrypcje cancelled są usuwane) albo gdy używasz nieprawidłowego subscription_id.

  • Pusta kolejka (200 OK + [] ) — to jest oczekiwane zachowanie.

    Oznacza to, że obecnie nie ma powiadomień pasujących do twoich FilterParam i SubscriptionEvent. Poczekaj na nowe pasujące zdarzenia, a następnie ponownie odczytaj kolejkę.

Subskrypcje pull przy użyciu curl

Poniższe przykłady zawierają obowiązkowe nagłówki i pokazują najmniejsze możliwe działające żądania.

Informacja

Zastąp:

  • YOUR_ACCESS_TOKEN_HERE swoim tokenem Keycloak

  • catalogue.nsiscloud.polsa.gov.pl nazwą hosta twojego API

  • <<subscription_id>> oraz <<AckId>> rzeczywistymi wartościami

Tworzenie subskrypcji

curl -sS -X POST "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
  -d '{"SubscriptionType":"pull","Status":"running","SubscriptionEvent":["created"]}'

Lista subskrypcji

curl -sS -X GET "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"

Odczyt kolejki

curl -sS -X GET "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)/Read?$top=20" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"

Potwierdzenie powiadomienia

curl -sS -X POST "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)/Ack?$ackid=<<AckId>>" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"

Zmiana statusu

curl -sS -X PATCH "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE" \
  -d '{"Status":"paused"}'

Usuwanie subskrypcji

curl -sS -X DELETE "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN_HERE"

Subskrypcje pull przy użyciu kodu Python

Tworzenie subskrypcji pull przy użyciu Pythona

Oto kod w Pythonie, który wyśle żądanie z parametrami opisanymi powyżej:

import requests
import json

access_token = ""

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {access_token}",
}

body = {
    "SubscriptionType": "pull",
    "StageOrder": True,
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created"
    ]
}

url = "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions"

response = requests.post(url=url, headers=headers, json=body)

print(f"{response.status_code} {response.reason}\n")
try:
    print(json.dumps(json.loads(response.text), indent=4))
except Exception:
    print(response.text)

Ten skrypt:

  • Wysyła żądanie HTTP na wskazany adres URL.

  • Pobiera i wyświetla wynik, który składa się z:

    • Kodu odpowiedzi (np. 200) i powodu (np. OK).

    • Pustego wiersza (dla czytelności).

    • Treści odpowiedzi, jeśli występuje. (Jeśli jest to poprawny JSON, zostanie sformatowany tak, aby był bardziej czytelny.)

Zwróć uwagę, że w tym skrypcie treść żądania jest przekazywana do modułu requests przy użyciu parametru json.

Przypisz token Keycloak uzyskany zgodnie z Wymaganiem wstępnym nr 4 do zmiennej access_token.

Zapisz plik jako http_request_test_create.py

python3 http_request_test_create.py

Tworzenie subskrypcji śledzącej produkty utworzone i zmodyfikowane

W tym przykładzie utworzymy subskrypcję śledzącą zarówno produkty utworzone, jak i zmodyfikowane, które spełniają następujące kryteria (FilterParam):

Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')

Aby utworzyć tę subskrypcję, wyślij żądanie HTTP POST z następującą treścią:

{
    "SubscriptionType": "pull",
    "StageOrder": true,
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created", "modified"
    ]
}

na ten adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Powinieneś otrzymać kod odpowiedzi 201 Created oraz odpowiedź podobną do tej:

{
    "@odata.context": "$metadata#OData.CSC.Subscription",
    "Id": "3de3bcf4-4990-4e7f-8d89-67d80deb378c",
    "SubscriptionType": "pull",
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "Priority": 1,
    "StageOrder": false,
    "Status": "running",
    "SubmissionDate": "2025-03-18T17:46:01.709952Z",
    "SubscriptionEvent": [
        "created",
        "modified"
    ]
}

Próba utworzenia subskrypcji z niepoprawnym FilterParam

Załóżmy, że przez pomyłkę próbowaliśmy utworzyć subskrypcję z niepoprawnym zapytaniem, na przykład używając Colection/Name zamiast Collection/Name:

Colection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')

Treść żądania, które wyślemy, zawiera to niepoprawne zapytanie:

{
    "SubscriptionType": "pull",
    "StageOrder": true,
    "FilterParam": "Colection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created"
    ]
}

Tak jak wcześniej, wysyłamy to żądanie na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions

W odpowiedzi otrzymujemy kod 400 Bad Request oraz następujące dane JSON:

{
    "detail": "Your filter is incorrect. We suggest to verify it with catalogue API. Detailed error message -> Invalid field: Colection"
}

Ta odpowiedź będzie się różnić w zależności od rodzaju błędu popełnionego w zapytaniu.

Zasady bezpieczeństwa i zalecenia

  • Read jest operacją nieniszczącą.

  • Ack jest operacją niszczącą i prefiksową: usuwa wybrane powiadomienie oraz wszystkie starsze powiadomienia z kolejki. Zobacz Potwierdzanie powiadomień.

  • Zapisz powiadomienia (lub przynajmniej ProductId i AckId) przed wykonaniem ack.

  • Pobierz pełne metadane w ciągu 3 dni, jeśli ich potrzebujesz (lub od razu odczytaj produkt z punktu końcowego Products).

Wyświetlanie kolejki

Aby wyświetlić najstarsze powiadomienia w kolejce, wyślij żądanie GET na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)/Read?$top=20

Zastąp <<subscription_id>> identyfikatorem subskrypcji.

Parametr $top określa liczbę najstarszych powiadomień, które mają zostać wyświetlone, przy czym maksymalny limit wynosi 20. Jeśli nie zostanie podany, domyślnie przyjmowana jest wartość 1.

Jeśli liczba powiadomień w kolejce jest mniejsza lub równa wartości $top, otrzymasz wszystkie powiadomienia.

API zwraca powiadomienia od najstarszego do najnowszego.

Informacja

Częstotliwość odpytywania zależy od ciebie. W aktywnych procesach typowe jest odpytywanie co kilka minut do co godzinę. W przypadku subskrypcji o małej liczbie zdarzeń wystarczające może być odpytywanie raz dziennie — unikaj jednak długiej nieaktywności.

Przykładowe żądanie mogłoby być żądaniem GET wysłanym pod następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(991c4730-cf6f-432a-9f6c-47be0230ff45)/Read?$top=2

W zależności od okoliczności odpowiedź będzie się różnić.

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Subskrypcja została anulowana

Proces anulowania subskrypcji faktycznie ją usuwa. Dlatego jeśli spróbujesz wyświetlić kolejkę powiadomień takiej subskrypcji, otrzymasz kod 404 Not Found oraz dane JSON podobne do poniższych:

{
    "detail": {
        "message": "Subscription with id 991c4730-cf6f-432a-9f6c-47be0230ff45 not found.",
        "request_id": "aed89ead-b495-4f76-b6e9-51870973a44e"
    }
}

Subskrypcja jest w stanie Running lub Paused

Jeśli subskrypcja ma status running (aktywna) lub paused (nieaktywna), otrzymasz tablicę obiektów JSON, z których każdy reprezentuje jedno powiadomienie.

Każdy z tych obiektów zawiera informacje o

  • powiadomieniu,

  • produkcie, a także

  • subskrypcji.

Ważne

Pełna zawartość powiadomienia jest przechowywana w kolejce użytkownika przez trzy dni. Po tym czasie klucze value i ProductName są usuwane. Jeśli więc potrzebujesz pełnych metadanych produktu, pobierz je i zapisz w ciągu 3 dni (lub natychmiast odpytaj punkt końcowy Products przy użyciu ProductId).

Przykład 1

Poniższy plik JSON do pobrania

example-notification.json

zawiera poprawną odpowiedź dla SubscriptionEvent ustawionego na created (status 200 OK).

Pełna odpowiedź jest zbyt długa, aby publikować ją w całości w tym artykule.

../_images/pull-subscriptions-01_creodias1.png

Oto jak wygląda tablica value -> Attributes. Zaczyna się ona w wierszu 67 i kończy w 248, podczas gdy cały plik ma 293 wiersze; czerwony prostokąt po prawej stronie obrazu pokazuje pozycję tablicy Attributes proporcjonalnie do długości całego tekstu.

Przykład 2

Poniżej znajduje się przykład poprawnej odpowiedzi (status 200 OK) dla SubscriptionEvent ustawionego na modified. Pominięte zostały następujące wartości:

  • value -> GeoFootprint -> coordinates

  • value -> Attributes

  • value -> Locations

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "modified",
        "ProductId": "b6801a5d-0e66-43d7-afac-1280f0895bf1",
        "ProductName": "S1A_IW_SLC__1SDV_20241123T044906_20241123T044930_056677_06F42F_97B3.SAFE",
        "SubscriptionId": "991c4730-cf6f-432a-9f6c-47be0230ff45",
        "NotificationDate": "2025-02-10T08:30:48.905365Z",
        "AckId": "MTcxMDc1NjcwNjUzMi0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ==",
        "value": {
            "@odata.context": "$metadata#Products(Attributes(),Assets(),Locations())/$entity",
            "@odata.mediaContentType": "application/octet-stream",
            "Id": "b6801a5d-0e66-43d7-afac-1280f0895bf1",
            "Name": "S1A_IW_SLC__1SDV_20241123T044906_20241123T044930_056677_06F42F_97B3.SAFE",
            "ContentType": "application/octet-stream",
            "ContentLength": 8217756705,
            "OriginDate": "2024-11-23T06:28:41.550000Z",
            "Checksum": [
                {
                    "Value": "40fbe8ddd886f24a323906af1e442155",
                    "Algorithm": "MD5",
                    "ChecksumDate": "2024-11-23T06:37:33.947488Z"
                },
                {
                    "Value": "5c128944c135faefd8eb15b28f776541c1e4d0b21fa5064906b1882ca590527e",
                    "Algorithm": "BLAKE3",
                    "ChecksumDate": "2024-11-23T06:37:43.810075Z"
                }
            ],
            "ContentDate": {
                "Start": "2024-11-23T04:49:06.776458Z",
                "End": "2024-11-23T04:49:30.129633Z"
            },
            "Footprint": "geography'SRID=4326;POLYGON ((15.389621 5.429769, 15.680731 6.842505, 13.45454 7.296846, 13.16956 5.8881, 15.389621 5.429769))'",
            "GeoFootprint": {
                "type": "Polygon",
                "coordinates": []
            },
            "Attributes": [],
            "ModificationDate": "2025-02-10T08:30:48.665109Z",
            "PublicationDate": "2024-11-23T06:36:54.654519Z",
            "Online": true,
            "EvictionDate": "2025-03-12T08:28:16.409489Z",
            "S3Path": "/eodata/Sentinel-1/SAR/IW_SLC__1S/2024/11/23/S1A_IW_SLC__1SDV_20241123T044906_20241123T044930_056677_06F42F_97B3.SAFE",
            "Assets": [
                {
                    "Type": "QUICKLOOK",
                    "Id": "b43f60cb-3869-4c1d-b1e5-336e0d057f43",
                    "DownloadLink": "https://datahub.creodias.eu/odata/v1/Assets(f4cfe4c9-5b56-47c2-87ce-05b090c7a4ba)/$value",
                    "S3Path": "/eodata/Sentinel-1/SAR/IW_SLC__1S/2024/03/13/S1A_IW_SLC__1SDV_20240313T054626_20240313T054653_052959_066921_3759.SAFE"
                }
            ],
            "Locations": []
        }
    }
]

Przykład 3

To jest przykład poprawnej odpowiedzi (status 200 OK) dla SubscriptionEvent ustawionego na deleted.

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "deleted",
        "ProductId": "232d796a-0552-4679-a1ed-b8cd3d002db2",
        "ProductName": "S1A_IW_SLC__1SDV_20241111T044907_20241111T044931_056502_06ED2E_7F0A",
        "SubscriptionId": "991c4730-cf6f-432a-9f6c-47be0230ff45",
        "NotificationDate": "2025-02-10T08:30:04.127132Z",
        "AckId": "MTcxMDc1NjcwNjUzMi0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ==",
        "value": {
            "@odata.context": "$metadata#DeletedProducts(Attributes())/$entity",
            "@odata.mediaContentType": "application/image-tiff",
            "Id": "232d796a-0552-4679-a1ed-b8cd3d002db2",
            "Name": "S1A_IW_SLC__1SDV_20241111T044907_20241111T044931_056502_06ED2E_7F0A",
            "ContentType": "application/image-tiff",
            "ContentLength": 999999,
            "OriginDate": "2025-02-10T08:28:16.409494Z",
            "Checksum": [
                {
                    "Value": "1efb9cf89aa30086e114705c20831606",
                    "Algorithm": "MD5",
                    "ChecksumDate": "2025-02-10T08:28:16.409494Z"
                },
                {
                    "Value": "7a8e7280a1b37f14ecf6cf9216ec3f9e3824e5a7098d266168b8ce6b32598551",
                    "Algorithm": "BLAKE3",
                    "ChecksumDate": "2025-02-10T08:28:16.409494Z"
                }
            ],
            "Footprint": "geography'SRID=4326;POLYGON ((14.412463 5.424546, 15.703652 6.837446, 13.453771 7.296696, 13.168763 5.887819, 14.412463 5.424546))'",
            "GeoFootprint": {
                "type": "Polygon",
                "coordinates": []
                },
                "ContentDate": {
                    "Start": "2025-02-09T08:28:16.409468Z",
                    "End": "2025-02-10T08:28:16.409494Z"
                },
                "Attributes": [],
                "DeletionDate": "2025-02-10T08:30:03.907283Z",
                "DeletionCause": "Corrupted product"
            }
        }
    }
]

Przykład 4

Poniżej przykład poprawnej odpowiedzi (status 200 OK) dla powiadomień, które mają 3 dni lub więcej:

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "d2ff986b-9454-43d6-95e0-1a0ae27019d7",
        "SubscriptionId": "991c4730-cf6f-432a-9f6c-47be0230ff45",
        "NotificationDate": "2024-03-13T13:39:59.000Z",
        "AckId": "MTcxMDc1NjcwNjUzMi0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ=="
    },
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "33ad5694-9208-4001-ae4f-6d7cd0579ce0",
        "SubscriptionId": "991c4730-cf6f-432a-9f6c-47be0230ff45",
        "NotificationDate": "2024-03-13T13:39:59.000Z",
        "AckId": "MTcxMDc1NjcwNjY2NC0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ=="
    }
]

Przykład 5

Jeśli nie masz żadnych powiadomień w kolejce, powinieneś otrzymać status 200 OK i pustą tablicę:

[]

Objaśnienie kluczy w powiadomieniu

Nazwa właściwości Typ Opis
ProductId Guid Jest to uniwersalny unikalny identyfikator (UUID) produktu, którego dotyczy powiadomienie.

Przykład
8d654e59-d7b6-4a53-b086-c9de764e506b
ProductName String Jest to nazwa produktu, którego dotyczy powiadomienie, przypisana w Katalogu.

Wartość ProductName może być długa i zwykle nie mieści się w jednej komórce tabeli; konkretny przykład znajduje się pod tabelą.
SubscriptionId Guid Jest to uniwersalny unikalny identyfikator (UUID). Id jest lokalnym identyfikatorem instancji Subscription w obrębie Katalogu, przypisywanym w momencie utworzenia subskrypcji.

Przykład
991c4730-cf6f-432a-9f6c-47be0230ff4
SubscriptionEvent Subscription Event enumeration Zdarzenie subskrypcji, które jest monitorowane i dla którego dostarczane jest powiadomienie:
  • created
  • modified
  • deleted
Przykład
created
NotificationDate DateTimeOffset Data i godzina wygenerowania powiadomienia. Czas jest w formacie ISO 8601 (UTC+0): YYYY-MM-DDThh:mm:ss.sssZ

Przykład
2024-01-29T10:59:08.698Z
AckId String Acknowledge Id przypisany do każdego powiadomienia o produkcie. Wymagany do potwierdzania wiadomości z kolejki klienta.

Ponieważ AckId jest długi, jego przykład podano pod tą tabelą.
value JSON object Zawiera standardową odpowiedź API katalogu ze wszystkimi metadanymi i szczegółami dotyczącymi zawartości produktu.

Przykład ProductName

S2A_MSIL2A_20240129T062121_N0510_R034_T44VMN_20240129T093752.SAFE

Przykład AckId

MTcxMDc1NjcwNjUzMi0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ==

Potwierdzanie powiadomień

Ack (acknowledge) to operacja, która usuwa powiadomienia z kolejki subskrypcji pull.

Ack jest operacją niszczącą i prefiksową: usuwa wybrane powiadomienie oraz wszystkie starsze powiadomienia z kolejki.

  • Gdy wykonasz ack jednego powiadomienia, API usuwa to powiadomienie oraz każde powiadomienie starsze od niego.

  • Nowsze powiadomienia (z późniejszym NotificationDate) pozostają w kolejce.

Z tego względu należy traktować ack jak kursor, który przesuwasz do przodu w czasie.

Bezpieczny workflow ack (zalecany)

  1. Wykonaj Read najstarszych powiadomień (na przykład $top=20).

  2. Zapisz potrzebne informacje z odpowiedzi (co najmniej: ProductId, AckId, NotificationDate i ProductName, jeśli występuje).

  3. Wykonaj Ack najnowszego powiadomienia z tej odpowiedzi (czyli ostatniego elementu na zwróconej liście).

Pozwala to przesuwać kursor bez pomijania powiadomień i zapobiega utracie metadanych przed ich zapisaniem.

Adres URL żądania Ack

Aby potwierdzić powiadomienie, wyślij żądanie POST na następujący punkt końcowy i podaj:

  • <<subscription_id>> — identyfikator subskrypcji

  • <<AckId>> — wartość AckId powiadomienia, które chcesz wykorzystać jako pozycję kursora

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)/Ack?$ackid=<<AckId>>

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Na przykład może to być żądanie POST wysłane na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(991c4730-cf6f-432a-9f6c-47be0230ff45)/Ack?$ackid=MTcxMDc1NjcwNjY2NC0wOjk5MWM0NzMwLWNmNmYtNDMyYS05ZjZjLTQ3YmUwMjMwZmY0NQ==

Powinieneś otrzymać odpowiedź 200 OK. Odpowiedź powinna również zawierać dane JSON podobne do tych:

{
     "@odata.context": "$metadata#Notification/$entity",
     "AckMessagesNum": 2,
     "CurrentQueueLength": 2115,
     "MaxQueueLength": 100000
}

które zawierają następujące informacje:

Klucz Typ Opis
AckMessagesNum Int64 Liczba powiadomień, które zostały potwierdzone przez twoje żądanie.
CurrentQueueLength Int64 Liczba powiadomień aktualnie znajdujących się w twojej kolejce.
MaxQueueLength Int64 Maksymalna liczba powiadomień, które mogą być przechowywane w twojej kolejce

Jeśli subskrypcja została wcześniej ustawiona na cancelled, powinieneś otrzymać kod 404 Not Found oraz dane JSON podobne do poniższych:

{
    "detail": {
        "message": "Subscription with id 991c4730-cf6f-432a-9f6c-47be0230ff4 not found.",
        "request_id": "ae19864a-5bda-4893-9f02-a62eba95fd7a"
    }
}

Używanie ack do odczytu dalszych powiadomień

Żądanie służące do odczytu kolejki może zwrócić maksymalnie 20 najstarszych powiadomień. Maksymalna liczba powiadomień, które mogą znajdować się w kolejce, wynosi 100000. Z tego powodu samo to żądanie może być niewystarczające do pobrania wszystkich powiadomień.

Ack jest operacją niszczącą i prefiksową: usuwa wybrane powiadomienie oraz wszystkie starsze powiadomienia z kolejki. Zobacz Potwierdzanie powiadomień.

  • Wyświetl bieżącą listę powiadomień — ustaw parametr $top na 20.

  • W razie potrzeby zapisz te powiadomienia.

  • Wykonaj Ack ostatniego z nich.

Ponownie sprawdź bieżącą listę powiadomień — powinna teraz zawierać powiadomienia, które pojawiły się po tym, które zostało potwierdzone poleceniem ack. Jeśli w kolejce było więcej niż 20 powiadomień, powinieneś teraz zobaczyć te, których wcześniej nie było widać.

Ponownie zapisz powiadomienia, jeśli są potrzebne, i wykonaj ack ostatniego z nich.

Powtarzaj tę czynność, aż kolejka będzie pusta.

Zmiana statusu subskrypcji pull

W przypadku subskrypcji pull możesz zmienić jedynie jej status.

Subskrypcja może mieć jeden z następujących statusów:

  • running - subskrypcja otrzymuje nowe powiadomienia

  • paused - subskrypcja tymczasowo nie otrzymuje nowych powiadomień

  • cancelled - ustawienie tego statusu zawiesza i usuwa subskrypcję

Aby zmienić status subskrypcji, wyślij żądanie HTTP PATCH z następującą treścią (zastąp <<new_status>> statusem, który chcesz ustawić dla subskrypcji):

{
    "Status": "<<new_status>>"
}

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Wyślij to żądanie na poniższy adres URL (zastąp <<subscription_id>> identyfikatorem subskrypcji, którą chcesz edytować).

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)

Powinieneś otrzymać odpowiedź zawierającą zaktualizowane informacje o subskrypcji wraz z kodem 200 OK. Wyjątkiem jest ustawienie statusu na cancelled — w takim przypadku powinieneś otrzymać kod 204 No Content.

Nieniszcząca zmiana statusu subskrypcji pull

Jeśli identyfikator twojej subskrypcji to 7ca682c3-7b21-4e9b-952e-874798181340 i chcesz ustawić jej status na paused, użyj następującej treści żądania PATCH:

{
    "Status": "paused"
}

To jest adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(7ca682c3-7b21-4e9b-952e-874798181340)

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Ustawienie statusu subskrypcji na cancelled

Załóżmy, że chcemy usunąć subskrypcję z powyższego przykładu, ustawiając jej status na cancelled.

W tym celu użyjemy następującego obiektu JSON jako treści żądania HTTP PATCH:

{
   "Status": "cancelled"
}

Adres URL pozostaje taki sam:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(7ca682c3-7b21-4e9b-952e-874798181340)

Otrzymujemy kod 204 No Content. Subskrypcja powinna teraz zostać usunięta.

Wyświetlanie bieżących subskrypcji

Aby wyświetlić listę wszystkich subskrypcji aktualnie powiązanych z twoim kontem, wyślij żądanie GET na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Status odpowiedzi powinien mieć wartość 200 OK. Powinieneś otrzymać listę bieżących subskrypcji. Obejmuje ona:

  • subskrypcje pull, a także

  • subskrypcje push.

Oto przykład:

[
  {
    "Id": "0a449cc9-d6d4-4db7-af6a-d10105bedd2b",
    "SubscriptionType": "push",
    "FilterParam": "Collection/Name eq 'SENTINEL-2' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'S2MSI2A')",
    "StageOrder": false,
    "Priority": 1,
    "Status": "paused",
    "NotificationEndpoint": "https://example.com/notification",
    "SubscriptionEvent": [
      "created"
    ],
    "SubmissionDate": "2025-04-10T13:11:11.203179Z",
    "@odata.context": "$metadata#OData.CSC.Subscription"
  },
  {
    "Id": "e9d0b04b-cb58-4963-814c-e6d81be4219e",
    "SubscriptionType": "pull",
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S')",
    "StageOrder": false,
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
      "created",
      "modified"
    ],
    "SubmissionDate": "2025-04-10T13:13:51.988546Z",
    "@odata.context": "$metadata#OData.CSC.Subscription"
  }
]

W tym przykładzie widzimy, że użytkownik ma dwie subskrypcje:

  • subskrypcję push śledzącą produkty created

  • subskrypcję pull śledzącą zarówno produkty created, jak i modified

Subskrypcja push, w przeciwieństwie do subskrypcji pull, zawiera klucz NotificationEndpoint, który pokazuje adres URL punktu końcowego, do którego mają być dostarczane powiadomienia. Więcej informacji o tym typie subskrypcji znajdziesz tutaj: Subskrypcje push do katalogu EODATA na NSIS Cloud

Jeśli obecnie nie masz żadnych subskrypcji, zapytanie powinno zwrócić pustą tablicę:

[]

Wyświetlanie subskrypcji przy użyciu Pythona

Oto kompletny kod Pythona służący do wyświetlania subskrypcji:

import requests
import json

access_token = ""

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {access_token}",
}

url = "https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info"

response = requests.get(url=url, headers=headers)

print(f"{response.status_code} {response.reason}\n")
try:
    print(json.dumps(json.loads(response.text), indent=4))
except Exception as e:
    print(e)
    print(response.text)

Ten skrypt:

  • Wysyła żądanie HTTP na wskazany adres URL.

  • Pobiera i wyświetla wynik, który składa się z:

    • Kodu odpowiedzi (np. 200) i powodu (np. OK).

    • Pustego wiersza (dla czytelności).

    • Treści odpowiedzi, jeśli występuje. (Jeśli jest to poprawny JSON, zostanie sformatowany tak, aby był bardziej czytelny.)

Przypisz token Keycloak uzyskany zgodnie z Wymaganiem wstępnym nr 4 do zmiennej access_token.

Zapisz plik jako http_request_test_list.py

python3 http_request_test_list.py

Usuwanie subskrypcji

Metoda 1: Wysłanie żądania HTTP DELETE

Wyślij żądanie DELETE na poniższy adres URL. Zastąp w nim <<subscription_id>> identyfikatorem subskrypcji, którą chcesz usunąć.

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(<<subscription_id>>)

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Powinieneś otrzymać status odpowiedzi: 204 No Content.

Lista subskrypcji (zgodnie z opisem w sekcji Wyświetlanie bieżących subskrypcji tego artykułu) powinna pokazać, że ta subskrypcja już nie istnieje.

Metoda 2: Zmiana statusu subskrypcji na cancelled

Ten proces opisano w sekcji Zmiana statusu subskrypcji pull tego artykułu.

Subskrypcja pull - przykładowy workflow

W tej sekcji omówimy przykładowy workflow z wykorzystaniem subskrypcji pull.

Tworzenie subskrypcji

Zacznijmy od wyświetlenia subskrypcji powiązanych z naszym kontem.

Robimy to, wysyłając żądanie GET na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

To żądanie zwraca kod 200 OK oraz pustą tablicę. Oznacza to, że nasze konto nie ma jeszcze żadnych subskrypcji:

[]

Teraz tworzymy naszą pierwszą subskrypcję. Będzie ona śledzić produkty dodawane do katalogu. Użyjemy następującego filtra:

Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S') and Online eq true and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value gt 0) and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value lt 100000) and OData.CSC.Intersects(area=geography'SRID=4326;POLYGON((-180.0000 90.0000,180.00 90.00,180 -90,-180.0 -90.0,-180.0000 90.0000))')

To zapytanie śledzi produkty, które:

  • Należą do kolekcji SENTINEL-1

  • Mają następujący typ produktu: IW_SLC__1S

  • Mają parametr Online ustawiony na true

  • Mają parametr orbitNumber większy niż 0

  • Mają parametr orbitNumber mniejszy niż 100000

  • Przecinają następujący wielokąt: POLYGON((-180.0000 90.0000,180.00 90.00,180 -90,-180.0 -90.0,-180.0000 90.0000))

To jest treść żądania, które wysyłamy, aby osiągnąć ten cel:

{
    "SubscriptionType": "pull",
    "StageOrder": true,
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S') and Online eq true and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value gt 0) and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value lt 100000) and OData.CSC.Intersects(area=geography'SRID=4326;POLYGON((-180.0000 90.0000,180.00 90.00,180 -90,-180.0 -90.0,-180.0000 90.0000))')",
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
        "created"
    ]
}

Ta treść zawiera informacje o naszej subskrypcji, takie jak:

FilterParam

Zapytanie do katalogu filtrujące produkty.

Status

Status tworzonej subskrypcji (chcemy, aby subskrypcja zaczęła działać natychmiast po utworzeniu, więc ustawiamy running).

SubscriptionEvent

Typ zmian w Katalogu, które chcesz śledzić. Więcej informacji znajdziesz w tabeli w sekcji Opis jednostki subskrypcji pull tego artykułu. W tym przykładzie wybraliśmy created, ponieważ chcemy otrzymywać powiadomienia o produktach tworzonych.

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Wysyłamy to żądanie na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions

Po wysłaniu tego żądania otrzymujemy kod 201 Created oraz następujący obiekt JSON:

{
    "Id": "32ee6df9-3008-4279-92e6-200828e532d1",
    "SubscriptionType": "pull",
    "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S') and Online eq true and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value gt 0) and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value lt 100000) and OData.CSC.Intersects(area=geography'SRID=4326;POLYGON((-180.0000 90.0000,180.00 90.00,180 -90,-180.0 -90.0,-180.0000 90.0000))')",
    "StageOrder": false,
    "Priority": 1,
    "Status": "running",
    "SubscriptionEvent": [
      "created"
    ],
    "SubmissionDate": "2025-03-26T12:19:03.492271Z",
    "@odata.context": "$metadata#OData.CSC.Subscription"
}

Ten obiekt JSON potwierdza szczegóły naszej nowej subskrypcji, takie jak zapytanie użyte do filtrowania produktów i typ śledzonych zdarzeń.

Do dalszej pracy z tą subskrypcją będziemy później potrzebować jej identyfikatora, który w tym przykładzie ma wartość 32ee6df9-3008-4279-92e6-200828e532d1.

Wynik ten zawiera także potwierdzenie, że Status naszej subskrypcji ma wartość running, co oznacza, że powinna już być gotowa do odbierania powiadomień.

Aby dodatkowo sprawdzić, czy subskrypcja została utworzona, ponownie wyświetlamy listę subskrypcji powiązanych z naszym kontem, wysyłając następujące żądanie GET na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Kod odpowiedzi ma ponownie wartość 200 OK.

Otrzymane dane to tablica z obiektami, z których każdy reprezentuje jedną subskrypcję.

[
    {
        "Id": "32ee6df9-3008-4279-92e6-200828e532d1",
        "SubscriptionType": "pull",
        "FilterParam": "Collection/Name eq 'SENTINEL-1' and Attributes/OData.CSC.StringAttribute/any(att:att/Name eq 'productType' and att/OData.CSC.StringAttribute/Value eq 'IW_SLC__1S') and Online eq true and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value gt 0) and Attributes/OData.CSC.IntegerAttribute/any(att:att/Name eq 'orbitNumber' and att/OData.CSC.IntegerAttribute/Value lt 100000) and OData.CSC.Intersects(area=geography'SRID=4326;POLYGON((-180.0000 90.0000,180.00 90.00,180 -90,-180.0 -90.0,-180.0000 90.0000))')",
        "StageOrder": false,
        "Priority": 1,
        "Status": "running",
        "SubscriptionEvent": [
            "created"
        ],
        "SubmissionDate": "2025-03-26T12:19:03.492271Z",
        "@odata.context": "$metadata#OData.CSC.Subscription"
    }
]

Ponieważ mamy teraz jedną subskrypcję, występuje jeden obiekt. Zawiera on szczegółowe informacje o naszej subskrypcji, identyczne jak dane zwrócone podczas jej utworzenia.

Jeśli kiedykolwiek zapomnimy czegoś o naszej subskrypcji (na przykład jej ID lub użytego zapytania), możemy wykonać to polecenie, aby ponownie uzyskać te informacje.

Oczywiście, chociaż możesz mieć tylko jedną aktywną subskrypcję, możesz mieć wiele subskrypcji wstrzymanych. To żądanie powinno wyświetlić je wszystkie, jeśli istnieją.

Potwierdzanie jednego powiadomienia

Sprawdźmy teraz kolejkę powiadomień powiązaną z tą subskrypcją. W tym celu wysyłamy żądanie GET na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Read?$top=20

Ten adres URL zawiera takie dane jak:

  • ID naszej subskrypcji (32ee6df9-3008-4279-92e6-200828e532d1)

  • maksymalna liczba powiadomień, które chcemy zobaczyć (20, tej wartości nie można zwiększyć)

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

To żądanie zwraca kod 200 OK oraz pustą tablicę jako dane:

[]

Oznacza to, że w naszej kolejce nie ma jeszcze żadnych powiadomień.

Czekamy jakiś czas, aż pojawi się pierwsze powiadomienie.

Następnie wysyłamy to samo żądanie HTTP ponownie. Tym razem również otrzymujemy kod 200 OK. Tablica zwrócona w odpowiedzi zawiera teraz jedno powiadomienie.

(Wartość klucza JSON value została przycięta — pozostawiona pusta — dla czytelności.)

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "f2587c70-1104-4e92-960b-640495331d2e",
        "ProductName": "S1A_IW_SLC__1SDV_20250326T101553_20250326T101621_058474_073BCB_A673.SAFE",
        "SubscriptionId": "32ee6df9-3008-4279-92e6-200828e532d1",
        "NotificationDate": "2025-03-26T12:20:43.000000Z",
        "AckId": "MTc0Mjk5MTY0Mzg5MC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==",
        "value": {
        }
    }
]

To powiadomienie ogłasza publikację produktu o nazwie:

S1A_IW_SLC__1SDV_20250326T101553_20250326T101621_058474_073BCB_A673.SAFE

Do dalszego wykorzystania (np. przetwarzania) zapisujemy informacje z tego powiadomienia, które nas interesują.

Gdy już to zrobimy, to powiadomienie nie jest nam potrzebne i chcemy je usunąć przez acking (potwierdzenie).

W tym celu potrzebujemy AckId tego powiadomienia, który w tym przykładzie ma wartość:

MTc0Mjk5MTY0Mzg5MC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

Aby wykonać Ack tego powiadomienia, wysyłamy żądanie POST na poniższy adres URL. W tym adresie URL używamy identyfikatora subskrypcji oraz tego AckId:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Ack?$ackid=MTc0Mjk5MTY0Mzg5MC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Zwracany kod odpowiedzi ma wartość 200 OK. Dane JSON pobrane przez to żądanie zawierają informacje o wynikach tej operacji:

{
    "@odata.context": "$metadata#Notification/$entity",
    "AckMessagesNum": 1,
    "CurrentQueueLength": 0,
    "MaxQueueLength": 100000
}

Z tego obiektu JSON dowiadujemy się, że

  • to Ack usunęło 1 powiadomienie (AckMessagesNum)

  • w kolejce pozostało 0 powiadomień (CurrentQueueLength)

Zawiera on także przypomnienie, że maksymalna liczba powiadomień przechowywanych w kolejce wynosi 100000 (wartość klucza MaxQueueLength).

Ponownie sprawdzamy bieżącą kolejkę powiadomień, wysyłając żądanie GET na poniższy adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Read?$top=20

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Żądanie zwraca kod 200 OK oraz pustą tablicę JSON jako dane:

[]

Wcześniej mieliśmy jedno powiadomienie. Usunęliśmy je przez wykonanie ack, więc teraz lista powiadomień jest pusta.

Potwierdzanie wielu powiadomień jednocześnie

Czekamy teraz jakiś czas, aż nasza kolejka zostanie zapełniona większą liczbą powiadomień.

Następnie sprawdzamy kolejkę powiadomień, wysyłając żądanie GET na ten sam adres URL co wcześniej:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Read?$top=20

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Otrzymujemy kod 200 OK oraz trzy powiadomienia. Zwróć uwagę, że dla czytelności wartość klucza value została przycięta.

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "ea5e8c98-a3bd-4cab-86c9-7ea48f21f356",
        "ProductName": "S1A_IW_SLC__1SDV_20250326T101258_20250326T101325_058474_073BCA_A4FE.SAFE",
        "SubscriptionId": "32ee6df9-3008-4279-92e6-200828e532d1",
        "NotificationDate": "2025-03-26T12:21:27.000000Z",
        "AckId": "MTc0Mjk5MTY4NzE1MS0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==",
        "value": {
        }
    },
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "9ab913a7-0445-4466-9825-90a36c9541e7",
        "ProductName": "S1A_IW_SLC__1SDV_20250326T101323_20250326T101350_058474_073BCA_EAEE.SAFE",
        "SubscriptionId": "32ee6df9-3008-4279-92e6-200828e532d1",
        "NotificationDate": "2025-03-26T12:21:41.000000Z",
        "AckId": "MTc0Mjk5MTcwMTQ5OC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==",
        "value": {
        }
    },
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "a05f5274-cad5-451c-b1d3-b86017251c57",
        "ProductName": "S1A_IW_SLC__1SDV_20250326T101348_20250326T101415_058474_073BCA_6916.SAFE",
        "SubscriptionId": "32ee6df9-3008-4279-92e6-200828e532d1",
        "NotificationDate": "2025-03-26T12:21:59.000000Z",
        "AckId": "MTc0Mjk5MTcxOTU3MS0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==",
        "value": {
        }
    }
]

Każde z tych trzech powiadomień reprezentuje jeden produkt. Są one uporządkowane chronologicznie, od najwcześniejszego znacznika czasu otrzymania powiadomienia (NotificationDate) do najpóźniejszego.

Załóżmy, że chcemy wykonać Ack drugiego powiadomienia, które zostało wysłane o następującym czasie: 2025-03-26T12:21:41.000000Z

Jego AckId ma wartość:

MTc0Mjk5MTcwMTQ5OC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

Aby wykonać tę operację, wysyłamy żądanie POST na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Ack?$ackid=MTc0Mjk5MTcwMTQ5OC0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Żądanie zwraca kod 200 OK oraz dane JSON podsumowujące, co stało się w wyniku tego żądania:

{
    "@odata.context": "$metadata#Notification/$entity",
    "AckMessagesNum": 2,
    "CurrentQueueLength": 1,
    "MaxQueueLength": 100000
}

Wykonanie Ack na powiadomieniu usuwa zarówno to powiadomienie, jak i wszystkie powiadomienia, które pojawiły się przed nim. W tym przypadku istniało jedno starsze powiadomienie niż to, które zostało potwierdzone (Ack), więc oba zostały usunięte. Łącznie usunięto dwa powiadomienia — właśnie to pokazuje wartość klucza AckMessagesNum.

W naszej kolejce znajdowało się również trzecie powiadomienie, które przetrwało ten proces, ponieważ pojawiło się chronologicznie później niż powiadomienie, które zostało potwierdzone (Ack). To powiadomienie jest liczone w wartości klucza CurrentQueueLength.

Możemy wyświetlić to pozostałe powiadomienie, ponownie sprawdzając kolejkę powiadomień. Wysyłamy żądanie GET na ten adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Read?$top=20

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Otrzymujemy kod 200 OK i tablicę z naszym jednym pozostałym powiadomieniem (ponownie, dla czytelności, wartość klucza value została przycięta):

[
    {
        "@odata.context": "$metadata#Notification/$entity",
        "SubscriptionEvent": "created",
        "ProductId": "a05f5274-cad5-451c-b1d3-b86017251c57",
        "ProductName": "S1A_IW_SLC__1SDV_20250326T101348_20250326T101415_058474_073BCA_6916.SAFE",
        "SubscriptionId": "32ee6df9-3008-4279-92e6-200828e532d1",
        "NotificationDate": "2025-03-26T12:21:59.000000Z",
        "AckId": "MTc0Mjk5MTcxOTU3MS0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==",
        "value": {
        }
    }
]

Jego AckId ma wartość:

MTc0Mjk5MTcxOTU3MS0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

Aby również wykonać ack tego powiadomienia, wysyłamy żądanie POST na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Ack?$ackid=MTc0Mjk5MTcxOTU3MS0wOjMyZWU2ZGY5LTMwMDgtNDI3OS05MmU2LTIwMDgyOGU1MzJkMQ==

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Żądanie ponownie zwraca kod 200 OK oraz wyniki tej operacji w postaci danych JSON:

{
    "@odata.context": "$metadata#Notification/$entity",
    "AckMessagesNum": 1,
    "CurrentQueueLength": 0,
    "MaxQueueLength": 100000
}

Z tego obiektu JSON możemy się dowiedzieć, że było to ostatnie powiadomienie w naszej kolejce. Aby potwierdzić, że kolejka jest pusta, ponownie ją sprawdzamy. Wysyłamy żądanie GET na ten adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)/Read?$top=20

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Zwracany jest kod 200 OK wraz z pustą odpowiedzią JSON:

[]

Ponieważ usunęliśmy jedyne powiadomienie z tej kolejki, kolejka jest rzeczywiście pusta.

Usuwanie subskrypcji

Załóżmy teraz, że po pewnym czasie nie potrzebujemy już naszej subskrypcji i chcemy ją usunąć.

Aby to zrobić, wysyłamy żądanie DELETE na następujący adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions(32ee6df9-3008-4279-92e6-200828e532d1)

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Zwracany jest kod 204 No Content (bez danych JSON).

Aby sprawdzić aktualną listę subskrypcji, wysyłamy żądanie GET na ten adres URL:

https://catalogue.nsiscloud.polsa.gov.pl/odata/v1/Subscriptions/Info

PRZYPOMNIENIE: Dołącz obowiązkowe nagłówki.

Otrzymujemy kod 200 OK oraz pustą tablicę:

[]

Potwierdza to, że na naszym koncie nie pozostały żadne subskrypcje.

Co można zrobić dalej?

Po otrzymaniu powiadomienia możesz chcieć pobrać ten produkt. Sposoby osiągnięcia tego celu obejmują:

Poniższe artykuły opisują niektóre z dostępnych sposobów przetwarzania EODATA: