Conectividad Externa

ODBC/JDBC drivers, IBM i Access Client Solutions, connection pooling, data type mapping, ETL, tablas federadas y seguridad de conexiones.

ODBC y JDBC drivers

IBM i ofrece dos familias principales de drivers para conectividad externa: los drivers incluidos en IBM i Access Client Solutions (ACS) y el driver JDBC JTOpen (open source, parte del proyecto JTOpen/Toolbox for Java).

DriverProtocoloUso principal
IBM i Access ODBCODBCWindows apps, Excel, Power BI, Python (pyodbc)
IBM i Access JDBCJDBCJava apps, DBeaver, Spring Boot
JTOpen JDBC (jt400.jar)JDBCJava apps, open source, multiplataforma
IBM i Access .NET ProviderADO.NETC#, ASP.NET, .NET apps
DRDATCP/IP nativoServer-to-server, tablas federadas, CONNECT

PostgreSQL / MySQL -- Conectividad

  • psycopg2 / mysql-connector (Python)
  • pg / mysql2 (Node.js)
  • Npgsql / MySql.Data (.NET)
  • JDBC incluido en drivers oficiales
  • Connection strings simples: host:port/db

IBM i -- Conectividad

  • pyodbc + IBM i Access ODBC (Python)
  • idb-connector / odbc (Node.js)
  • IBM.Data.DB2.iSeries (.NET)
  • JTOpen jt400.jar (Java/JDBC)
  • Connection strings con parametros especificos

IBM i Access Client Solutions - driver

IBM i Access Client Solutions (ACS) incluye los drivers ODBC y JDBC oficiales. Se instala en la maquina cliente (Windows, Linux, Mac) y provee conectividad completa al IBM i.

ODBC Driver

Se instala con ACS. Aparece en el ODBC Data Source Administrator de Windows como 'IBM i Access ODBC Driver'.

JDBC Driver

El JAR se encuentra en la instalacion de ACS. Tambien disponible via Maven: com.ibm.as400:jt400.

.NET Provider

NuGet package: IBM.Data.DB2.iSeries. Integra nativamente con ADO.NET y Entity Framework.

Shell -- Verificar instalacion del driver ODBC
# En Linux/Mac: verificar que el driver esta registrado
odbcinst -q -d
# Debe mostrar: [IBM i Access ODBC Driver]

# En Windows: Panel de Control > ODBC Data Sources
# O ejecutar: odbcad32.exe

# Ubicacion tipica del driver en Windows:
# C:Program FilesIBMIBM i Access Client SolutionsODBCin
# Ubicacion del JAR JDBC:
# C:Program FilesIBMIBM i Access Client SolutionsJavajt400.jar

Connection pooling y tuning

Las conexiones a IBM i son costosas de crear (requieren autenticacion, setup de job, etc.). Connection pooling es esencial para aplicaciones que hacen muchas operaciones cortas.

Parametro de poolRecomendacion
Min pool size5-10 conexiones. Mantiene conexiones precalentadas disponibles.
Max pool size20-50 segun carga. Cada conexion es un job en IBM i.
Connection timeout30 segundos. Tiempo maximo para obtener conexion del pool.
Idle timeout300 segundos. Libera conexiones ociosas para reducir jobs.
Max lifetime1800 segundos. Recicla conexiones para evitar memory leaks.
Validation queryVALUES 1 o SELECT 1 FROM SYSIBM.SYSDUMMY1.
Java -- HikariCP connection pool para IBM i
// build.gradle o pom.xml
// implementation 'com.zaxxer:HikariCP:5.0.1'
// implementation 'net.sf.jt400:jt400:20.0.7'

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:as400://IBMI_HOST/MILIB");
config.setUsername("MIUSUARIO");
config.setPassword("mipassword");
config.setDriverClassName("com.ibm.as400.access.AS400JDBCDriver");

// Pool settings
config.setMinimumIdle(5);
config.setMaximumPoolSize(20);
config.setConnectionTimeout(30000);    // 30 seg
config.setIdleTimeout(300000);          // 5 min
config.setMaxLifetime(1800000);         // 30 min
config.setConnectionTestQuery("VALUES 1");

// Propiedades especificas de IBM i
config.addDataSourceProperty("naming", "sql");
config.addDataSourceProperty("date format", "iso");
config.addDataSourceProperty("libraries", "MILIB OTRALIB");
config.addDataSourceProperty("transaction isolation", "read committed");

HikariDataSource ds = new HikariDataSource(config);
Jobs en IBM i: Cada conexion al IBM i genera un job en el subsistema QUSRWRK (o QSERVER). Monitorea con WRKACTJOB SBS(QUSRWRK) para verificar que el pool no este creando demasiados jobs. Un pool de 50 conexiones significa 50 jobs concurrentes.

Data type mapping

La correspondencia de tipos de datos entre IBM i y lenguajes externos es critica para evitar perdida de precision, errores de conversion y problemas de CCSID.

Db2 for iJavaPython.NET
SMALLINTshortintInt16
INTEGERintintInt32
BIGINTlongintInt64
DECIMAL(p,s)BigDecimalDecimaldecimal
NUMERIC(p,s)BigDecimalDecimaldecimal
REALfloatfloatfloat
DOUBLEdoublefloatdouble
CHAR(n)Stringstrstring
VARCHAR(n)Stringstrstring
DATEjava.sql.Datedatetime.dateDateTime
TIMEjava.sql.Timedatetime.timeTimeSpan
TIMESTAMPjava.sql.TimestampdatetimeDateTime
BLOBbyte[]bytesbyte[]
CLOBStringstrstring
PACKED/ZONED decimal: IBM i usa formatos PACKED y ZONED para numeros decimales. Los drivers ODBC/JDBC manejan la conversion automaticamente, pero si accedes datos directamente (lectura de archivos flat) necesitas parsear estos formatos manualmente. Usa siempre SQL para evitar este problema.

Configuracion ODBC

La configuracion ODBC para IBM i incluye parametros especificos del sistema como naming convention, default library, formatos de fecha y manejo de CCSID.

Config -- Connection string ODBC
# Connection string completa para IBM i Access ODBC
Driver={IBM i Access ODBC Driver};
System=IBMI_HOST;
UID=MIUSUARIO;
PWD=mipassword;
DefaultLibraries=MILIB OTRALIB;
Naming=1;
DateFormat=5;
DateSeparator=/;
TimeFormat=1;
CommitMode=2;
ConnectionType=0;
AllowUnsupportedChar=1;
BlockFetch=1;
BlockSizeKB=512;
TrueAutoCommit=1;
ForceTranslation=0;
CCSID=1208;
ParametroValoresDescripcion
Naming0=SQL, 1=SystemSQL usa schema.tabla, System usa lib/tabla
DefaultLibrariesLIB1 LIB2 ...Lista de bibliotecas para resolver nombres
CommitMode0-40=*NONE, 1=*CHG, 2=*CS, 3=*ALL, 4=*RR
DateFormat0-75=ISO (YYYY-MM-DD), mas comun para apps externas
BlockFetch0/11=block fetch activado, mejora performance en SELECTs
CCSID37, 1208...CCSID de la conexion. 1208=UTF-8 para apps modernas
Python -- Conexion con pyodbc
import pyodbc

# Connection string
conn_str = (
    "Driver={IBM i Access ODBC Driver};"
    "System=IBMI_HOST;"
    "UID=MIUSUARIO;"
    "PWD=mipassword;"
    "DefaultLibraries=MILIB;"
    "Naming=0;"           # SQL naming (schema.tabla)
    "DateFormat=5;"       # ISO date format
    "CommitMode=2;"       # Read committed
    "CCSID=1208;"         # UTF-8
)

conn = pyodbc.connect(conn_str)
cursor = conn.cursor()

# Ejecutar query
cursor.execute("""
    SELECT ID, NOMBRE, SALDO
    FROM MILIB.CLIENTES
    WHERE ESTADO = ?
    ORDER BY NOMBRE
""", ('A',))

for row in cursor.fetchall():
    print(f"{row.ID}: {row.NOMBRE} - ${row.SALDO}")

cursor.close()
conn.close()

Configuracion JDBC

El driver JDBC de IBM i (JTOpen jt400.jar) se configura via URL de conexion y propiedades. Es el driver mas usado para aplicaciones Java y herramientas como DBeaver, DataGrip y Spring Boot.

Config -- JDBC URL y propiedades
# URL basica
jdbc:as400://IBMI_HOST/MILIB

# URL con propiedades inline
jdbc:as400://IBMI_HOST/MILIB;
  naming=sql;
  date format=iso;
  time format=iso;
  libraries=MILIB OTRALIB;
  transaction isolation=read committed;
  translate binary=true;
  prompt=false;
  block size=512;
  lazy close=true

# Driver class
com.ibm.as400.access.AS400JDBCDriver

# Maven dependency
# <dependency>
#   <groupId>net.sf.jt400</groupId>
#   <artifactId>jt400</artifactId>
#   <version>20.0.7</version>
# </dependency>
Java -- Spring Boot application.properties
# application.properties para Spring Boot
spring.datasource.url=jdbc:as400://IBMI_HOST/MILIB;\
  naming=sql;date format=iso;libraries=MILIB;\
  transaction isolation=read committed
spring.datasource.username=MIUSUARIO
spring.datasource.password=mipassword
spring.datasource.driver-class-name=\
  com.ibm.as400.access.AS400JDBCDriver

# HikariCP pool settings
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1800000
spring.datasource.hikari.connection-test-query=VALUES 1
Propiedad JDBCDescripcion
naming=sqlUsa notacion schema.tabla en vez de lib/tabla
libraries=LIB1 LIB2Library list para la conexion
date format=isoFormato ISO para fechas (YYYY-MM-DD)
translate binary=trueConvierte campos CHAR/VARCHAR binarios automaticamente
prompt=falseNo mostrar dialogo de credenciales
block size=512Tamano de bloque para fetch (KB)
lazy close=trueRetrasa el cierre de cursores para reuso
trace=trueHabilita trace para debugging (solo desarrollo)

.NET y IBM i

Para aplicaciones .NET (C#, ASP.NET, Blazor), IBM provee el paquete NuGet IBM.Data.DB2.iSeries que implementa ADO.NET y permite integracion con Entity Framework.

C# -- Conexion ADO.NET a IBM i
// NuGet: Install-Package IBM.Data.DB2.iSeries

using IBM.Data.DB2.iSeries;

var connStr = "DataSource=IBMI_HOST;" +
              "UserID=MIUSUARIO;" +
              "Password=mipassword;" +
              "DefaultCollection=MILIB;" +
              "Naming=sql;" +
              "DateFormat=ISO;" +
              "TrueAutoCommit=true;";

using var conn = new iDB2Connection(connStr);
conn.Open();

using var cmd = conn.CreateCommand();
cmd.CommandText = @"
    SELECT ID, NOMBRE, SALDO
    FROM MILIB.CLIENTES
    WHERE ESTADO = @estado
    ORDER BY NOMBRE";
cmd.Parameters.AddWithValue("@estado", "A");

using var reader = cmd.ExecuteReader();
while (reader.Read())
{
    Console.WriteLine(
        $"{reader.GetInt32(0)}: " +
        $"{reader.GetString(1)} - " +
        $"${reader.GetDecimal(2)}"
    );
}
Alternativa ODBC en .NET: Tambien podes usar System.Data.Odbc con el driver IBM i Access ODBC. Es mas simple de configurar pero el provider nativo iDB2 ofrece mejor performance y soporte de tipos de datos especificos de IBM i.

ETL y movimiento de datos

Mover datos entre IBM i y sistemas externos es una necesidad comun. Existen multiples estrategias segun el volumen, frecuencia y direccion del movimiento.

CPYTOIMPF / CPYFRMIMPF

Comandos CL nativos para exportar/importar CSV, delimited files. Rapido para batch.

SQL INSERT INTO ... SELECT

Usando tablas remotas via DRDA o federated queries. Directo y transaccional.

FTP / SFTP

Transferencia de archivos flat. Util para integracion con sistemas legacy.

Herramientas ETL externas

Talend, Informatica, SSIS pueden conectar via ODBC/JDBC al IBM i.

CL -- Exportar datos a CSV
/* Exportar tabla a CSV delimitado */
CPYTOIMPF FROMFILE(MILIB/CLIENTES) +
          TOSTMF('/home/exports/clientes.csv') +
          MBROPT(*REPLACE) +
          STMFCCSID(1208) +
          RCDDLM(*CRLF) +
          DTAFMT(*DLM) +
          STRDLM('"') +
          FLDDLM(',') +
          ADDCOLNAM(*SQL)

/* Importar CSV a tabla */
CPYFRMIMPF FROMSTMF('/home/imports/nuevos_clientes.csv') +
           TOFILE(MILIB/CLIENTES) +
           MBROPT(*ADD) +
           RCDDLM(*CRLF) +
           DTAFMT(*DLM) +
           STRDLM('"') +
           FLDDLM(',')
SQL -- Mover datos entre tablas y sistemas
-- Insertar datos desde una consulta SQL
INSERT INTO MILIB.CLIENTES_BACKUP
  SELECT * FROM MILIB.CLIENTES
  WHERE FECHA_CREACION < CURRENT_DATE - 365 DAYS;

-- Crear tabla a partir de query (CTAS)
CREATE TABLE MILIB.RESUMEN_ANUAL AS (
  SELECT YEAR(FECHA) AS ANIO,
         REGION, COUNT(*) AS TOTAL,
         SUM(MONTO) AS MONTO_TOTAL
  FROM MILIB.VENTAS
  GROUP BY YEAR(FECHA), REGION
) WITH DATA;

-- Usando IFS para leer archivos
-- (requiere configuracion previa)
CREATE TABLE QTEMP.DATOS_IMPORT AS (
  SELECT * FROM
  TABLE(QSYS2.IFS_READ_UTF8(
    PATH_NAME => '/home/datos/input.csv'
  ))
) WITH DATA;

Tablas federadas / linked tables

DRDA (Distributed Relational Database Architecture) permite que un IBM i acceda a tablas de otro IBM i o de otros motores de base de datos como si fueran locales. Es el equivalente a foreign data wrappers en PostgreSQL o linked servers en SQL Server.

SQL -- Acceder a tablas remotas con CONNECT/DRDA
-- Conectar a otro sistema IBM i via DRDA
CONNECT TO SYSDR;

-- Consultar tabla remota
SELECT * FROM REMOTELIB.CLIENTES
WHERE REGION = 'NORTE';

-- Desconectar
DISCONNECT SYSDR;

-- Three-part naming (sin CONNECT explicito)
-- Requiere configuracion previa en WRKRDBDIRE
SELECT *
FROM SYSDR.REMOTELIB.CLIENTES
WHERE ESTADO = 'A';

-- Copiar datos entre sistemas
INSERT INTO MILIB.CLIENTES_COPIA
  SELECT * FROM SYSDR.REMOTELIB.CLIENTES
  WHERE FECHA_ALTA > '2025-01-01';
CL -- Configurar entrada RDB para DRDA
/* Agregar entrada de remote database */
ADDRDBDIRE RDB(SYSDR) +
           RMTLOCNAME('10.1.1.50' *IP) +
           PORT(446) +
           TEXT('Sistema DR en datacenter B')

/* Verificar conexion */
WRKRDBDIRE

/* Probar conectividad */
STRSQL
CONNECT TO SYSDR USER MIUSUARIO USING 'mipassword'
Three-part naming: La sintaxis RDB.SCHEMA.TABLA permite acceder a tablas remotas sin ejecutar CONNECT explicito. Es mas simple para queries puntuales pero menos eficiente que una sesion DRDA dedicada para multiples operaciones.

Seguridad de conexiones

Las conexiones externas a IBM i deben estar protegidas con SSL/TLS para cifrar el trafico de red, y controladas con exit programs y politicas de autoridad.

SSL/TLS

Cifra todo el trafico entre cliente y servidor. Se configura en DCM (Digital Certificate Manager) del IBM i. Usa port 449 (DRDA over SSL).

Exit Programs

Programas que se ejecutan en el IBM i cuando un usuario se conecta. Permiten validar, logear y denegar conexiones segun reglas custom.

Kerberos / SSO

Integracion con Active Directory para single sign-on. Evita manejar passwords en connection strings.

Connection profiles

Perfiles especificos para conexiones externas con autoridades limitadas. Nunca usar QSECOFR para conexiones de aplicacion.

Config -- Connection strings con SSL
# JDBC con SSL
jdbc:as400://IBMI_HOST/MILIB;
  secure=true;
  naming=sql;
  date format=iso

# ODBC con SSL
Driver={IBM i Access ODBC Driver};
System=IBMI_HOST;
SSL=1;
DefaultLibraries=MILIB;
Naming=0;
CCSID=1208;

# .NET con SSL
DataSource=IBMI_HOST;
DefaultCollection=MILIB;
SSL=true;
Naming=sql;
SQL -- Monitorear conexiones activas
-- Ver conexiones activas al IBM i
SELECT
  JOB_NAME,
  AUTHORIZATION_NAME AS USUARIO,
  CLIENT_IP_ADDRESS AS IP_CLIENTE,
  FUNCTION_TYPE,
  JOB_STATUS,
  ELAPSED_CPU_PERCENTAGE AS CPU_PCT
FROM TABLE(QSYS2.ACTIVE_JOB_INFO(
  SUBSYSTEM_LIST_FILTER => 'QUSRWRK',
  DETAILED_INFO => 'ALL'
)) AS j
WHERE FUNCTION_TYPE = 'DATABASE'
ORDER BY ELAPSED_CPU_PERCENTAGE DESC;

-- Conexiones DRDA activas
SELECT
  JOB_NAME, AUTHORIZATION_NAME,
  CLIENT_IP_ADDRESS,
  FUNCTION AS PROGRAMA,
  SQL_STATEMENT_STATUS
FROM TABLE(QSYS2.ACTIVE_JOB_INFO(
  SUBSYSTEM_LIST_FILTER => 'QSERVER',
  DETAILED_INFO => 'ALL'
)) AS j
WHERE JOB_TYPE = 'SBS'
ORDER BY JOB_NAME;
Seguridad critica: Nunca almacenes passwords en texto plano en connection strings de archivos de configuracion. Usa secrets managers (Vault, AWS Secrets Manager, Azure Key Vault) o variables de entorno protegidas. En IBM i, nunca uses el perfil QSECOFR para conexiones de aplicacion; crea perfiles dedicados con los permisos minimos necesarios.