Managed Service para Apache Spark te permite consultar y analizar datos empresariales externos directamente desde tus cargas de trabajo de Spark. Puedes usar el controlador JDBC de Workday Live Data Query para conectarte a tu usuario de Workday, cargar conjuntos de datos de Workday en tiempo real en Spark DataFrames y, luego, integrar esos datos en tu canalización de estadísticas en Google Cloud.
En esta guía, configurarás Workday Live Data Query, almacenarás tu clave privada de forma segura en Secret Manager y usarás la extensión de Google Cloud Data Agent Kit para ejecutar un notebook de PySpark en Visual Studio Code o el editor de Cloud Shell en Managed Service para Apache Spark.
Costos
La extensión Data Agent Kit está disponible sin costo adicional. Sin embargo, en esta guía se usan los siguientes componentes facturables de Google Cloud:
Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios.
Antes de comenzar
- Accede a tu cuenta de Google Cloud . Si eres nuevo en Google Cloud, crea una cuenta para evaluar el rendimiento de nuestros productos en situaciones reales. Los clientes nuevos también obtienen $300 en créditos gratuitos para ejecutar, probar y, además, implementar cargas de trabajo.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that you have the permissions required to complete this guide.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc, Dataplex, Cloud Storage, and Secret Manager APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that you have the permissions required to complete this guide.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Dataproc, Dataplex, Cloud Storage, and Secret Manager APIs, if any are not already enabled.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.
Roles de Identity and Access Management (IAM) necesarios
Se requieren ciertos roles de IAM para ejecutar los ejemplos de esta página. Según las políticas de la organización, es posible que ya se hayan otorgado estos roles. Para verificar las asignaciones de roles, consulta ¿Necesitas otorgar roles?. Para obtener más información para otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.
Los roles que necesitas dependen de cómo se ejecuta tu carga de trabajo. Los entornos de ejecución sin servidores 2.3 y anteriores de Managed Service para Apache Spark ejecutan cargas de trabajo como una cuenta de servicio. Los entornos de ejecución sin servidores 3.0 y posteriores de Managed Service para Apache Spark ejecutan cargas de trabajo de forma predeterminada con tus credenciales de usuario final (EUC), por lo que otorgas roles de acceso a los datos a tu cuenta de usuario en lugar de a una cuenta de servicio. Si especificas una cuenta de servicio personalizada para un entorno de ejecución 3.0 o posterior, la carga de trabajo se ejecuta con las credenciales de la cuenta de servicio. Para obtener más información, consulta Roles de implementaciones sin servidores.
Funciones de usuario
Para obtener los permisos que necesitas para crear una sesión de notebook interactiva de Managed Service para Apache Spark y acceder a los recursos, pídele a tu administrador que te otorgue los siguientes roles de IAM:
-
Usa el entorno de ejecución sin servidores 2.3 o una versión anterior:
- Editor de Dataproc (
roles/dataproc.editor) en el proyecto - Usuario de cuenta de servicio (
roles/iam.serviceAccountUser) en la cuenta de servicio predeterminada de Compute Engine o en una cuenta de servicio personalizada
- Editor de Dataproc (
-
Usa el entorno de ejecución sin servidores 3.0 o una versión posterior:
Editor de Dataproc Serverless (
roles/dataproc.serverlessEditor) en el proyecto -
Lee el controlador de JDBC desde Cloud Storage con las credenciales del usuario final:
Visualizador de objetos de almacenamiento (
roles/storage.objectViewer) en el bucket que contiene el controlador -
Lee el secreto de la clave privada de Secret Manager con las credenciales del usuario final:
Descriptor de acceso a secretos de Secret Manager (
roles/secretmanager.secretAccessor) en el secreto o proyecto
Roles de la cuenta de servicio
Otorga los siguientes roles a la cuenta de servicio que ejecuta tu carga de trabajo. Los entornos de ejecución sin servidores 3.0 y posteriores de Managed Service para Apache Spark necesitan estos roles solo si la carga de trabajo se ejecuta con credenciales de cuenta de servicio en lugar de las credenciales de usuario final (EUC) predeterminadas.
Para garantizar que la cuenta de servicio predeterminada de Compute Engine o una cuenta de servicio personalizada tengan los permisos necesarios para ejecutar cargas de trabajo de Managed Service para Apache Spark, leer el controlador y acceder a los secretos, pídele a tu administrador que otorgue los siguientes roles de IAM a la cuenta de servicio predeterminada de Compute Engine o a una cuenta de servicio personalizada:
-
Usa el entorno de ejecución sin servidores 2.3 o anterior:
Trabajador de Dataproc (
roles/dataproc.worker) en el proyecto -
Usa el entorno de ejecución sin servidores 3.0 o una versión posterior con credenciales de cuenta de servicio en lugar de las credenciales de usuario final (EUC) predeterminadas:
- Nodo sin servidores de Dataproc (
roles/dataproc.serverlessNode) en el proyecto - Agente de servicio del nodo de Dataproc Resource Manager (
roles/dataprocrm.nodeServiceAgent) en el proyecto
- Nodo sin servidores de Dataproc (
-
Lee el controlador de JDBC desde Cloud Storage:
Visualizador de objetos de Storage (
roles/storage.objectViewer) en el bucket que contiene el controlador -
Lee el secreto de la clave privada de Secret Manager:
Descriptor de acceso a secretos de Secret Manager (
roles/secretmanager.secretAccessor) en el secreto o proyecto
Requisitos previos de Workday
Antes de conectarte a Workday con Live Data Query, completa la siguiente configuración:
Descarga el controlador de JDBC de Workday Live Data Query desde Workday.
Sube el archivo JAR del controlador JDBC descargado a un bucket de Cloud Storage en tu proyecto.
Completa los pasos de configuración para establecer la consulta de datos en vivo en tu inquilino de Workday, como se describe en la documentación de la consulta de datos en vivo de Workday.
Durante la configuración en Workday, crea un usuario del sistema de integración (ISU), registra un cliente de API y genera un par de claves privadas.
Toma nota de los siguientes valores de configuración de Workday:
Host de Workday: Es el host de tu usuario de Workday, por ejemplo,
services1.workday.com.Nombre del usuario: Es el nombre del usuario de Workday.
ID de cliente: Es el ID de cliente de API registrado de tu usuario de Workday.
Nombre de usuario de ISU: Es el nombre de usuario del sistema de integración.
Almacena la clave privada en Secret Manager
Almacena el archivo de clave privada generado durante la configuración de Workday Live Data Query de forma segura en Secret Manager:
En Cloud Shell, ejecuta el siguiente comando para generar un par de claves x509:
openssl req -x509 -newkey rsa:2048 -keyout private-key.pem -out public-key.cert -sha256 -days 365 -nodesPara ver la clave privada, ejecuta el siguiente comando:
cat private-key.pemAlmacena la clave privada en Secret Manager:
En la consola de Google Cloud , ve a la página Secret Manager:
Haz clic en Crear secreto.
En el campo Nombre, ingresa un nombre para el Secret, como
workday-private-key.En Valor del Secret, sube
private-key.pemo pega el contenido de la clave privada, incluidas las líneas de encabezado y pie de página-----BEGIN PRIVATE KEY-----y-----END PRIVATE KEY-----.Haz clic en Crear secreto.
Para ver la clave pública, ejecuta el siguiente comando:
cat public-key.certEn Workday, busca Create x509 Public Key, pega la clave pública de
public-key.certy haz clic en OK.En el cliente de la API de Workday que creaste antes, actualiza el certificado x509 a la nueva clave x509.
Configura el Data Agent Kit en tu IDE
Puedes configurar el Data Agent Kit instalando la extensión en Visual Studio Code o en otro IDE compatible, o bien usando la extensión preinstalada en el editor de Cloud Shell.
Para configurar el Data Agent Kit en tu IDE o en el editor de Cloud Shell, completa los siguientes pasos:
Establece y configura el Data Agent Kit:
Crear un notebook
Con Data Agent Kit, crea un notebook de PySpark interactivo:
En tu IDE o en el editor de Cloud Shell, abre el panel Data Agent Kit.
En Apache Spark, selecciona Nuevo notebook y, luego, Kernel local.
Selecciona un entorno de ejecución de la lista de entornos de ejecución disponibles (también llamados plantillas de sesión).
Selecciona Comenzar con un cuaderno nuevo.
Se abrirá un notebook nuevo con una celda inicial que contiene el código de inicialización de la sesión de Spark Connect.
En la parte superior del editor de notebooks, haz clic en Select Kernel y, luego, selecciona un kernel de Python local para tu notebook.
Consulta datos de Workday en PySpark
En la primera celda del notebook, instala las bibliotecas cliente necesarias y configura las variables de entorno:
%pip install dataproc-spark-connect google-cloud-dataproc google-cloud-secret-manager google-cloud-storage #@title Set up all environment variables # Replace with your Project ID %env PROJECT_ID=PROJECT_ID # Replace with the name of the Secret Manager global secret in the project %env SECRET_NAME=workday-private-key # Replace with the version of the secret to use %env SECRET_VERSION=latest # Replace with the Cloud Storage bucket where you have the Workday Data Cloud JDBC Driver file stored %env JDBC_DRIVER_GCS_BUCKET=BUCKET_NAME # Replace with the name of the Workday Data Cloud JDBC Driver file in the Cloud Storage bucket %env JDBC_DRIVER_FILE_NAME=ldq-jdbc-driver-1.1.0-all.jar # Replace with the local directory of the notebook to copy the JDBC Driver File to %env JDBC_DRIVER_LOCAL_DIRECTORY=/tmp # Replace with the Driver Class for the Workday Data Cloud JDBC Driver %env WORKDAY_DRIVER_CLASS=com.workday.ldq.jdbc.Driver # ------------------------------------------------------------------------------ # Replace with the Workday URL of your tenant %env WORKDAY_HOST=WORKDAY_HOST # Replace with your Workday tenant name %env TENANT_NAME=TENANT_NAME # Replace with the Client ID of the "API Client" %env CLIENT_ID=CLIENT_ID # Replace with the Integration System User username %env ISU_USERNAME=ISU_USERNAMEEn una celda nueva, otorga el rol de Usuario con acceso a secretos de Secret Manager (
roles/secretmanager.secretAccessor) a la cuenta de servicio predeterminada de Compute Engine:%%bash COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT=$(gcloud iam service-accounts list --project="${PROJECT_ID}" \ --filter="email ~ -compute@developer.gserviceaccount.com" \ --format="value(email)") echo "COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT: ${COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT}" gcloud secrets add-iam-policy-binding ${SECRET_NAME} \ --project="${PROJECT_ID}" \ --member="serviceAccount:${COMPUTE_ENGINE_DEFAULT_SERVICE_ACCOUNT}" \ --role="roles/secretmanager.secretAccessor"En una celda nueva, copia el controlador JDBC de Cloud Storage al directorio local:
gsutil cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME $JDBC_DRIVER_LOCAL_DIRECTORYEn una celda nueva, instala la biblioteca cliente de Secret Manager:
%%bash pip install google-cloud-secret-managerEn una celda nueva, verifica que el archivo JAR del controlador se descargue de forma local:
!gsutil cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME /tmp/ !ls -lh /tmp/ldq-jdbc-driver-1.1.0-all.jarEn una celda nueva, inserta el JAR del controlador de Workday en el directorio de JAR de PySpark:
%%bash echo "Downloading Workday JAR from Cloud Storage..." # Downloads your specific 1.1.0 driver JAR into the notebook's /tmp folder gcloud storage cp gs://$JDBC_DRIVER_GCS_BUCKET/$JDBC_DRIVER_FILE_NAME /tmp/ echo "Dynamically finding the PySpark jars directory..." PYSPARK_JARS=$(python -c "import os, pyspark; print(os.path.join(os.path.dirname(pyspark.__file__), 'jars'))") echo "Found PySpark jars at: $PYSPARK_JARS" echo "Injecting Workday driver into PySpark core..." cp /tmp/$JDBC_DRIVER_FILE_NAME "$PYSPARK_JARS/" echo "Success! The driver is now a native part of PySpark."En una celda nueva, configura el entorno de Spark y recupera la clave privada x509 de Secret Manager:
#@title Configure the Spark environment and retrieve the x509 private key from Secret Manager import os import pyspark from pyspark.sql import SparkSession from google.cloud import secretmanager PROJECT_ID = os.environ["PROJECT_ID"] SECRET_NAME = os.environ["SECRET_NAME"] SECRET_VERSION = os.environ["SECRET_VERSION"] JDBC_DRIVER_LOCAL_DIRECTORY = os.environ["JDBC_DRIVER_LOCAL_DIRECTORY"] JDBC_DRIVER_FILE_NAME = os.environ["JDBC_DRIVER_FILE_NAME"] LOCAL_JAR_PATH = JDBC_DRIVER_LOCAL_DIRECTORY + "/" + JDBC_DRIVER_FILE_NAME WORKDAY_HOST = os.environ["WORKDAY_HOST"] TENANT_NAME = os.environ["TENANT_NAME"] CLIENT_ID = os.environ["CLIENT_ID"] ISU_USERNAME = os.environ["ISU_USERNAME"] WORKDAY_DRIVER_CLASS = os.environ["WORKDAY_DRIVER_CLASS"] jdbc_url = f"jdbc:workday://{WORKDAY_HOST}:443/system/information_schema?SSLVerification=CA" def access_private_key_secret(): print(f"Fetching secret contents from Secret Manager: {SECRET_NAME}...") client = secretmanager.SecretManagerServiceClient() secret_name = f"projects/{PROJECT_ID}/secrets/{SECRET_NAME}/versions/{SECRET_VERSION}" response = client.access_secret_version(request={"name": secret_name}) print(f"Fetched secret contents from Secret Manager: {SECRET_NAME}") return response.payload.data.decode("UTF-8") private_key_content = access_private_key_secret()En una celda nueva, inicializa la sesión de Spark con la configuración de classpath:
# Stop the old cached Spark session so your newly downloaded JAR is not ignored! try: spark.stop() print("Stopped existing Spark session.") except Exception: pass print("Initializing fresh Spark session with Classpath configuration...") print(f"Loading JAR from: {LOCAL_JAR_PATH}") # Rebuild Spark session with explicit Driver & Executor classpaths spark = SparkSession.builder \ .appName("WorkdayJDBC Connection Example") \ .config("spark.jars", LOCAL_JAR_PATH) \ .config("spark.driver.extraClassPath", LOCAL_JAR_PATH) \ .config("spark.executor.extraClassPath", LOCAL_JAR_PATH) \ .getOrCreate() print("Spark Session successfully booted with JAR!")En una celda final, inicia la conexión y consulta Workday:
import os import subprocess import zipfile from pyspark.sql import SparkSession LOCAL_JAR_PATH = "/tmp/ldq-jdbc-driver-1.1.0-all.jar" # Load bucket and file name from your Cell 1 environment variables GCS_BUCKET = os.environ.get("JDBC_DRIVER_GCS_BUCKET", "BUCKET_NAME") GCS_FILE = os.environ.get("JDBC_DRIVER_FILE_NAME", "ldq-jdbc-driver-1.1.0-all.jar") GCS_URI = f"gs://{GCS_BUCKET}/{GCS_FILE}" # 1. Ensure the JAR file is in the notebook's /tmp directory if not os.path.exists(LOCAL_JAR_PATH): print(f"Downloading {GCS_URI} to {LOCAL_JAR_PATH}...") subprocess.run(["gsutil", "cp", GCS_URI, LOCAL_JAR_PATH], check=True) print(f"JAR verified on disk: {LOCAL_JAR_PATH} ({os.path.getsize(LOCAL_JAR_PATH):,} bytes)") # 2. Read the real JDBC driver class name (skipping any '#' comment lines!) with zipfile.ZipFile(LOCAL_JAR_PATH, "r") as z: raw_lines = ( z.read("META-INF/services/java.sql.Driver") .decode("utf-8") .splitlines() ) # Filter out empty lines and '#' comment lines valid_classes = [ line.strip() for line in raw_lines if line.strip() and not line.strip().startswith("#") ] driver_class = valid_classes[0] print(f"Real Driver Class inside JAR: {driver_class}") # 3. Get or create the Spark session spark = SparkSession.builder.appName("WorkdayJDBC Connection Example").getOrCreate() # 4. Inject the JAR directly into the running Java URLClassLoader (and Scala SparkContext) jvm = spark.sparkContext._jvm jar_url = jvm.java.io.File(LOCAL_JAR_PATH).toURI().toURL() # Add to both the Spark classloader and the current thread's context classloader jvm.org.apache.spark.util.Utils.getContextOrSparkClassLoader().addURL(jar_url) jvm.java.lang.Thread.currentThread().getContextClassLoader().addURL(jar_url) spark.sparkContext._jsc.sc().addJar(LOCAL_JAR_PATH) # Register the driver class with Spark's JDBC DriverRegistry jvm.org.apache.spark.sql.execution.datasources.jdbc.DriverRegistry.register(driver_class) print(f"Successfully registered {driver_class} in Spark's live JVM!") # 5. Query Workday print("Querying Workday...") df_data = ( spark.read.format("jdbc") .option("driver", driver_class) .option("url", jdbc_url) .option("wd.authn.clientId", CLIENT_ID) .option("wd.authn.isu", ISU_USERNAME) .option( "wd.authn.accessTokenEndpoint", f"https://{WORKDAY_HOST}/ccx/oauth2/{TENANT_NAME}/token", ) .option("wd.authn.privateKey", private_key_content) .option("query", "SELECT * FROM system.jdbc.catalogs") .load() ) print("Connection Successful! Data Retrieved:") df_data.show(50, truncate=False)Reemplaza lo siguiente:
PROJECT_ID: Es el ID del proyecto de Google Cloud .LOCATION: Es la región de Google Cloud tu plantilla de sesión de Managed Service para Apache Spark, por ejemplo,us-central1.RUNTIME_ID: Es el ID de la plantilla de sesión de Managed Service para Apache Spark.BUCKET_NAME: Es el nombre del bucket de Cloud Storage que contiene el controlador JDBC de Workday.PATH/workday-live-data-query-jdbc-driver.jar: Es la ruta de acceso del objeto al JAR del controlador JDBC de Workday en tu bucket de Cloud Storage.WORKDAY_HOST: Es el host de tu usuario de Workday, por ejemplo,services1.workday.com.TENANT_NAME: Es el nombre de tu usuario de Workday.CLIENT_ID: Es el ID de cliente de la API registrado de tu usuario de Workday.ISU_USERNAME: el nombre de usuario del usuario del sistema de integración de tu inquilino de Workday.
Haz clic en Ejecutar celda (el ícono de reproducción) junto a la celda o presiona Mayúsculas + Intro.
Managed Service para Apache Spark ejecuta la consulta y muestra el resultado del DataFrame de Workday debajo de la celda.
Realiza una limpieza
Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en esta guía, finaliza las sesiones interactivas activas o borra los recursos creados.
Finalizar sesiones interactivas
En tu IDE o editor de Cloud Shell, finaliza la sesión activa del notebook cuando termine tu carga de trabajo.
Opcional: Borra el bucket de Cloud Storage o el archivo JAR del controlador de JDBC si ya no los necesitas.
Opcional: Borra el secreto de Secret Manager si ya no lo necesitas:
gcloud secrets delete workday-private-key
¿Qué sigue?
Obtén más información sobre la consulta de datos en vivo de Workday.
Obtén más información sobre el Data Agent Kit.
Explora las sesiones interactivas de Managed Service para Apache Spark.
Lee sobre las opciones de conexión de JDBC de Spark.