CarneiroTech/Content/Cases/es/asp-to-dotnet-migration.md

330 lines
10 KiB
Markdown

---
title: "Migración ASP 3.0 a .NET Core - Sistema de Rastreo de Cargas"
slug: "asp-to-dotnet-migration"
summary: "Tech Lead en la migración gradual de sistema crítico ASP 3.0 a .NET Core, con sincronización de datos entre versiones y reducción de costos de $20k/año en APIs de mapeo."
client: "Empresa de Logística y Rastreo"
industry: "Logística & Seguridad"
timeline: "12 meses (migración completa)"
role: "Tech Lead & Solution Architect"
image: ""
tags:
- ASP Classic
- .NET Core
- SQL Server
- Migration
- Tech Lead
- OSRM
- APIs
- Arquitectura
featured: true
order: 2
date: 2015-06-01
seo_title: "Migración ASP 3.0 a .NET Core - Case Carneiro Tech"
seo_description: "Caso de migración gradual de aplicación ASP 3.0 a .NET Core con sincronización de datos y reducción de $20k/año en costos de APIs."
seo_keywords: "ASP migration, .NET Core, legacy modernization, SQL Server, OSRM, tech lead, routing API"
---
## Descripción General
Sistema crítico de monitoreo de cargas de alto valor (TVs LED de $600 cada una, cargamentos de hasta 1000 unidades) utilizando rastreo GPS vía satélite. La aplicación cubría todo el ciclo: desde registro y evaluación de conductores (verificación de antecedentes policiales) hasta monitoreo en tiempo real y entrega final.
**Desafío principal:** Migrar aplicación legacy ASP 3.0 a .NET Core sin downtime, manteniendo operación crítica 24/7.
---
## Desafío
### Sistema Legacy Crítico
La empresa operaba un sistema mission-critical en **ASP 3.0** (Classic ASP) que no podía detenerse:
**Tecnología legacy:**
- ASP 3.0 (tecnología de 1998)
- SQL Server 2005
- Cluster failover on-premises (perfectamente capaz de soportar la carga)
- Integración con rastreadores GPS vía satélite
- Google Maps API (costo: **$20,000/año** solo para cálculo de rutas)
**Restricciones:**
- Sistema operando 24/7 con cargas de alto valor
- Imposibilidad de downtime durante migración
- Múltiples módulos interdependientes
- Equipo necesitaba continuar desarrollando features durante la migración
---
## Arquitectura de Solución
### Fase 1: Preparación de Infraestructura (Meses 1-3)
#### Upgrade de Base de Datos
```
SQL Server 2005 → SQL Server 2014
- Backup completo y validación
- Migración de stored procedures
- Optimización de índices
- Pruebas de performance
```
#### Estrategia de Sincronización Dual-Write
Implementé un **sistema de sincronización bidireccional** que permitía:
1. **Módulos nuevos (.NET Core)** escribían en la base de datos nueva
2. **Trigger automático** sincronizaba datos hacia la base de datos legacy
3. **Módulos antiguos (ASP 3.0)** continuaban funcionando normalmente
4. **Zero downtime** durante toda la migración
```csharp
// Ejemplo de sincronización implementada
public class DualWriteService
{
public async Task SaveDriver(Driver driver)
{
// Escribe en base de datos nueva (.NET Core)
await _newDbContext.Drivers.AddAsync(driver);
await _newDbContext.SaveChangesAsync();
// Trigger SQL sincroniza automáticamente hacia base de datos legacy
// Módulos ASP 3.0 continúan funcionando
}
}
```
**¿Por qué este enfoque?**
- Permitió migración **módulo por módulo**
- Equipo podía continuar desarrollando
- Rollback sencillo si fuera necesario
- Reducción de riesgo operacional
---
### Fase 2: Migración Gradual de Módulos (Meses 4-12)
Migré los módulos en orden de complejidad creciente:
**Orden de migración:**
1. ✅ Registros básicos (conductores, vehículos)
2. ✅ Evaluación de riesgo (integración con base policial)
3. ✅ Gestión de cargas y rutas
4. ✅ Monitoreo GPS en tiempo real
5. ✅ Alertas y notificaciones
6. ✅ Reportes y analytics
**Stack de la aplicación migrada:**
- `.NET Core 1.0` (2015-2016 era el inicio de .NET Core)
- `Entity Framework Core`
- `SignalR` para monitoreo real-time
- `SQL Server 2014`
- APIs RESTful
---
### Fase 3: Reducción de Costos con OSRM (Ahorro de $20k/año)
#### Problema: Costo Prohibitivo de Google Maps
La empresa gastaba **$20,000/año** solo en Google Maps Directions API para cálculo de rutas de camiones.
#### Solución: OSRM (Open Source Routing Machine)
Implementé una solución basada en **OSRM** (motor de ruteo open-source):
**Arquitectura de la solución:**
```
┌─────────────────┐
│ Frontend │
│ (Leaflet.js) │
└────────┬────────┘
┌─────────────────┐ ┌──────────────┐
│ API Wrapper │─────▶│ OSRM Server │
│ (.NET Core) │ │ (self-hosted)│
└────────┬────────┘ └──────────────┘
┌─────────────────┐
│ Google Maps │
│ (display only) │
└─────────────────┘
```
**Implementación:**
1. **Servidor OSRM configurado** en servidor propio
2. **API wrapper amigable** en .NET Core que:
- Recibía origen/destino
- Consultaba OSRM (gratuito)
- Devolvía todos los puntos de la ruta
- Formateaba para el frontend
3. **Frontend** dibujaba la ruta en Google Maps (solo visualización, sin API de rutas)
```csharp
[HttpGet("route")]
public async Task<IActionResult> GetRoute(double originLat, double originLng,
double destLat, double destLng)
{
// Consulta OSRM (gratuito)
var osrmResponse = await _osrmClient.GetRouteAsync(
originLat, originLng, destLat, destLng);
// Retorna puntos formateados para el frontend
return Ok(new {
points = osrmResponse.Routes[0].Geometry.Coordinates,
distance = osrmResponse.Routes[0].Distance,
duration = osrmResponse.Routes[0].Duration
});
}
```
**Frontend con Leaflet:**
```javascript
// Dibuja ruta en el mapa (Google Maps solo para tiles)
L.polyline(routePoints, {color: 'red'}).addTo(map);
```
#### Intento con OpenStreetMap
Intenté sustituir también Google Maps (tiles) por **OpenStreetMap**, que funcionó técnicamente, pero:
**A los usuarios no les gustó** la apariencia
❌ Preferían la interfaz familiar de Google Maps
**Decisión:** Mantener Google Maps solo para visualización (sin costo de API de rutas)
**Resultado:** Ahorro de **~$20,000/año** manteniendo calidad de las rutas.
---
## Resultados e Impacto
### Migración Completa en 12 Meses
**100% de los módulos** migrados de ASP 3.0 a .NET Core
**Zero downtime** durante toda la migración
**Equipo productivo** durante todo el proceso
✅ Sistema más rápido y escalable
### Reducción de Costos
💰 **$20,000/año ahorrados** con sustitución de Google Maps Directions API
📉 **Infraestructura optimizada** con SQL Server 2014
### Mejoras Técnicas
🚀 **Performance:** Aplicación .NET Core 3x más rápida que ASP 3.0
🔒 **Seguridad:** Stack moderno con parches de seguridad activos
🛠️ **Mantenibilidad:** Código C# moderno vs VBScript legacy
📊 **Monitoreo:** SignalR para tracking real-time más eficiente
---
## Fase No Ejecutada: Microservicios & Cloud
### Planificación Inicial
Participé en el **diseño y concepción** de la segunda fase (nunca ejecutada):
**Arquitectura planificada:**
- Migración a **Azure** (cloud estaba apenas comenzando en 2015)
- División en **microservicios**:
- Servicio de autenticación
- Servicio de GPS/tracking
- Servicio de rutas
- Servicio de notificaciones
- **Event-driven architecture** con message queues
**Por qué no fue ejecutada:**
Salí de la empresa inmediatamente después de concluir la migración a .NET Core. La segunda fase quedó planificada pero no fue implementada por mí.
---
## Tech Stack
`ASP 3.0` `VBScript` `.NET Core 1.0` `C#` `Entity Framework Core` `SQL Server 2005` `SQL Server 2014` `OSRM` `Leaflet.js` `Google Maps` `SignalR` `REST APIs` `GPS/Satellite` `Migration Strategy` `Dual-Write Pattern`
---
## Decisiones Clave & Trade-offs
### ¿Por qué sincronización dual-write?
**Alternativas consideradas:**
1. ❌ Big Bang migration (demasiado arriesgado)
2. ❌ Mantener todo en ASP 3.0 (insostenible)
3.**Migración gradual con sync** (elegido)
**Justificación:**
- Sistema crítico no podía detenerse
- Permitió rollback módulo por módulo
- Equipo continuó productivo
### ¿Por qué OSRM en vez de otros?
**Alternativas:**
- Google Maps: $20k/año ❌
- Mapbox: Licencia paga ❌
- GraphHopper: Configuración compleja ❌
- **OSRM: Open-source, rápido, configurable** ✅
### ¿Por qué no OpenStreetMap para tiles?
**Decisión basada en UX:**
- Técnicamente funcionó perfectamente
- Usuarios preferían interfaz familiar de Google
- **Compromiso:** Google Maps para visualización (gratis) + OSRM para rutas (gratis)
---
## Lecciones Aprendidas
### 1. Migración Gradual > Big Bang
Migrar módulo por módulo con sincronización permitió:
- Aprendizaje continuo
- Ajustes de ruta durante el proceso
- Confianza del equipo y stakeholders
### 2. Open Source Puede Ahorrar Mucho
OSRM ahorró **$20k/año** sin pérdida de calidad. Pero requiere:
- Expertise para configurar
- Infraestructura propia
- Mantenimiento continuo
### 3. UX > Tecnología A Veces
OpenStreetMap era técnicamente superior (gratuito), pero usuarios prefirieron Google Maps. **Lección:** Escuchar a los usuarios finales.
### 4. Planifique Cloud, pero Valide el ROI
En 2015, cloud estaba comenzando. La infraestructura on-premises (cluster SQL Server) era perfectamente capaz. **No fuerce cloud si no hay beneficio claro.**
---
## Contexto: Por qué 2015 fue un Momento Especial
**Estado de la tecnología en 2015:**
- ☁️ **Cloud en pañales:** AWS existía, Azure creciendo, pero adopción corporativa aún baja
- 🆕 **.NET Core 1.0 lanzado** en junio/2016 (usamos RC durante proyecto)
- 📱 **Microservicios:** Concepto nuevo, Docker en adopción inicial
- 🗺️ **Google Maps dominante:** APIs pagas, pocas alternativas open-source maduras
**Desafíos de la época:**
- Herramientas de migración ASP→.NET inexistentes
- Documentación .NET Core escasa (versión 1.0!)
- Patrones de arquitectura aún consolidándose
Este proyecto fue **pionero** al adoptar .NET Core al inicio, cuando la mayoría migraba a .NET Framework 4.x.
---
**Resultado:** Migración exitosa de sistema crítico 24/7, ahorro de $20k/año, y base sólida para evolución futura.
[¿Quiere discutir una migración similar? Póngase en contacto](#contact)