Entradas

Versión estable y lista del servidor proxy en Node.js

Para este tipo de pruebas Node.js es más flexible, rápido de levantar y más visual que un servidor embebido en Java (como NanoHTTPD). Además, puedes extenderlo fácil con métricas o gráficas si lo necesitas después. Entonces, dejemos todo claro para que puedas usar Node como tu analizador de peticiones Spark const express = require('express'); const app = express(); app.use(express.json()); let contador = 0; let contadorMinuto = 0; const peticiones = []; setInterval(() => {   console.log(`📊 ${contadorMinuto} peticiones en el último minuto`);   contadorMinuto = 0; }, 60 * 1000); app.all('*', (req, res) => {   contador++;   contadorMinuto++;   const timestamp = Date.now();   const diff = peticiones.length > 0 ? timestamp - peticiones[peticiones.length - 1] : 0;   peticiones.push(timestamp);   console.log(`==== NUEVA PETICIÓN ==== #${contador} Tiempo desde la anterior: ${diff} ms Método: ${req.method} Ruta: ${req.url} Headers: ${JSON.strin...

Pequeño server local

<project xmlns="http://maven.apache.org/POM/4.0.0"          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0                              http://maven.apache.org/xsd/maven-4.0.0.xsd">     <modelVersion>4.0.0</modelVersion>     <groupId>com.example</groupId>     <artifactId>simple-server</artifactId>     <version>1.0-SNAPSHOT</version>     <properties>         <java.version>11</java.version>     </properties>     <dependencies>         <!-- NanoHTTPD -->         <dependency>             <groupId>org.nanohttpd</groupId>     ...

iteratorSeguro

El problema con toLocalIterator() es que trae todos los datos al driver , y Sonar lo marca como riesgo de memoria si el dataset es grande. La solución es procesar los datos en particiones usando mapPartitions , que mantiene los datos en los nodos del cluster y solo itera localmente por partición.  n método auxiliar que reemplace toLocalIterator() y devuelva un Iterator de manera segura por partición: public static <T> Iterator<T> iteratorSeguro(Dataset<T> dataset) {     return dataset.mapPartitions((Iterator<T> partition) -> {         List<T> buffer = new ArrayList<>();         partition.forEachRemaining(buffer::add);         return buffer.iterator();     }, Encoders.javaSerialization(Object.class)).toLocalIterator(); } public static <T> Iterator<T> iteratorSeguro(Dataset<T> dataset) {     return dataset.mapPartitions((Iterator<T...

CobolParser Para Spark

 import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import org.apache.spark.sql.SparkSession; import static org.apache.spark.sql.functions.*; public class CobolParser {     public static Dataset<Row> parseCobolFromLeft(SparkSession spark, String path) {         Dataset<Row> df = spark.read().text(path)             .withColumn("line_length", length(col("value")));         // Extraer campos desde la izquierda         df = df.withColumn("id",                     when(col("line_length").geq(6),                         substring(col("value"), 1, 6))                     .otherwise(lit(null)))               .withColumn("producto",           ...

Cómo convertir múltiples formatos de fecha en Apache Spark con Java y evitar errores comunes

 Cuando trabajamos con Dataset<Row> en Apache Spark, un desafío común es el formato inconsistente de fechas . Algunas columnas pueden traer la fecha como "1987-12-05" , otras como "2007-06-15 00:00:00 +0100 +01:00" , y algunas incluso como texto plano. Este problema puede causar errores de parseo y valores null inesperados. En este artículo te mostraré cómo resolver esto de forma robusta y escalable con Java, renombrando columnas, manejando múltiples formatos y evitando valores nulos. 🎯 Objetivo Queremos transformar varias columnas de un Dataset<Row> que contienen fechas en diferentes formatos, para: Renombrar las columnas con nombres estándar. Convertir el contenido a tipo Date si es necesario. Agregar una columna formateada en estilo dd/MM/yy para persistencia o exportación. 📦 ¿Por qué puede fallar el parseo? Spark utiliza to_date() con un patrón de formato específico. Si le pasas un valor que no se ajusta exactamente, te dev...

Cómo parsear archivos CSV procesamiento de archivos

 el procesamiento de archivos CSV en Spark, especialmente cuando las comas dentro de comillas deben ser respetadas. Ambos métodos funcionan bien, pero tienen diferencias clave: 1. Usando UserDefinedFunction (UDF) Este enfoque utiliza una función definida por el usuario (UDF) para procesar la cadena, hacer el split y devolver un array de strings. El UDF garantiza que las comas dentro de comillas se respeten. Es una solución más flexible, ya que puedes definir tu propia lógica de transformación. Pros: Flexibilidad: Permite una transformación personalizada de las columnas. Fácil de aplicar a un Dataset: Se aplica directamente sobre una columna. Optimización de Spark: Puedes aprovechar las optimizaciones que realiza Spark para aplicar el UDF en paralelo. Ejemplo: import org.apache.spark.sql.*; import org.apache.spark.sql.functions; import org.apache.spark.sql.expressions.UserDefinedFunction; import org.apache.spark.sql.types.*; import java.util.regex.Pattern; import java.util.regex.Mat...

Separacion de archivos csv por comas

Aquí tienes un ejemplo completo con datos de prueba: java import org . apache . spark . sql . * ; import org . apache . spark . sql . types . * ; import java . util . Arrays ; import java . util . List ; import static org . apache . spark . sql . functions . * ; public class SparkCSVParserExample { public static void main ( String [ ] args ) { // Crear la sesión de Spark SparkSession spark = SparkSession . builder ( ) . appName ( "CSVParserExample" ) . master ( "local[*]" ) . getOrCreate ( ) ; // Crear datos de ejemplo donde cada fila es una cadena CSV completa List < String > rawDataList = Arrays . asList ( "id,nombre,direccion,edad" , "101,\"Juan, Pérez\",\"Calle Principal, #45, Ciudad\",30" , "102,\"María Rodríguez\",\"Av. Central #123\",25...