Abilitare le notifiche relative al ciclo di vita degli elementi

Importante

A partire dalla fine di aprile 2026, Fabric inizierà a inviare notifiche di eliminazione temporanea e ripristino agli endpoint del carico di lavoro. Se il OnDelete è abilitato nella descrizione del carico di lavoro, assicurati che gli endpoint siano pronti per gestire questi nuovi eventi del ciclo di vita.

Le notifiche del ciclo di vita degli elementi forniscono ai creatori di carichi di lavoro la possibilità di ricevere notifiche sugli eventi del ciclo di vita per gli elementi personalizzati, anche quando l'esperienza utente del carico di lavoro non è coinvolta. Questa impostazione consente all'elemento di rispondere alle operazioni degli elementi indipendentemente dalla modalità di avvio.

Informazioni generali

Le notifiche relative al ciclo di vita degli elementi sono essenziali per gli scenari in cui vengono creati, aggiornati o eliminati elementi all'esterno dell'interfaccia utente del carico di lavoro. Questo servizio invia una notifica al carico di lavoro ogni volta che si verifica un evento del ciclo di vita degli elementi, consentendo di:

  • Configurare o smantellare l'infrastruttura per gli elementi nuovi o rimossi
  • Convalidare licenze o quote prima di consentire le operazioni
  • Sincronizzare lo stato con i sistemi esterni
  • Implementare la logica di business personalizzata per le operazioni sugli elementi
  • Gestire scenari di eliminazione temporanea con logica di pulizia personalizzata

Quando vengono attivate le notifiche relative al ciclo di vita

Le notifiche del ciclo di vita vengono attivate per le operazioni sugli elementi provenienti da più origini:

API pubbliche

Gli elementi possono essere creati, aggiornati o eliminati tramite le API REST pubbliche di Fabric senza alcuna interazione con l'interfaccia utente del carico di lavoro. Per esempio:

  • Script di automazione con l'API Items
  • Integrazione di applicazioni di terze parti con Fabric
  • Operazioni amministrative eseguite a livello di codice

Pipeline di CI/CD

Gli elementi vengono distribuiti tramite le funzionalità CI/CD di <>Fabric come parte delle pipeline di distribuzione automatizzate. In questo scenario:

  • Gli elementi vengono creati o aggiornati come parte dei flussi di lavoro di integrazione Git
  • Le pipeline di distribuzione promuovono gli elementi attraverso gli ambienti
  • Durante il processo di distribuzione non si verifica alcuna interazione con l'interfaccia utente

Flussi dell'esperienza utente controllati dalla piattaforma

Anche all'interno dell'interfaccia utente Fabric, la piattaforma controlla determinati flussi di creazione e gestione. Il carico di lavoro riceve notifiche per queste operazioni per mantenere la coerenza:

  • Creazione di elementi tramite finestre di dialogo della piattaforma
  • Operazioni a livello di area di lavoro che influiscono sugli elementi
  • Operazioni di copia o spostamento tra aree di lavoro

Eventi del Ciclo di Vita

Il carico di lavoro può ricevere notifiche per gli eventi del ciclo di vita seguenti:

Creazione

Attivato quando viene creato un nuovo elemento. È possibile:

  • Configurare l'infrastruttura necessaria (database, risorse di calcolo)
  • Convalidare le licenze o le quote di capacità
  • Inizializzare le risorse specifiche di un elemento
  • Bloccare l'operazione se la convalida ha esito negativo o se i prerequisiti non sono soddisfatti

Update

Attivato quando vengono modificate le proprietà o la definizione di un elemento. È possibile:

  • Aggiornare l'infrastruttura associata
  • Convalidare la nuova configurazione
  • Sincronizzare le modifiche con i sistemi esterni
  • Bloccare l'operazione se l'aggiornamento viola le regole business

Elimina

Attivato quando viene eliminato un elemento. La richiesta include un deleteType campo che indica se si tratta di un'eliminazione temporanea o complessa:

  • Eliminazione definitiva: eliminazione permanente - Pulizia di tutte le risorse associate
  • Eliminazione temporanea: l'elemento è contrassegnato per l'eliminazione, ma può essere ripristinato in un secondo momento, mantenendo metadati e risorse sufficienti per supportare il ripristino

Il carico di lavoro può scegliere tra diverse strategie per l'eliminazione morbida.

  • Arrestare le risorse di calcolo costose durante la conservazione dei dati
  • Archiviare i dati critici nell'archiviazione a costi inferiori
  • Mantenere lo stato completo per il periodo di recupero

Annotazioni

Il token soggetto potrebbe non essere disponibile durante le operazioni di eliminazione. L'endpoint deve gestire di conseguenza l'autenticazione.

Restore

Attivato quando un elemento precedentemente eliminato temporaneamente viene ripristinato. L'endpoint riceve la definizione dell'elemento e deve:

  • Riassegnare le risorse liberate durante l'eliminazione temporanea
  • Ripristinare lo stato dell'elemento e riprendere i servizi
  • Reinizializzare le risorse di calcolo o di archiviazione in base alle esigenze

Formato richiesta

Fabric chiama un endpoint separato per ogni evento del ciclo di vita. Ogni richiesta include:

Parametri percorso URL

Le informazioni di identificazione dell'elemento vengono fornite nel percorso URL:

  • workspaceId - ID area di lavoro (UUID)
  • itemType - Tipo di elemento (ad esempio, Contoso.FinanceAnalytics.Forecast)
  • itemId - ID elemento (UUID)

Intestazione di autenticazione

L'intestazione Authorization usa lo schema SubjectAndAppToken1.0, che contiene sia un token utente delegato che un token solo app.

SubjectAndAppToken1.0 subjectToken="<delegated token>", appToken="<S2S token>"

Questo formato dual-token consente al carico di lavoro di convalidare l'origine della richiesta, verificare il contesto utente e chiamare altri servizi. Le intestazioni aggiuntive obbligatorie includono ActivityId, RequestIde x-ms-client-tenant-id.

Per informazioni dettagliate sulla convalida di questi token, vedere Autenticare endpoint remoti.

Corpo della richiesta

Il corpo della richiesta varia in base all'operazione:

  • Creare, aggiornare e ripristinare: il corpo contiene un ItemDefinition oggetto con una parts matrice. Ogni parte ha un oggetto path, payload (con codifica Base64) e payloadType.
  • Delete: il corpo contiene un campo deleteType con un valore di Hard o Soft.

Le informazioni nel corpo della richiesta consentono di:

  • Estrarre la configurazione per la configurazione dell'infrastruttura durante la creazione e il ripristino
  • Informazioni sulle modifiche apportate alle operazioni di aggiornamento
  • Prendere decisioni informate sulle operazioni di blocco
  • Scegliere la strategia di pulizia appropriata per eliminazioni hard e soft

Operazioni di blocco

Per le operazioni di creazione e aggiornamento, il carico di lavoro può bloccare l'operazione restituendo una risposta di errore dall'endpoint del flusso di lavoro. Ciò è utile per:

  • Convalida della licenza: impedire la creazione di elementi se l'utente non dispone di licenze necessarie
  • Imposizione della quota: blocca la creazione se vengono superati i limiti dell'area di lavoro o della capacità
  • Convalida della configurazione: rifiutare gli aggiornamenti che potrebbero creare stati non validi
  • Criteri di sicurezza: applicare i criteri dell'organizzazione alle configurazioni degli elementi

Quando si blocca un'operazione:

  1. Restituisci un codice di stato di errore (ad esempio, 400 o 403) dal tuo endpoint
  2. Fornire un messaggio di errore chiaro che spiega perché l'operazione è stata bloccata
  3. La piattaforma visualizza il messaggio di errore all'utente
  4. L'operazione sull'elemento non è stata completata

Importante

Le operazioni di eliminazione (sia hard che soft) non possono essere bloccate. Il carico di lavoro deve gestire la pulizia indipendentemente dallo stato dell'oggetto. Le operazioni di ripristino possono essere bloccate restituendo una risposta di errore.

Implementazione della gestione delle notifiche del ciclo di vita

Le notifiche del ciclo di vita definite negli elementi personalizzati non possono essere gestite direttamente all'interno di Fabric. È invece necessario implementare un endpoint remoto che Fabric chiama quando si verifica un evento del ciclo di vita. In questo modo è possibile controllare completamente dove e come viene eseguita la logica di gestione delle notifiche.

L'endpoint remoto può essere:

  • An Azure Function - Esecuzione semplice e serverless per la gestione semplificata delle notifiche
  • Un'istanza di Azure Container - Per le notifiche che richiedono ambienti di esecuzione specifici
  • Un servizio Web personalizzato : per orchestrazione ed elaborazione complesse
  • Qualsiasi servizio di calcolo : purché possa esporre un endpoint HTTP e gestire la notifica

Per informazioni dettagliate sull'implementazione e la configurazione di endpoint remoti, vedere Abilitare gli endpoint remoti.

Configurazione

Per abilitare le notifiche del ciclo di vita per l'elemento personalizzato, configurare le notifiche nel manifesto dell'elemento.

Definire le notifiche relative al ciclo di vita nel manifesto dell'elemento

Aggiungere la configurazione della notifica del ciclo di vita al manifesto dell'elemento:

<Item>
    <Name>YourItemType</Name>
    <!-- Other item configuration -->
    
    <LifecycleOperationsNotifications>
        <OnCreate>true</OnCreate>
        <OnUpdate>true</OnUpdate>
        <OnDelete>true</OnDelete>
    </LifecycleOperationsNotifications>
</Item>

Configurare solo gli eventi da gestire. Impostare il valore su false o omettere l'elemento se non sono necessarie notifiche per un tipo di evento specifico.

Importante

Quando OnDelete è abilitato, il carico di lavoro deve implementare anche l'endpoint OnRestoreItem . Fabric chiama questo endpoint quando viene ripristinato un elemento eliminato in modo soft, quindi il carico di lavoro deve essere preparato a gestire le notifiche di ripristino se gestisce quelle di eliminazione.

Requisiti dei terminali

L'endpoint del ciclo di vita deve:

  • Essere accessibili pubblicamente tramite HTTPS
  • Rispondere entro un timeout ragionevole (consigliato: 30 secondi)
  • Restituire i codici di stato HTTP appropriati
  • Gestire l'autenticazione usando il token fornito

Per le operazioni di creazione e aggiornamento che si desidera bloccare:

  • Restituire il codice di stato 4xx con i dettagli dell'errore
  • Includere un messaggio di errore descrittivo nel corpo della risposta

Per le operazioni che hanno esito positivo o per operazioni di eliminazione e ripristino:

  • Restituire il codice di stato 200 OK
  • Facoltativamente, includere informazioni di registrazione o rilevamento

Supporto per lo sviluppo locale

Per lo sviluppo e il test locali, l'Fabric Extensibility Toolkit fornisce un'implementazione stub predefinita nel server di sviluppo. In questo modo è possibile testare le notifiche del ciclo di vita degli elementi nel computer locale senza eseguire la distribuzione in Azure.

Funzionamento

Quando si esegue il server di sviluppo locale (vedere Introduzione a Fabric Extensibility Toolkit e Register Local Web Server), tutte le notifiche del ciclo di vita definite nel manifesto dell'elemento vengono reindirizzate automaticamente al computer locale.

Quando si verifica un evento del ciclo di vita in modalità di sviluppo:

  1. La notifica viene intercettata dal server di sviluppo locale
  2. Le istruzioni di log vengono visualizzate nella console locale che mostra i dettagli dell'evento
  3. Un'implementazione di esempio illustra come interagire con la definizione dell'elemento e l'archiviazione di OneLake
  4. Si riceve un token che può essere usato per chiamare qualsiasi operazione di Fabric

Questa implementazione dello stub fornisce:

  • Feedback immediato - vedere i messaggi di log nella console durante gli eventi del ciclo di vita
  • Codice di esempio - Informazioni su come strutturare la logica di gestione delle notifiche
  • Esempi di integrazione di OneLake - Vedere come accedere all'archiviazione OneLake dell'elemento durante le notifiche
  • gestione Token - Informazioni su come ottenere e usare token di autenticazione Fabric
  • Accesso alla definizione dell'elemento - Visualizzare il payload completo della definizione dell'elemento

Uso dello stub di sviluppo

Per usare il server di sviluppo locale per i test delle notifiche del ciclo di vita:

  1. Avviare il server di sviluppo locale seguendo la guida introduttiva
  2. Registrare il server Web locale usando la procedura di registrazione
  3. Configurare le notifiche del ciclo di vita nel manifesto dell'elemento come descritto in precedenza
  4. Eseguire operazioni sugli elementi (creazione, aggiornamento, eliminazione) in Fabric
  5. Osservare i dettagli della notifica nella console locale
  6. Esaminare il codice di esempio per l'interazione di OneLake e la gestione dei token nei log del server di sviluppo

Esempio di interazione di OneLake

Lo stub di sviluppo include codice di esempio che illustra come interagire con l'archiviazione OneLake dell'elemento:

// Example from the development stub
const tokenExchangeService = require('./tokenExchangeService');
const oneLakeClientService = require('./oneLakeClientService');

async function handleCreateWithOneLakeAccess(req) {
  const { workspaceId, itemId } = req.params;
  const { subjectToken, tenantId } = req.authContext;

  // Exchange user token for OneLake-scoped token
  const oneLakeToken = await tokenExchangeService.getTokenForScope(
    subjectToken, tenantId, oneLakeClientService.ONELAKE_SCOPE);

  // Write to the item's OneLake storage
  const filePath = oneLakeClientService.getOneLakeFilePath(
    workspaceId, itemId, 'config.json');
  const content = JSON.stringify(req.body, null, 2);
  await oneLakeClientService.writeToOneLakeFile(oneLakeToken, filePath, content);

  console.log(`Initialized item configuration in OneLake at ${filePath}`);
}

Questa esperienza di sviluppo locale consente di compilare e testare la logica di notifica del ciclo di vita prima della distribuzione agli endpoint di produzione.

Esempio di implementazione

L'esempio seguente usa Node.js ed Express, in base all'implementazione di riferimento Fabric Extensibility Toolkit. Ogni evento del ciclo di vita ha un proprio endpoint che Fabric chiama con il corpo della richiesta appropriato. Per informazioni dettagliate sull'API, vedere le informazioni di riferimento sull'API REST del ciclo di vita degli elementi.

const express = require('express');
const { authenticateControlPlaneCall } = require('./authentication');
const router = express.Router();

// POST /workspaces/{workspaceId}/items/{itemType}/{itemId}/onCreateItem
// Request body: { definition: { parts: [{ path, payload, payloadType }] } }
router.post('/workspaces/:workspaceId/items/:itemType/:itemId/onCreateItem',
  async (req, res) => {
    const authResult = await authenticateControlPlaneCall(req, res);
    if (!authResult) return;

    const { workspaceId, itemId, itemType } = req.params;
    const { definition } = req.body;

    // Validate license before allowing creation
    const hasLicense = await checkUserLicense(req.authContext.userId);
    if (!hasLicense) {
      return res.status(403).json({
        errorCode: 'LicenseRequired',
        message: 'User does not have the required license for this item type.',
        source: 'User',
        isPermanent: true
      });
    }

    // Set up infrastructure for the new item
    await provisionResources(workspaceId, itemId, definition);

    console.log(`Created item ${itemId} of type ${itemType}`);
    res.status(200).json({});
  }
);

// POST /workspaces/{workspaceId}/items/{itemType}/{itemId}/onUpdateItem
// Request body: { definition: { parts: [{ path, payload, payloadType }] } }
router.post('/workspaces/:workspaceId/items/:itemType/:itemId/onUpdateItem',
  async (req, res) => {
    const authResult = await authenticateControlPlaneCall(req, res);
    if (!authResult) return;

    const { workspaceId, itemId } = req.params;
    const { definition } = req.body;

    // Validate the updated definition
    if (!isValidConfiguration(definition)) {
      return res.status(400).json({
        errorCode: 'InvalidConfiguration',
        message: 'Invalid configuration: required settings are missing.',
        source: 'User',
        isPermanent: true
      });
    }

    await updateResources(workspaceId, itemId, definition);

    console.log(`Updated item ${itemId}`);
    res.status(200).json({});
  }
);

// POST /workspaces/{workspaceId}/items/{itemType}/{itemId}/onDeleteItem
// Request body: { deleteType: "Hard" | "Soft" }
// Note: Subject token may not be available during delete operations.
router.post('/workspaces/:workspaceId/items/:itemType/:itemId/onDeleteItem',
  async (req, res) => {
    const authResult = await authenticateControlPlaneCall(req, res,
      { requireSubjectToken: false });
    if (!authResult) return;

    const { workspaceId, itemId } = req.params;
    const { deleteType } = req.body;

    if (deleteType === 'Hard') {
      await deleteAllResources(workspaceId, itemId);
      console.log(`Hard deleted item ${itemId}`);
    } else if (deleteType === 'Soft') {
      // Retain metadata for recovery; optionally free expensive resources
      await stopComputeResources(workspaceId, itemId);
      console.log(`Soft deleted item ${itemId}`);
    }

    res.status(200).json({});
  }
);

// POST /workspaces/{workspaceId}/items/{itemType}/{itemId}/onRestoreItem
// Request body: { definition: { parts: [{ path, payload, payloadType }] } }
// Called when a soft-deleted item is restored.
router.post('/workspaces/:workspaceId/items/:itemType/:itemId/onRestoreItem',
  async (req, res) => {
    const authResult = await authenticateControlPlaneCall(req, res,
      { requireSubjectToken: false });
    if (!authResult) return;

    const { workspaceId, itemId } = req.params;
    const { definition } = req.body;

    // Re-allocate resources freed during soft delete
    await restoreResources(workspaceId, itemId, definition);

    console.log(`Restored item ${itemId}`);
    res.status(200).json({});
  }
);

Casi d'uso

Gestione dell'infrastruttura

Effettuare automaticamente il provisioning e il deprovisioning dell'infrastruttura in base al ciclo di vita degli elementi:

// In onCreateItem handler: Provision resources
await createSqlDatabase(itemId);
await createStorageAccount(itemId);
await createComputeCluster(itemId);

// In onDeleteItem handler (deleteType === 'Hard'): Clean up resources
await deleteSqlDatabase(itemId);
await deleteStorageAccount(itemId);
await deleteComputeCluster(itemId);

Convalida delle licenze e delle quote

Imporre i requisiti di licenza e capacità nel gestore onCreateItem.

// Check user license before allowing creation
const userLicense = await getUserLicense(req.authContext.userId);
if (userLicense.tier < REQUIRED_TIER_PREMIUM) {
  return res.status(403).json({
    errorCode: 'LicenseRequired',
    message: 'Premium license required for this item type.',
    source: 'User',
    isPermanent: true
  });
}

// Check workspace capacity
const workspaceUsage = await getWorkspaceUsage(workspaceId);
if (workspaceUsage.itemCount >= workspaceUsage.maxItems) {
  return res.status(403).json({
    errorCode: 'QuotaExceeded',
    message: 'Workspace item limit reached.',
    source: 'User',
    isPermanent: false
  });
}

Sincronizzazione del sistema esterno

Mantenere sincronizzati i sistemi esterni con gli elementi Fabric:

// In onCreateItem handler: Sync item to external catalog
const { workspaceId, itemId, itemType } = req.params;
await externalCatalog.registerItem({
  id: itemId,
  type: itemType,
  workspaceId: workspaceId
});

// Update external monitoring
await monitoringSystem.trackItemCreated(workspaceId, itemId);

Strategia di eliminazione e ripristino

Implementare strategie di pulizia diverse in base a deleteTypee gestire il ripristino:

// In onDeleteItem handler:
const { deleteType } = req.body;

if (deleteType === 'Soft') {
  // Free expensive resources but retain data for potential recovery
  await stopExpensiveCompute(itemId);
  await archiveDataToLowCostStorage(itemId);
}

if (deleteType === 'Hard') {
  // Permanent deletion - clean up everything
  await deleteAllResources(itemId);
}

// In onRestoreItem handler:
// Re-allocate resources freed during soft delete
await restartCompute(itemId);
await restoreDataFromArchive(itemId);

Migliori pratiche

Rispondere rapidamente

Gli endpoint del ciclo di vita devono rispondere il più rapidamente possibile:

  • Eseguire le operazioni di convalida e configurazione rapida in modo sincrono
  • Provisioning dell'infrastruttura a esecuzione prolungata in coda per l'elaborazione in background
  • Restituire rapidamente successo/fallimento per evitare timeout

Gestire idempotenza

Le operazioni sugli elementi possono essere ripetute, quindi l'idempotenza dell'endpoint è necessaria.

  • Verificare se l'infrastruttura esiste già prima della creazione
  • Usare identificatori univoci per tenere traccia delle operazioni
  • Gestire correttamente le notifiche duplicate

Fornire messaggi di errore non crittografati

Quando si bloccano le operazioni, fornire messaggi di errore utili:

// Good: Structured ErrorResponse with a clear message
return res.status(403).json({
  errorCode: 'LicenseRequired',
  message: 'Cannot create item: Premium license required. Upgrade your subscription.',
  source: 'User',
  isPermanent: true
});

// Poor: Missing structured error information
return res.status(403).json({ message: 'Forbidden' });

sicurezza

  • Convalidare il token di autenticazione in ogni richiesta
  • Usare il token per verificare che l'operazione sia legittima
  • Non considerare attendibili gli ID elemento o gli ID dell'area di lavoro senza convalida
  • Vedere Autenticare gli endpoint remoti per le procedure consigliate per la sicurezza

Monitoraggio e registrazione

  • Registrare tutte le notifiche del ciclo di vita ricevute
  • Monitorare il successo/fallimento del provisioning dell'infrastruttura
  • Monitorare le prestazioni e gli errori degli endpoint
  • Usare i dati di notifica per i tracciamenti di controllo

Risoluzione dei problemi

Notifiche non ricevute

  • Verificare che l'URL dell'endpoint sia corretto nel manifesto
  • Verificare che l'endpoint sia accessibile pubblicamente
  • Verificare che HTTPS sia configurato correttamente
  • Esaminare i log degli endpoint per individuare gli errori

Timeout delle operazioni

  • Ottimizzare il tempo di risposta dell'endpoint
  • Spostare le operazioni a esecuzione prolungata in processi in background
  • Aumentare le impostazioni di timeout dell'endpoint, se necessario
  • Valutare le prestazioni del provisioning dell'infrastruttura

Blocco non funzionante

  • Verificare di restituire codici di stato 4xx per le operazioni bloccate
  • Verificare che i messaggi di errore siano inclusi nella risposta
  • Verificare che l'endpoint risponda all'interno della finestra di timeout
  • Tenere presente che le operazioni di eliminazione non possono essere bloccate. La piattaforma Fabric contrassegna l'elemento come eliminato indipendentemente dalla risposta del carico di lavoro.