Translate

viernes, 19 de agosto de 2022

Cursos Gugler!!

 

 PRENSA GUGLER  LAB 2022

  NOTICIAS ACTUALES

informacion  OFERTA ACADÉMICA


Estimado Goette Emanuel :

 Se encuentran abiertas las inscripciones para el segundo cuatrimestre del año 2022, para todas las capacitaciones dictadas por el Laboratorio de Investigación Gugler. Podés asegurar tu lugar en el curso y comisión que desees !!!.

Las clases inician:

  • Martes 30/08 , Miércoles 31/08, Jueves 01/09 o Sábado 03/09, según el curso que elegiste

 

Inscribirteclic aquí

Cursos, Horarios y comisionesclic aquí.

 

 

Dictamos nuestros cursos en la Facultad de Ciencia y Tecnología, perteneciente a la Universidad Autónoma de Entre Ríos. En nuestro portafolio de capacitación encontrarás:

MODALIDAD PRESENCIAL

  • Cursos de Sistemas Operativos:
    Administración GNU/Linux.
     
  • Cursos de Programación:
    Programación en Python.
      
  • Cursos de Mantenimiento/Reparación:
    Reparación y Mantenimiento de PC.

 MODALIDAD DISTANCIA

  • Cursos de Programación:
    Programación en PHP.
    Programación en Java.
    Programación web frontend
informacion   MÁS INFORMACIÓN 

informacion LABORATORIO DE INVESTIGACIÓN GUGLER

Si deseas comunicarte con nosotros, te recordamos que podes hacerlo a través de los siguientes portales, en los cuales encontrarás información sobre Gugler.

TEL: (0343) - 4975066 Interno 119

Sitio Oficial:  www.gugler.com.ar

Campus:  campusvirtual.gugler.com.ar

Sistema de Gestión Cursos:  sgc.gugler.com.ar

Sistema de Gestión Cursos Móvil: Aquí 

Sistema de Documentación:  sgd.gugler.com.ar

Sistema de Validación:  giua.gugler.com.ar

                   Twitter                Facebook

Laboratorio Gugler

partir del 2012, la Facultad de Ciencia y Tecnología nos declaro:  "Laboratorio de Investigación".

 

El laboratorio ha ampliado las incumbencias de Gugler, ya que además de la capacitación, la promoción y difusión del software libre, ahora abarcará actividades como publicaciones y proyectos de investigación, así como también el dictado y participación en conferencias o exposiciones de ámbitos académicos y científicos.

 

Ante cualquier duda comunicarse con nosotros a gugler_contacto@uader.edu.ar

GUGLER PRESS

 

[O'Reilly eBook] The Enterprise Path to Service Mesh Architectures

 

 
 
 

Whether you’re preparing to build microservices-based, cloud-native applications, or looking to modernize your existing set of application services, you may want to consider using a service mesh. The more services your enterprise manages, the more intense any headaches you encounter are likely to be. This practical ebook explains how a service mesh provides a configurable infrastructure layer that makes service-to-service communication flexible, reliable, and fast.

Download this ebook to learn:

  • Service mesh concepts, architecture, and components, such as data planes and control planes
  • How a service mesh provides visibility, traffic management, resiliency, and security control for distributed application services, and the differences among service meshes and service mesh components
  • How service meshes compare to related technologies such as container orchestrators, API gateways, and client-side libraries
  • Practical steps for service mesh adoption, customization, deployment, and integration
 
 
 
Related Resources
 

What Is a Service Mesh?
A service mesh is a configurable infrastructure layer for microservices application that makes communication flexible, reliable, and fast. Learn more in this blog. 

 

NGINX, Istio, and the Move to Microservices and Service Mesh
This webinar discusses microservices architectures, and describes how NGINX is emerging as a widely used microservices hub, as a Kubernetes Ingress controller, and as a sidecar proxy in the Istio service mesh.

 
twitterIcon.pngyoutubeIcon.pnglinkedinIcon.png
nginx-favicon.png
Contact us
nginx-inquiries@nginx.com
1-800-915-9122
© 2022 F5, Inc. ⋅ 795 Folsom Street, San Francisco, CA 94107

miércoles, 17 de agosto de 2022

Mónadas en Cats parte 22

Como hemos visto con Reader y Writer, el poder de la mónada State proviene de la combinación de instancias. Los métodos map y flatMap enhebran el estado de una instancia a otra. Cada instancia individual representa una transformación de estado atómico, y su combinación representa una secuencia completa de cambios:

val step1 = State[Int, String]{ num =>

    val ans = num + 1

    (ans, s"Result of step1: $ans")

}

val step2 = State[Int, String]{ num =>

    val ans = num * 2

    (ans, s"Result of step2: $ans")

}

val both = for {

    a <- step1

    b <- step2

} yield (a, b)

val (state, result) = both.run(20).value

// state: Int = 42

// result: (String, String) = ("Result of step1: 21", "Result of step2: 42")


Como puedes ver, en este ejemplo el estado final es el resultado de aplicar ambas transformaciones en secuencia. El estado se entrelaza paso a paso, aunque no interactuamos con él. El modelo general para usar la mónada de estado es representar cada paso de un cálculo como una instancia y componer los pasos usando los operadores de mónada estándar. Cats proporciona varios constructores de conveniencia para crear pasos primitivos:

  • get extrae el estado como resultado;
  • set actualiza el estado y devuelve la unidad como resultado;
  • pure ignora el estado y devuelve un resultado proporcionado;
  • inspect extrae el estado a través de una función de transformación;
  • modify actualiza el estado utilizando una función de actualización.

val getDemo = State.get[Int]
// getDemo: State[Int, Int] = cats.data.IndexedStateT@796af713
getDemo.run(10).value
// res1: (Int, Int) = (10, 10)
val setDemo = State.set[Int](30)
// setDemo: State[Int, Unit] = cats.data.IndexedStateT@f9e66fa
setDemo.run(10).value
// res2: (Int, Unit) = (30, ())
val pureDemo = State.pure[Int, String]("Result")
// pureDemo: State[Int, String] = cats.data.IndexedStateT@439e3ee4
pureDemo.run(10).value
// res3: (Int, String) = (10, "Result")
val inspectDemo = State.inspect[Int, String](x => s"${x}!")
// inspectDemo: State[Int, String] = cats.data.IndexedStateT@77263be4
inspectDemo.run(10).value
// res4: (Int, String) = (10, "10!")
val modifyDemo = State.modify[Int](_ + 1)
// modifyDemo: State[Int, Unit] = cats.data.IndexedStateT@44ddcbfc
modifyDemo.run(10).value
// res5: (Int, Unit) = (11, ())

Podemos ensamblar estos bloques de construcción usando una comprensión. Por lo general, ignoramos el resultado de las etapas intermedias que solo representan transformaciones en el estado:

import cats.data.State
import State._
val program: State[Int, (Int, Int, Int)] = for {
a <- get[Int]
_ <- set[Int](a + 1)
b <- get[Int]
_ <- modify[Int](_ + 1)
c <- inspect[Int, Int](_ * 1000)
} yield (a, b, c)
// program: State[Int, (Int, Int, Int)] = cats.data.
IndexedStateT@42c9d44a
val (state, result) = program.run(1).value
// state: Int = 3
// result: (Int, Int, Int) = (1, 2, 3000)

sábado, 13 de agosto de 2022

Interfaces en Kotlin


Las interfaces de Kotlin son similares a las de Java 8: pueden contener definiciones de métodos abstractos, así como implementaciones de métodos no abstractos (similares a los métodos predeterminados de Java 8), pero no pueden contener ningún estado. Para declarar una interfaz en Kotlin, se usa la palabra clave de interface en lugar de class.


interface Clickable {

    fun click()

}


Esto declara una interfaz con un solo método abstracto llamado clic. Todas las clases no abstractas que implementan la interfaz deben proporcionar una implementación de este método. 

class Button : Clickable { override fun click() = println("I was clicked") } 

>>> Button().click() 

I was clicked


Kotlin usa los dos puntos después del nombre de la clase para reemplazar las palabras clave extends e implements que se usan en Java. Como en Java, una clase puede implementar tantas interfaces como quiera, pero solo puede extender una clase.

El modificador override, similar a la anotación @Override en Java, se utiliza para marcar métodos y propiedades que anulan los de la superclase o la interfaz. A diferencia de Java, el uso del modificador de anulación es obligatorio en Kotlin. Esto le evita anular accidentalmente un método si se agrega después de escribir su implementación; su código no se compilará a menos que marque explícitamente el método como anulado o le cambie el nombre.

Un método de interfaz puede tener una implementación predeterminada. A diferencia de Java 8, que requiere que marques tales implementaciones con la palabra clave predeterminada, Kotlin no tiene una anotación especial para tales métodos: solo proporcionas un cuerpo de método. Cambiemos la interfaz Clickable agregando un método con una implementación predeterminada


interface Clickable { 

  fun click() 

  fun showOff() = println("I'm clickable!") 

}


Si implementa esta interfaz, debe proporcionar una implementación para hacer clic. Puede redefinir el comportamiento del método showOff o puede omitirlo si está de acuerdo con el comportamiento predeterminado. Supongamos ahora que otra interfaz también define un método showOff y tiene la siguiente implementación para él.


interface Focusable {

    fun setFocus(b: Boolean) = println("I ${if (b) "got" else "lost"} focus.")

    fun showOff() = println("I'm focusable!")

}


¿Qué sucede si necesita implementar ambas interfaces en su clase? Cada uno de ellos contiene un método showOff con una implementación predeterminada; ¿Qué implementación gana? Ninguno de los dos gana. En su lugar, obtiene el siguiente error del compilador si no implementa showOff explícitamente


The class 'Button' must override public open fun showOff() because it inherits many implementations of it


El compilador de Kotlin te obliga a proporcionar tu propia implementación.


class Button : Clickable, Focusable { 

    override fun click() = println("I was clicked")

    override fun showOff() { 

        super<Clickable>.showOff()

        super<Focusable>.showOff() } 

}


La clase Button ahora implementa dos interfaces. Implementa showOff() llamando a ambas implementaciones que heredó de los supertipos. Para invocar una implementación heredada, usa la misma palabra clave que en Java: super. Pero la sintaxis para seleccionar una implementación específica es diferente. Mientras que en Java puede colocar el nombre del tipo base antes de la palabra clave super, como en Clickable.super.showOff(), en Kotlin coloca el nombre del tipo base entre paréntesis angulares: super<Clickable>.showOff().

Si solo necesita invocar una implementación heredada, puede escribir esto:


override fun showOff() = super.showOff()


Puede crear una instancia de esta clase y verificar que se pueden llamar todos los métodos heredados


fun main(args: Array) { 

    val button = Button() 

    button.showOff() 

    button.setFocus(true) 

    button.click() 

}


La implementación de setFocus se declara en la interfaz Focusable y se hereda automáticamente en la clase Button.   

viernes, 12 de agosto de 2022

Creando un web service REST con ZIO


 Vamos hacer un pequeño proyecto con ZIO, como para empezar. El "hola mundo" de toda la vida pero en un servicio REST. 

Antes de empezar vamos a hacer un proyecto con scala 3 con sbt : 


sbt new scala/scala3.g8


Luego agregamos las dependencias de zio, el build.sbt debe quedar así : 


scalaVersion := "3.1.2"

organization := "dev.zio"

name         := "zio-quickstart-restful-webservice"


libraryDependencies ++= Seq(

  "dev.zio"       %% "zio"            % "2.0.0",

  "dev.zio"       %% "zio-json"       % "0.3.0-RC10",

  "io.d11"        %% "zhttp"        % "2.0.0-RC10",

  "io.getquill"   %% "quill-zio"    % "4.2.0",

  "io.getquill"   %% "quill-jdbc-zio" % "4.2.0",

  "com.h2database" % "h2"             % "2.1.214"

)


Aclaro que tengo otras dependencias como la de base de dato que las voy a usar en proximos ejemplos. 

Y ahore si, hacemos el web service para nuestro "hola mundo" : 


package dev.zio.quickstart.greet


import zhttp.http._


object GreetingApp {

  def apply(): Http[Any, Nothing, Request, Response] =

    Http.collect[Request] {

      // GET /greet?name=:name

      case req@(Method.GET -> !! / "greet") if (req.url.queryParams.nonEmpty) =>

        Response.text(s"Hello ${req.url.queryParams("name").mkString(" and ")}!")


      // GET /greet

      case Method.GET -> !! / "greet" =>

        Response.text(s"Hello World!")


      // GET /greet/:name

      case Method.GET -> !! / "greet" / name =>

        Response.text(s"Hello $name!")

    }

}



Luego programamos el Main :


package dev.zio.quickstart


import dev.zio.quickstart.counter.CounterApp

import dev.zio.quickstart.download.DownloadApp

import dev.zio.quickstart.greet.GreetingApp

import dev.zio.quickstart.users.{InmemoryUserRepo, PersistentUserRepo, UserApp}

import zhttp.service.Server

import zio._


object MainApp extends ZIOAppDefault {

  def run =

    Server.start(

      port = 8999,

      http = GreetingApp() 

    ).provide(

      // An layer responsible for storing the state of the `counterApp`

      ZLayer.fromZIO(Ref.make(0)),

      

      // To use the persistence layer, provide the `PersistentUserRepo.layer` layer instead

      InmemoryUserRepo.layer

    )

}


Y listo!! Si vamos a http://localhost:8999/greet?name=Emanuel me va a saludar. 

Para correrlo lo pueden hacer con sbt run o con intellij corriendo el Main. 


Dejo el repo : 

https://github.com/emanuelpeg/zio-quickstart-restful-webservice

lunes, 8 de agosto de 2022

Primeros pasos con ZIO


Vamos hacer un pequeño proyecto con ZIO, como para empezar. El "hola mundo" de toda la vida. 

Antes de empezar vamos a hacer un proyecto con scala 3 con sbt : 

sbt new scala/scala3.g8

Luego agregamos las dependencias de zio, en este caso solo usaremos : 


libraryDependencies += "dev.zio" %% "zio" % "2.0.0"


De esta manera el archivo build.sbt será : 


val scala3Version = "3.1.3"


lazy val root = project

  .in(file("."))

  .settings(

    name := "zioHello",

    version := "0.1.0-SNAPSHOT",


    scalaVersion := scala3Version,

    libraryDependencies += "dev.zio" %% "zio" % "2.0.0",

    libraryDependencies += "org.scalameta" %% "munit" % "0.7.29" % Test

  )


Y luego vamos a hacer nuestro "hola mundo" en el archivo Main.scala : 


import zio._
import zio.Console._

object Main extends ZIOAppDefault :

  def run = myAppLogic

  val myAppLogic =
    for {
      _    <- printLine("Hola, como te llamas guapo?")
      nombre <- readLine
      _    <- printLine(s"Hola, ${nombre}, welcome to ZIO!")
    } yield ()


Y listo!! 


domingo, 7 de agosto de 2022

Programación Funcional con Scala y ZIO 2.0

Quiero compartirles un vídeo de scalac que esta muy bueno y nos da una primera mirada a ZIO :


viernes, 5 de agosto de 2022

Get me to the Cluster: Providing External Access to Services in Kubernetes with NGINX and BGP

 

WHITEPAPER

[Whitepaper] Get me to the Cluster: Providing External Access to Services in Kubernetes with NGINX and BGP

Hi Emanuel,

Learn how to use NGINX and BGP to provide external access to services running in Kubernetes. This whitepaper discusses the detailed solution architecture and components and shares step-by-step implementation instructions to help you deploy the solution.

In this whitepaper you will learn:

  • About the real-world challenges of exposing containerized applications in Kubernetes externally
  • How NGINX and BGP can help provide external access to services running in Kubernetes
  • About the detailed solution architecture and components
  • How to implement the solution with complete, step-by-step instructions

DevOps como puntapié inicial para tu transformación digital

 Me llego este mail y me resulto interesante, por eso se los comparto : 

miércoles, 3 de agosto de 2022

Mónadas en Cats parte 21

cats.data.State nos permite pasar estados adicionales como parte de un cálculo. Definimos instancias de estado que representan operaciones de estado atómico y las unimos usando map y flatMap. De esta manera, podemos modelar el estado mutable de una manera puramente funcional, sin usar la mutación real.

Reducido a su forma más simple, las instancias de State[S, A] representan funciones de tipo S => (S, A). S es el tipo del estado y A es el tipo del resultado.


import cats.data.State

val a = State[Int, String]{ state =>

(state, s"The state is $state")

}


En otras palabras, una instancia de State es una función que hace dos cosas:

• transforma un estado de entrada en un estado de salida;

• calcular un resultado.

Podemos "ejecutar" nuestra mónada desde un estado inicial. State proporciona tres métodos (run, runS y runA) que devuelven diferentes combinaciones de estado y resultado. Cada método devuelve una instancia de Eval, que State usa para mantener la seguridad de la pila. Llamamos al método de valor como de costumbre para extraer el resultado real:


// Get the state and the result:

val (state, result) = a.run(10).value

// state: Int = 10

// result: String = "The state is 10"

// Get the state, ignore the result:

val justTheState = a.runS(10).value

// justTheState: Int = 10

// Get the result, ignore the state:

val justTheResult = a.runA(10).value

// justTheResult: String = "The state is 10"

Mónadas en Cats parte 20

Los Readers proporcionan una herramienta para realizar inyección de dependencia. Escribimos pasos de nuestro programa como instancias de Reader, los encadenamos junto con map y flatMap, y construimos una función que acepta la dependencia como entrada.

Hay muchas formas de implementar la inyección de dependencia en Scala, desde técnicas simples como métodos con múltiples listas de parámetros, pasando por parámetros implícitos y clases de tipos, hasta técnicas complejas como el patrón cake  y frameworks.

Los Readers son más útiles en situaciones donde:

• estamos construyendo un programa que puede ser fácilmente representado por una función;

• necesitamos diferir la inyección de un parámetro conocido o conjunto de parámetros;

• queremos poder probar partes del programa de forma aislada.

Al representar los pasos de nuestro programa como Lectores, podemos probarlos tan fácilmente como funciones puras, además de obtener acceso a los combinadores map y flatMap.

Para problemas más complicados donde tenemos muchas dependencias, o donde un programa no se representa fácilmente como una función pura, otras técnicas de inyección de dependencia tienden a ser más apropiadas.


lunes, 1 de agosto de 2022

Mónadas en Cats parte 19

cats.data.Reader es una mónada que nos permite secuenciar operaciones que dependen de alguna entrada. Las instancias de Reader envuelven funciones de un argumento, brindándonos métodos útiles para componerlas.

Un uso común para Readers es la inyección de dependencia. Si tenemos varias operaciones que dependen de alguna configuración externa, podemos encadenarlas usando un Reader para producir una gran operación que acepte la configuración como un parámetro y ejecute nuestro programa en el orden especificado.

Podemos crear un Reader[A, B] a partir de una función A => B usando el constructor Reader.apply:


import cats.data.Reader

final case class Cat(name: String, favoriteFood: String)

val catName: Reader[Cat, String] = Reader(cat => cat.name)

// catName: Reader[Cat, String] = Kleisli(<function1>)


Podemos extraer la función nuevamente usando el método de ejecución del Reader's y llamarla usando apply:


catName.run(Cat("Garfield", "lasagne"))

// res1: cats.package.Id[String] = "Garfield"


El poder de Readers proviene de sus métodos map y flatMap, que representan diferentes tipos de composición de funciones. Por lo general, creamos un conjunto de Readers que aceptan el mismo tipo de configuración, los combinamos con map y flatMap, y luego llamamos a ejecutar para inyectar la configuración al final.

El método map simplemente extiende el cálculo en el Reader al pasar su resultado a través de una función:


val greetKitty: Reader[Cat, String] = catName.map(name => s"Hello ${name}")

greetKitty.run(Cat("Heathcliff", "junk food"))

// res2: cats.package.Id[String] = "Hello Heathcliff"


El método flatMap es más interesante. Nos permite combinar Readers que dependen del mismo tipo de entrada. Para ilustrar esto, ampliemos nuestro ejemplo de saludo para alimentar también al gato:


val feedKitty: Reader[Cat, String] = Reader(cat => s"Have a nice bowl of ${cat.favoriteFood}")

val greetAndFeed: Reader[Cat, String] =

for {

greet <- greetKitty

feed <- feedKitty

} yield s"$greet. $feed."

greetAndFeed(Cat("Garfield", "lasagne"))

// res3: cats.package.Id[String] = "Hello Garfield. Have a nice bowl of lasagne."

greetAndFeed(Cat("Heathcliff", "junk food"))

// res4: cats.package.Id[String] = "Hello Heathcliff. Have a nice bowl of junk food."



Log con Aop de Spring boot


Supongamos que queremos logear cada cosa que pasa por cada método de nuestros objetos, para hacer esto podemos utilizar aop. 

Veamos un ejemplo: 

@Aspect

@Configuration

@Order(0)

class LogingAspect {

    private val logger = LogFactory.getLog(LoggingAspect::class.java)


    @Pointcut("execution(public * com.paquete..*(..))")

    fun allControllersMethods() {

    }


    @Around("allControllersMethods()")

    fun profileAllMethods(pjp: ProceedingJoinPoint): Any {

        val method: Method = (pjp.signature as MethodSignature).method


        logger.info("Started ${method.name}")


        try {

            return if (pjp.args != null) {

                pjp.proceed(pjp.args)

            } else {

                pjp.proceed()

            }

        } catch (ex: Exception) {

            logger.error("Error in ${method.name}", ex)

            throw ex

        } finally {

            logger.info( "Finished ${method.name}")

        }

    }

}


Y Listo!!