SlideShare una empresa de Scribd logo
1 de 35
Descargar para leer sin conexión
Álvaro Rodríguez
@alvrod
PayTrue
Características generales de C#
Ejemplos comparados
Observaciones
var zero = 0;
var numbers = new[] {1, 2, 3, 4};
numbers.Select(x => x / zero).ToList();
Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero.
at Test.Application.<>c__DisplayClass3.<Main>b__2(Int32 x) in F:Visual Studio
ProjectsScalaVsCsProgram.cs:line 21
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Test.Application.Main() in F:Visual Studio ProjectsScalaVsCsProgram.cs:line 21
wat
 Scala
 C#
def upperCase(args: Array[String]) {
val res = for (a <- args) yield a.toUpperCase
println("Arguments: " + res.mkString)
}
…
upperCase(Array ("a", "b", "c"))
public static void UpperCase(string[] args) {
var res = from arg in args select arg.ToUpperInvariant();
Console.Out.WriteLine("Arguments: {0}", String.Join("", res));
}
…
UpperCase(new []{"a", "b", "c"});
 Scala
 C#
def upperCase(args: Array[String]) {
val res = for (a <- args) yield a.toUpperCase
println("Arguments: " + res.mkString)
}
…
upperCase(Array ("a", "b", "c"))
public static IEnumerable<string> UpperCaseYield(string[] args) {
foreach (var arg in args) {
yield return arg.ToUpperInvariant();
}
}
object implicits {
implicit def arrayWrapper[A : ClassTag](x: Array[A]) =
new {
def sort(p: (A, A) => Boolean) = {
util.Sorting.stableSort(x, p); x
}
}
}
import implicits._
…
 Scala
val numbers = Array(2, 3, 1, 4)
numbers.sort((x: Int, y: Int) => x < y))
 C#
public static class implicits {
public static IList<T> MySort<T>(this IList<T> list, Func<T, T, int> func)
where T : class {
var temp = list.ToArray();
Array.Sort(temp, (x, y) => func(x, y));
return temp;
}
}
var objects = new[] {"a", "b", "c"};
objects.MySort(String.CompareOrdinal);
 Pattern matching
 Inmutabilidad
 Inferencia de tipos
 Locuacidad (DSL)
 Expressions everywhere
 Option > null, Nullable<T>
 trait >>>> interface
 case class > auto-properties
 macros / compiler-as-a-service > roslyn
 Automatic Resource Management
 Scala, a través de librerías
 C#, magia en el compilador
 Debatible
 Madurez
 dynamic
 async / await
 Código nativo
 Xamarin
 JVM
 Scala
 CLR
 C# tiene bastantes cosas, aunque a veces la
sintaxis no es la mejor
 F#
 “Scala feels closer to Java than F# to C#”
 Java-----C#-------Scala-------------------F#
let zero = 0
let numbers = [| 1; 2; 3 |]
Seq.map(fun x -> x / zero) numbers |> Seq.length
System.DivideByZeroException: Attempted to divide by zero.
at FSI_0002.it@7-1.Invoke(Int32 x) <- wat
at Microsoft.FSharp.Collections.IEnumerator.map@116.DoMoveNext(b& )
at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator-
MoveNext()
at Microsoft.FSharp.Collections.SeqModule.Length[T](IEnumerable`1 source)
at <StartupCode$FSI_0002>.$FSI_0002.main@()
at main@dm()
Stopped due to error
Una breve introducción a la industria de tarjetas de crédito
Por qué el proyecto vale la pena
Visión funcional de la aplicación
 MasterCard, VISA, American Express
 Esquema descentralizado de
cobertura mundial
 Iniciativas para nuevos negocios,
control de fraude
 Chip & PIN (EMV), “Verified By Visa”,
etc.
 PCI Council
 PCI DSS
 Data Security Standard
 Aplicable a ambientes productivos
 PA DSS
 Aplicable a aplicaciones de pagos
Estándares de seguridad para proteger información
sensible de tarjetas y prevenir fraude
Obligatorios para proveedores de servicio, comercios, etc.
Apuntan a impedir el acceso pero también a desvalorizar la información
 Nº de tarjeta, tracks, PIN, en claro,
“por todos lados”
CRM, contabilidad, facturación, etc.
etc.
 Sistemas no preparados para cumplir
con la norma PCI DSS
 Enorme costo de adaptación
 La norma en sí es cara y difícil de
cumplir
El estándar tiene más de 260 requisitos individuales,
afectando desde políticas de RRHH hasta el control de
qué servicios se ejecutan en cada computadora dentro
del “ambiente de tarjetas PCI”
 Análisis GAP: 2 meses
 Proyecto PCI: 7 meses
 Certificación / ajustes: 2 meses
 ~2 millones U$S
+
 200.000 – 500.000+ U$S / año
en auditorías
Cada módulo de software que deba certificarse tiene un sobrecosto enorme por los
requisitos técnicos.
 Documentación
 Detalles de logging, seguridad, estándares
 Evidencia de procesos de desarrollo seguro, etc.
 Criptografía -> gestión de claves
PCI aplica sólo a “sistemas que
almacenan, procesan o transmiten el nº
de tarjeta”
La forma más fácil de “certificar PCI”
entonces es evitar almacenar, procesar
o transmitir el nº de tarjeta
SecureTX es PA-DSS, el resto queda
fuera de la norma
Estrategia de reducción del alcance a
través de tokenización
def tokenize(card:String): String
5588 3201 2345 6789
->
1000 0000 4365 6789
Desarrollo de middleware tokenizador
“Secure TX”
Diseño con Akka
Implementación
Observaciones. Discusión.
 “Tokenizer”
es un servicio web aparte
 “SecureTX switch”
es la aplicación que estamos
discutiendo
 “Authorizer / switch”
podría ser un procesador de pagos
cualquiera
 El esquema de la derecha es minimal,
se dan escenarios más complejos
Transaction
storage
Authorizer /
switch
SecureTX
switch
SecureTX
tokenizer
Encrypted card
storage
TX
1
2
34
5
 Producto caja, cerrado
 Distintos canales
 TCP
 JMS
 Distintos formatos
 ISO 8583 en distintos sabores
 ASCII largo fijo
 Distintos flujos
 Camino crítico transaccional
 Estabilidad
 Performance
 Akka
 Librería y runtime para desarrollar
aplicaciones para la JVM
 Altamente concurrentes
 Distribuidas
 Con tolerancia a fallas
 Orientadas a eventos asincrónicos
 Modelo de actores
 Cada actor tiene un mailbox de eventos:
mensajes que procesa secuencialmente
 Modelo de ejecución simplificado, fácil
de entender y evitar problemas típicos
de concurrencia
 Modelo de supervisión para tolerancia a
fallas
 Meta-actores (p.e. para distribución de
carga)
 Librería para integración de mensajes
 “Todos con todos” de canales x
formatos
 Canales: JMS, Archivos, HTTP, … …
 Formatos: Largo fijo, CSV, XML, JSON,
etc.
 Muy configurable mediante Spring
 Rutas, endpoints, etc.
 EAI patterns en código o XML
 Akka – Camel integra ambas librerías
SecureTX "Switch"
Switch
Tokenizer
PaymentProcessorSender
PaymentProcessorReceiver
ManagementReceiver
ManagementSender
TcpServerA
TcpServerB
TcpClientD
HSM
Tokenizer Service
Authorizer
HSM Server
POS Network
E Gateway
VISA
MasterCard
TcpClientE
 TCP, HSM – Akka.IO 2.2 en Scala
 Precisamos full-duplex asincrónico, y Camel es one-way o request-reply
 Binario + ISO8583 o “ASCII largo fijo” configurable
 Tokenizer, PaymentProcessor, Management
 Camel
 En principio:
 Tokenizer por HTTP4
 PaymentProcessor, Management por JMS
 Pero parte de la gracia de Camel es que esto es muy configurable
class Tokenizer extends Actor with Producer with akka.actor.ActorLogging {
val config = SwApp.appConfigContext.getBean(self.path.name).asInstanceOf[TokenizerBean]
val contextHeader = "TOKENIZER_CONTEXT"
val cardIdResource = "cardid"
val cardNumberResource = "cardnumber"
def endpointUri: String = s"http4://${config.host}:${config.port}"
override def transformOutgoingMessage(msg: Any) = msg match {
case TokenizeRequest(cardNumber, senderContext) => CreateCamelMessage(cardIdResource, cardNumber, senderContext)
case OpenCardRequest(token, senderContext) => CreateCamelMessage(cardNumberResource, token, senderContext)
}
private def CreateCamelMessage(resource:String, data:String, senderContext:Any) = {
val headers = Map(
Exchange.HTTP_URI -> s"$endpointUri/$resource/$data",
Exchange.HTTP_METHOD -> "GET",
contextHeader -> senderContext
)
CamelMessage("", headers)
}
override def transformResponse(msg: Any) = msg match {
case msg: CamelMessage => msg.headerAs[String](Exchange.HTTP_URI) match {
case Success(cardId) if cardId.contains(cardIdResource) => TokenizeResponse(msg.bodyAs[String], msg.headers(contextHeader))
case Success(cardNumber) if cardNumber.contains(cardNumberResource) => OpenCardResponse(msg.bodyAs[String], msg.headers(contextHeader))
case Success(other) => log.error("Unexpected response {} from Tokenizer", other)
case Failure(e) => log.error(e, "Error received from Tokenizer")
}
case akka.actor.Status.Failure(e) => log.error(e, "Error received from Tokenizer")
}
}
 2200 LOC Scala
 promedio 100 por archivo
 1000 LOC Java (HSM)
 promedio 145 por archivo
 .jar 300 kb
 lib 22 mb
“If I have seen further it is by standing on the shoulders of giants”
 akka-testkit
 ScalaTest
 TeamCity no sabe ejecutar tests de
Scala 
http://youtrack.jetbrains.com/issue/TW-
29678
 JMeter
 En condiciones preliminares e
imperfectas
 Ambiente local + Oracle de desarrollo
 Flujo simplificado
 “Enviando” las transacciones a log por
Camel (sin JMS)
 Todo con la misma tarjeta
 ~100 tps
 A través del “ManagementReceiver”
podemos dinámicamente configurar,
bajar, reiniciar canales.
 Trivial de hacer con Akka
 Metrics de @coda
 Además enviamos status a través del
"ManagementSender"
Una introducción a la arquitectura de seguridad de tarjetas de crédito con Akka y Scala

Más contenido relacionado

La actualidad más candente

P R A C T I C A2
P R A C T I C A2P R A C T I C A2
P R A C T I C A2climancc
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAVíctor Bolinches
 
Analizador de una matriz utilizando compiladores
Analizador de una matriz utilizando compiladoresAnalizador de una matriz utilizando compiladores
Analizador de una matriz utilizando compiladoresChristian Lara
 
Ejercicios en Netbeans
Ejercicios en NetbeansEjercicios en Netbeans
Ejercicios en Netbeansedgar muñoz
 
José Ramón Palanco - NoSQL Security [RootedCON 2011]
José Ramón Palanco - NoSQL Security [RootedCON 2011]José Ramón Palanco - NoSQL Security [RootedCON 2011]
José Ramón Palanco - NoSQL Security [RootedCON 2011]RootedCON
 
08 strings o cadenas
08 strings o cadenas08 strings o cadenas
08 strings o cadenashorusblom
 
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantino
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantinoAlgoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantino
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantinoJohn Nelson Rojas
 
Ejemplos Para Dev C++
Ejemplos Para Dev C++Ejemplos Para Dev C++
Ejemplos Para Dev C++cemayoral
 
Programación en OTcl
Programación en OTclProgramación en OTcl
Programación en OTclJesus Vilchez
 
Practicas en matlab
Practicas en matlabPracticas en matlab
Practicas en matlabbachispasaca
 
Codificaciones c++
Codificaciones c++Codificaciones c++
Codificaciones c++mario_10
 
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...RootedCON
 

La actualidad más candente (20)

P R A C T I C A2
P R A C T I C A2P R A C T I C A2
P R A C T I C A2
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
 
Lecture 37
Lecture 37Lecture 37
Lecture 37
 
Analizador de una matriz utilizando compiladores
Analizador de una matriz utilizando compiladoresAnalizador de una matriz utilizando compiladores
Analizador de una matriz utilizando compiladores
 
Ejercicios en Netbeans
Ejercicios en NetbeansEjercicios en Netbeans
Ejercicios en Netbeans
 
Algoritmos para c#
Algoritmos para c#Algoritmos para c#
Algoritmos para c#
 
José Ramón Palanco - NoSQL Security [RootedCON 2011]
José Ramón Palanco - NoSQL Security [RootedCON 2011]José Ramón Palanco - NoSQL Security [RootedCON 2011]
José Ramón Palanco - NoSQL Security [RootedCON 2011]
 
08 strings o cadenas
08 strings o cadenas08 strings o cadenas
08 strings o cadenas
 
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantino
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantinoAlgoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantino
Algoritmos distribuidos bully o abusón, ronda,anillo o ring, bizantino
 
Ejemplos Para Dev C++
Ejemplos Para Dev C++Ejemplos Para Dev C++
Ejemplos Para Dev C++
 
Programación en OTcl
Programación en OTclProgramación en OTcl
Programación en OTcl
 
Tutorial c++
Tutorial c++Tutorial c++
Tutorial c++
 
Practicas en matlab
Practicas en matlabPracticas en matlab
Practicas en matlab
 
Reporte viernes 24
Reporte viernes 24Reporte viernes 24
Reporte viernes 24
 
Seguridad En Programación
Seguridad En ProgramaciónSeguridad En Programación
Seguridad En Programación
 
Codificaciones c++
Codificaciones c++Codificaciones c++
Codificaciones c++
 
Awt
AwtAwt
Awt
 
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...
Jaime Peñalba - Como defenderse en terreno hostil: Protecciones para la Defco...
 
Programas en netbeans
Programas en netbeansProgramas en netbeans
Programas en netbeans
 
MODELO PASO DE MENSAJES
MODELO PASO DE MENSAJESMODELO PASO DE MENSAJES
MODELO PASO DE MENSAJES
 

Similar a Una introducción a la arquitectura de seguridad de tarjetas de crédito con Akka y Scala

Lw2010 Pedro Valera
Lw2010 Pedro ValeraLw2010 Pedro Valera
Lw2010 Pedro Valeraguestf280e2
 
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En Redes
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En RedesLw2010 - Uso De La Programacion En Linux Para La Seguridad En Redes
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En Redesguest5d7f33c
 
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)Victor Asanza
 
37 supervisión del sistema
37  supervisión del sistema37  supervisión del sistema
37 supervisión del sistemaAprende Viendo
 
Scapy. Generación y manipulación básica de paquetes de red
Scapy. Generación y manipulación básica de paquetes de redScapy. Generación y manipulación básica de paquetes de red
Scapy. Generación y manipulación básica de paquetes de redDavid Cristóbal
 
Curso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpCurso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpEdgar Solis
 
Anatomía de un ataque a tns listener
Anatomía de un ataque a tns listenerAnatomía de un ataque a tns listener
Anatomía de un ataque a tns listeneryt f
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttlingGeneXus
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttlingGeneXus
 
Programación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions NavisionProgramación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions Navisionpabloesp
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túAgile Spain
 
Por qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túPor qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túJavier Acero
 

Similar a Una introducción a la arquitectura de seguridad de tarjetas de crédito con Akka y Scala (20)

Manual tecnico
Manual tecnicoManual tecnico
Manual tecnico
 
Lw2010 Pedro Valera
Lw2010 Pedro ValeraLw2010 Pedro Valera
Lw2010 Pedro Valera
 
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En Redes
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En RedesLw2010 - Uso De La Programacion En Linux Para La Seguridad En Redes
Lw2010 - Uso De La Programacion En Linux Para La Seguridad En Redes
 
Aplicación Cliente - Servidor / GUI - Consola
Aplicación Cliente - Servidor / GUI - ConsolaAplicación Cliente - Servidor / GUI - Consola
Aplicación Cliente - Servidor / GUI - Consola
 
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)
⭐⭐⭐⭐⭐ SOLUCIÓN LECCIÓN SISTEMAS EMBEBIDOS, 2do Parcial (2020 PAO 1)
 
Perceptron multicapa
Perceptron multicapa Perceptron multicapa
Perceptron multicapa
 
Crack Distribuido Atabuido
Crack Distribuido AtabuidoCrack Distribuido Atabuido
Crack Distribuido Atabuido
 
Crack Distribuido Atabuido
Crack Distribuido AtabuidoCrack Distribuido Atabuido
Crack Distribuido Atabuido
 
37 supervisión del sistema
37  supervisión del sistema37  supervisión del sistema
37 supervisión del sistema
 
Semana 1 Estructuras de Control en Java
Semana 1   Estructuras de Control en JavaSemana 1   Estructuras de Control en Java
Semana 1 Estructuras de Control en Java
 
6.funciones y recursividad en c++
6.funciones y recursividad en c++6.funciones y recursividad en c++
6.funciones y recursividad en c++
 
Scapy. Generación y manipulación básica de paquetes de red
Scapy. Generación y manipulación básica de paquetes de redScapy. Generación y manipulación básica de paquetes de red
Scapy. Generación y manipulación básica de paquetes de red
 
Curso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmpCurso migración de aplicaciones nsl nk90 a tmp
Curso migración de aplicaciones nsl nk90 a tmp
 
Anatomía de un ataque a tns listener
Anatomía de un ataque a tns listenerAnatomía de un ataque a tns listener
Anatomía de un ataque a tns listener
 
Viernes Tecnicos DTrace
Viernes Tecnicos DTraceViernes Tecnicos DTrace
Viernes Tecnicos DTrace
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttling
 
0157 genexus full_throttling
0157 genexus full_throttling0157 genexus full_throttling
0157 genexus full_throttling
 
Programación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions NavisionProgramación con C/AL para Microsoft Business Solutions Navision
Programación con C/AL para Microsoft Business Solutions Navision
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que tú
 
Por qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túPor qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que tú
 

Una introducción a la arquitectura de seguridad de tarjetas de crédito con Akka y Scala

  • 2. Características generales de C# Ejemplos comparados Observaciones
  • 3. var zero = 0; var numbers = new[] {1, 2, 3, 4}; numbers.Select(x => x / zero).ToList(); Unhandled Exception: System.DivideByZeroException: Attempted to divide by zero. at Test.Application.<>c__DisplayClass3.<Main>b__2(Int32 x) in F:Visual Studio ProjectsScalaVsCsProgram.cs:line 21 at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext() at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) at Test.Application.Main() in F:Visual Studio ProjectsScalaVsCsProgram.cs:line 21 wat
  • 4.  Scala  C# def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCase println("Arguments: " + res.mkString) } … upperCase(Array ("a", "b", "c")) public static void UpperCase(string[] args) { var res = from arg in args select arg.ToUpperInvariant(); Console.Out.WriteLine("Arguments: {0}", String.Join("", res)); } … UpperCase(new []{"a", "b", "c"});
  • 5.  Scala  C# def upperCase(args: Array[String]) { val res = for (a <- args) yield a.toUpperCase println("Arguments: " + res.mkString) } … upperCase(Array ("a", "b", "c")) public static IEnumerable<string> UpperCaseYield(string[] args) { foreach (var arg in args) { yield return arg.ToUpperInvariant(); } }
  • 6. object implicits { implicit def arrayWrapper[A : ClassTag](x: Array[A]) = new { def sort(p: (A, A) => Boolean) = { util.Sorting.stableSort(x, p); x } } } import implicits._ …  Scala val numbers = Array(2, 3, 1, 4) numbers.sort((x: Int, y: Int) => x < y))
  • 7.  C# public static class implicits { public static IList<T> MySort<T>(this IList<T> list, Func<T, T, int> func) where T : class { var temp = list.ToArray(); Array.Sort(temp, (x, y) => func(x, y)); return temp; } } var objects = new[] {"a", "b", "c"}; objects.MySort(String.CompareOrdinal);
  • 8.  Pattern matching  Inmutabilidad  Inferencia de tipos  Locuacidad (DSL)  Expressions everywhere  Option > null, Nullable<T>  trait >>>> interface  case class > auto-properties  macros / compiler-as-a-service > roslyn
  • 9.  Automatic Resource Management  Scala, a través de librerías  C#, magia en el compilador  Debatible  Madurez  dynamic  async / await  Código nativo  Xamarin
  • 10.  JVM  Scala  CLR  C# tiene bastantes cosas, aunque a veces la sintaxis no es la mejor  F#  “Scala feels closer to Java than F# to C#”  Java-----C#-------Scala-------------------F#
  • 11. let zero = 0 let numbers = [| 1; 2; 3 |] Seq.map(fun x -> x / zero) numbers |> Seq.length System.DivideByZeroException: Attempted to divide by zero. at FSI_0002.it@7-1.Invoke(Int32 x) <- wat at Microsoft.FSharp.Collections.IEnumerator.map@116.DoMoveNext(b& ) at Microsoft.FSharp.Collections.IEnumerator.MapEnumerator`1.System-Collections-IEnumerator- MoveNext() at Microsoft.FSharp.Collections.SeqModule.Length[T](IEnumerable`1 source) at <StartupCode$FSI_0002>.$FSI_0002.main@() at main@dm() Stopped due to error
  • 12. Una breve introducción a la industria de tarjetas de crédito Por qué el proyecto vale la pena Visión funcional de la aplicación
  • 13.  MasterCard, VISA, American Express  Esquema descentralizado de cobertura mundial  Iniciativas para nuevos negocios, control de fraude  Chip & PIN (EMV), “Verified By Visa”, etc.  PCI Council  PCI DSS  Data Security Standard  Aplicable a ambientes productivos  PA DSS  Aplicable a aplicaciones de pagos
  • 14.
  • 15. Estándares de seguridad para proteger información sensible de tarjetas y prevenir fraude Obligatorios para proveedores de servicio, comercios, etc. Apuntan a impedir el acceso pero también a desvalorizar la información
  • 16.
  • 17.  Nº de tarjeta, tracks, PIN, en claro, “por todos lados” CRM, contabilidad, facturación, etc. etc.  Sistemas no preparados para cumplir con la norma PCI DSS  Enorme costo de adaptación  La norma en sí es cara y difícil de cumplir
  • 18. El estándar tiene más de 260 requisitos individuales, afectando desde políticas de RRHH hasta el control de qué servicios se ejecutan en cada computadora dentro del “ambiente de tarjetas PCI”  Análisis GAP: 2 meses  Proyecto PCI: 7 meses  Certificación / ajustes: 2 meses  ~2 millones U$S +  200.000 – 500.000+ U$S / año en auditorías
  • 19. Cada módulo de software que deba certificarse tiene un sobrecosto enorme por los requisitos técnicos.  Documentación  Detalles de logging, seguridad, estándares  Evidencia de procesos de desarrollo seguro, etc.  Criptografía -> gestión de claves
  • 20.
  • 21. PCI aplica sólo a “sistemas que almacenan, procesan o transmiten el nº de tarjeta” La forma más fácil de “certificar PCI” entonces es evitar almacenar, procesar o transmitir el nº de tarjeta SecureTX es PA-DSS, el resto queda fuera de la norma
  • 22. Estrategia de reducción del alcance a través de tokenización def tokenize(card:String): String 5588 3201 2345 6789 -> 1000 0000 4365 6789 Desarrollo de middleware tokenizador “Secure TX”
  • 24.  “Tokenizer” es un servicio web aparte  “SecureTX switch” es la aplicación que estamos discutiendo  “Authorizer / switch” podría ser un procesador de pagos cualquiera  El esquema de la derecha es minimal, se dan escenarios más complejos Transaction storage Authorizer / switch SecureTX switch SecureTX tokenizer Encrypted card storage TX 1 2 34 5
  • 25.  Producto caja, cerrado  Distintos canales  TCP  JMS  Distintos formatos  ISO 8583 en distintos sabores  ASCII largo fijo  Distintos flujos  Camino crítico transaccional  Estabilidad  Performance
  • 26.  Akka  Librería y runtime para desarrollar aplicaciones para la JVM  Altamente concurrentes  Distribuidas  Con tolerancia a fallas  Orientadas a eventos asincrónicos  Modelo de actores  Cada actor tiene un mailbox de eventos: mensajes que procesa secuencialmente  Modelo de ejecución simplificado, fácil de entender y evitar problemas típicos de concurrencia  Modelo de supervisión para tolerancia a fallas  Meta-actores (p.e. para distribución de carga)
  • 27.  Librería para integración de mensajes  “Todos con todos” de canales x formatos  Canales: JMS, Archivos, HTTP, … …  Formatos: Largo fijo, CSV, XML, JSON, etc.  Muy configurable mediante Spring  Rutas, endpoints, etc.  EAI patterns en código o XML  Akka – Camel integra ambas librerías
  • 29.  TCP, HSM – Akka.IO 2.2 en Scala  Precisamos full-duplex asincrónico, y Camel es one-way o request-reply  Binario + ISO8583 o “ASCII largo fijo” configurable  Tokenizer, PaymentProcessor, Management  Camel  En principio:  Tokenizer por HTTP4  PaymentProcessor, Management por JMS  Pero parte de la gracia de Camel es que esto es muy configurable
  • 30. class Tokenizer extends Actor with Producer with akka.actor.ActorLogging { val config = SwApp.appConfigContext.getBean(self.path.name).asInstanceOf[TokenizerBean] val contextHeader = "TOKENIZER_CONTEXT" val cardIdResource = "cardid" val cardNumberResource = "cardnumber" def endpointUri: String = s"http4://${config.host}:${config.port}" override def transformOutgoingMessage(msg: Any) = msg match { case TokenizeRequest(cardNumber, senderContext) => CreateCamelMessage(cardIdResource, cardNumber, senderContext) case OpenCardRequest(token, senderContext) => CreateCamelMessage(cardNumberResource, token, senderContext) } private def CreateCamelMessage(resource:String, data:String, senderContext:Any) = { val headers = Map( Exchange.HTTP_URI -> s"$endpointUri/$resource/$data", Exchange.HTTP_METHOD -> "GET", contextHeader -> senderContext ) CamelMessage("", headers) } override def transformResponse(msg: Any) = msg match { case msg: CamelMessage => msg.headerAs[String](Exchange.HTTP_URI) match { case Success(cardId) if cardId.contains(cardIdResource) => TokenizeResponse(msg.bodyAs[String], msg.headers(contextHeader)) case Success(cardNumber) if cardNumber.contains(cardNumberResource) => OpenCardResponse(msg.bodyAs[String], msg.headers(contextHeader)) case Success(other) => log.error("Unexpected response {} from Tokenizer", other) case Failure(e) => log.error(e, "Error received from Tokenizer") } case akka.actor.Status.Failure(e) => log.error(e, "Error received from Tokenizer") } }
  • 31.  2200 LOC Scala  promedio 100 por archivo  1000 LOC Java (HSM)  promedio 145 por archivo  .jar 300 kb  lib 22 mb “If I have seen further it is by standing on the shoulders of giants”
  • 32.  akka-testkit  ScalaTest  TeamCity no sabe ejecutar tests de Scala  http://youtrack.jetbrains.com/issue/TW- 29678
  • 33.  JMeter  En condiciones preliminares e imperfectas  Ambiente local + Oracle de desarrollo  Flujo simplificado  “Enviando” las transacciones a log por Camel (sin JMS)  Todo con la misma tarjeta  ~100 tps
  • 34.  A través del “ManagementReceiver” podemos dinámicamente configurar, bajar, reiniciar canales.  Trivial de hacer con Akka  Metrics de @coda  Además enviamos status a través del "ManagementSender"