Code

GAPAND 2015 is over :)

Posted on Updated on

IMG_20150704_092031

Después de tanto meses de curro, el #gapand2015 ya se ha terminado.

Tanto trabajo para sólo un día… ufff, no me extraña que en ocasiones nos tomen por locos, pero la verdad es que el feedback ha sido, en una palabra COJONUDO, y ante eso, ante esa respuesta de la gente sólo cabe decir MUCHAS GRACIAS!!!

_MG_8847 _MG_8854

Gracias a todos los que habéis venido a ver alguna sesión, porque dedicar un sábado de verano a esto en lugar de irse a la playa o similar dice mucho -bueno- de vosotros. Gracias a los que habéis colaborado y habéis propuesto sesiones y talleres para compartir con la comunidad a cambio de nada. Y aquí quiero incluir también a las charlas que lamentablemente tuvimos que dejar fuera, ya que se presentaron al Call4Papers nada más y nada menos que 64 charlas y talleres. Algo que superó en mucho nuestras expectativas iniciales: lo de tener 24 propuestas en 24 horas es algo que recordaré toda mi vida 😀

_MG_8862 _MG_8869

Gracias a todos aquellos que han venido desde muy lejos, pegándose auténticos palizones de coche desde Barcelona, Madrid, Valencia y más lejos. Horas y horas de coche e incluso avión para venir a Andorra, a pasar un día con nosotros y el resto de geeks… eso no tiene precio!

_MG_8872(1) _MG_8893

Saber que el Domingo había gente que tenía que volver a Tenerife y el Sábado por la noche estaba tomándose una última caña con los colegas, eso señores, eso es la comunidad en su estado más puro. El evento podrá salir mejor o peor (aunque sinceramente creo que salió muy bien) y siempre hay cosas que se pueden mejorar, pero ese espíritu es algo mágico.

IMG_20150704_143950 IMG_20150704_100338

Gracias a todos aquellos colaboradores que nos han apoyado y han hecho que esto sea posible, desde particulares, asociaciones, empresas o la propia universitat d’Andorra. Sin vosotrros esto no hubiese sido posible!

Gracias también al resto de la organización, ya que en un momento personal complicado no sólo me ayudaron a tirar del carro, sino que completaron un trabajo fantástico, con el gran resultado que ya habéis visto. Gracias equipo! 😀

Gracias a todos!

_MG_8891 _MG_8889

Web: www.gapand.com

Y antes de que ponga sentimental, aquí van algunos tweets del #gapand2015. Gracias otra vez!

Se os quiere!

En breve iremos publicando contenido, demos y charlas 🙂

Nova xerrada (30/01/2015): Introducción a F#

Posted on Updated on

El proper 30/01/2015 a les 18h30 tindrem un convidat d’excepció per parlar de F#.

alex_casquete

F# es un lenguaje .NET maduro, de código abierto, multiplataforma, functional-first y preparado para la empresa, que permite a empresas y usuarios a hacer frente a problemas complejos con un código simple, fácil de mantener y robusto.

Una de las características más interesantes y potentes de F#, y que le distingue del resto de lenguajes, son los proveedores de tipo (Type Providers). En esta sesión veremos cómo comenzar a utilizar este mecanismo que nos permite trabajar con multitud orígenes de datos de una forma totalmente diferente. Veremos cómo podemos conectarnos y consultar desde servicios web o ficheros estructurados como JSON o XML, hasta bases de datos SQL Server o clústeres de Hadoop y que, gracias al uso de los proveedores de tipo, el lenguaje puede inferir la estructura de datos y proporcionar tipos, propiedades y métodos en tiempo de diseño, eliminando así una de las obstáculos más importantes que nos encontrarnos al utilizar distintas fuentes de datos en entornes empresariales.

Alex Casquete: Desarrollador especializado en soluciones empresariales utilizando tecnologías Microsoft para plataformas web, móvil y de escritorio. MVP en Windows.

C# Integració amb Active Directory

Posted on Updated on

ldapsearch

El passat divendres 16 per la tarda vàrem fer una xerrada sobre desenvolupament d’aplicacions empresarials integrades amb l’Active Directory de Microsoft.

En el mon empresarial és molt comú haver de desenvolupar aplicacions que verifiquin si un usuari forma part d’un (o varis) rols del AD, i així poder gestionar les autoritzacions de forma centralitzada.

També vàrem introduir alguns tòpics avançats, com per exemple impersonar un altre usuari, i així poder executar una aplicació amb un altre usuari sense haver de tancar la nostra sessió actual.

Us deixo el codi del projecte d’exemple que vàrem fer servir durant la sessió.

Enjoy!

Nous events per tancar l’any… que el ritmo no pare!

Posted on

Upcoming-Event

Hola a tots,

Aquesta setmana està sent força interessant, pel que fa als propers events:

Dilluns

Vaig començar el dilluns pensant si fer un nou event de desenvolupament en C# o bé un de SQL Server. La primera em venia molt de gust perquè darrerament he estat utilitzant alguns conceptes molt ‘chulis’ (Generics ‘a fondo’, LINQ amb lambdas, i fluent interfaces). I la segona perquè després de uns anys sense tocar-ho gaire, he estat programant força en TSQL i he pogut posar en pràctica algunes coses noves de la darrera versió de SQL Server 2008 (Filestream, Table-Valued-Parameters o funcions de tipus taula).

Dimarts

Quan em pensava que finalment ja m’havia decidit em va arribar un mail d’en David Martos. En David és un col·lega que treballa a Spenta i que també és MVP, però en el seu cas de SharePoint. Aprofitant que anava a fer una xerrada a SUG.CAT (grup d’usuaris de Sharepoint de Catalunya del qual n’és membre fundador) em proposava de pujar a Andorra i fer-la també aquí. És una xerrada molt interessant, ja que tracta de cóm gestionar el cicle de vida de les aplicacions (ALM) en SharePoint. La xerrada inclou SharePoint, però també eines per Unit testing com Moles, i també Mercurial, Jenkins, Cucumber, Capybara, etc.

Un parell de mails i varis tweets després, ja hem quedat per divendres 25 de Novembre a les 18h00, com és habitual. Si t’interessa conversar amb un dels millors experts de SharePoint d’Espanya no t’ho pots perdre. I a més a més tractarem temes molt importants (arquitectura, testing, etc.). Ja us aniré informant més en detall a mida que arribi la data.

Dimecres

Només estem a dimecres? Caram! Fa només uns minuts he rebut un missatge d’un altre col·lega. En aquest cas és en Paulo Dias, un dels evangelistes de IT de Microsoft que possiblement hauràs vist en algun dels darrers events de virtualització. En els darrers mesos hem estat en contacte per organitzar un event a Andorra, on vinguin el mateix Paulo, en Fernando Guillot, i en Dani Alonso.

El tema? Encara està obert però sent tres ponents ‘deluxe’ podríem aprofitar per demanar-los que ens parlin de App-V, VMM 2012, o qualsevol cosa que creieu que pugui estar interessant. Ells m’han dit que accepten suggerències així que si en teniu alguna, deixeu un comentari aquí o al Facebook d’AndorraDotNet o de l’AVIA.

I la data? Un divendres de cara a Desembre o Gener, ja que tots ells son esquiadors i aprofitaran que fem els events en divendres per quedar-se en cap de setmana a gaudir de la neu. I ja posats -com que els conec- segur que per la nit organitzem algun sarau 😛

En resum

La veritat es que no se si publicar el post o m’espero a demà a veure si hi ha alguna novetat més…

També us agrairia feedback sobre temes, dates o qualsevol cosa, així com la màxima difusió possible.

[HowTo] – LINQ to SQL: Mostrando el progreso de Context.SubmitChanges()

Posted on Updated on

Hola de nuevo,

En el proyecto que me ocupa actualmente he tenido que pelearme con algo curioso: Resulta que hay que realizar un proceso que lea una serie de ficheros de texto (si, si, de texto) que contienen una serie de información que debo analizar y posteriormente volcar a la base de datos. Hasta aquí ningún problema, salvo el de tener que lidiar con unos ficheros de texto cuyos formatos parecen haber sido diseñados por un loco (parece mentira que hoy en día hayan tantas organizaciones / empresas / bancos que sigan utilizando este método para intercambiar información).

SubmitChanges

El problema

Una vez desarrolladas las clases necesarias para leer y desglosar toda la información, me he encontrado con que se generan en el menor de los casos del orden de medio millón de filas a insertar en la BD.

Como os podéis imaginar el tiempo para realizar el volcado es considerable, del orden de entre 5 y 15 minutos. Así que he pensado en al menos optimizar la experiéncia del usuario, y me he marcado estos objetivos:

  1. Que el usuario pueda seguir trabajando mientras se insertan los registros
  2. Poder mostrar el progreso de la operación

Partimos de que tenemos un contexto de LINQ to SQL (por favor, no me preguntéis porque estamos usando esto en lugar de EF o NHibernate). En dicho contexto tenemos unas 495.000 filas pendientes de insertarse en cuanto hagamos la llamada a SubmitChanges(), y lo malo es que este método es síncrono y además no genera ningún evento ni permite usar callbacks ni ningún mecanismo de notificación del progreso.

Solución al primer problema (asincronía)

Es el más sencillo de los dos con diferencia. En versiones anteriores debíamos crear un thread manualmente, pero desde la aparición de la clase Task en .NET 4.0 esto se ha simplificado enormemente. Basta con crear un objeto Task que apunte al método que deseamos lanzar de forma asíncrona (mediante paralelismo).


importEngineInsertTask = new Task(() => insertPendingRows(), cancellationTokenSource.Token);
importEngineInsertTask.Start();

Una de las ventajas respecto a los diferentes métodos de versiones anteriores es la posibilidad de pasar un token de cancelación, para por ejemplo poder cancelar la tarea si el usuario así lo decide. Tal vez sea interesante un post sobre esto más adelante, aunque es bastante sencillo.

Solución al segundo problema (mostrar progreso)

Este ha sido un poco más peliagudo, ya que en principio no hay modo de interactuar con el DataContext de LINQ to SQL para reportar el progreso de las inserciones. Para poder mostrar el progreso necesitamos saber por un lado el número total de filas a insertar y por otro el elemento actual. Para conocer el número total de filas a insertar basta con preguntarle al DataContext:

numInsertLines = context.GetChangeSet().Inserts.Count;

Pero para saber el número de insert actual no disponemos de nada. Sin embargo, el Contexto dispone de una propiedad Log de tipo TextWriter, que permite la monitorización de cada operación. Bien, a partir de esto, podemos generar una clase propia que herede de TextWriter:

class ActionTextWriter : TextWriter
{
    private readonly Action<string> action;

    public ActionTextWriter(Action<string> action)
    {
        this.action = action;
    }

    public override void Write(char[] buffer, int index, int count)
    {
        Write(new string(buffer, index, count));
    }

    public override void Write(string value)
    {
        action.Invoke(value);
    }

    public override Encoding Encoding
    {
        get { return System.Text.Encoding.Default; }
    }
}

Y posteriormente usarla para llamar a un método que se encargue de lanzar un evento que será monitorizado para mostrar el progreso:


private void configureSubmitInsertProgress()
{
    context.Log = new ActionTextWriter(s =>
    {
        if (s.StartsWith("INSERT INTO"))
            ReportInsertProgress(s);
    });
}

Conclusión

El resultado es que el usuario puede realizar un proceso relativamente pesado sin tener que dejar de trabajar, ya que el proceso se ejecuta en segundo plano, y además puede ver un proceso del progrso de la operación. Ya sabemos lo impacientes que pueden ser los usuarios, verdad? 🙂

ReportProgress

Saludos,

HowTo: ¿Como saber si el usuario actual es administrador del dominio?

Posted on Updated on

Nota: Es una pregunta que me encuentro de forma recurrente en los foros de desarrollo, así que lo apunto aquí para tener una referencia.

El escenario

Cuando desarrollamos una aplicación de escritorio, puede ser interesante saber a qué grupos pertenece el usuario que está ejecutando nuestra aplicación, para mostrar / ocultar / permitir / revocar ciertas acciones, u opciones. Por ejemplo, yo acostumbro a tener un botón en la barra de estado de mis aplicaciones que permite cambiar la cadena de conexión, y evidentemente, solo está visible cuando el usuario pertenece al grupo “Administradores del dominio”.

privileges_thumb

IsInRole

Para ello, el objeto WindowsPrincipal dispone de un método IsInRole, que nos dirà si un usuario pertenece a un grupo determinado. Genial, además este método tiene varias sobrecargas, de modo que podemos usarlo pasando el RID, SID, el nombre e incluso una constante basada en la enumeración WindowsBuiltIOnRole.

De modo que para saber si nuestro usuario es administrador local, basta con hacer esto:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
return wp.IsInRole(WindowsBuiltInRole.Administrator);

Sencillo, verdad? A partir del usuario que ejecuta nuestra aplicación (válido también en caso de impersonación), creamos un objeto Principal e invocamos al método pasándole el grupo contra el que deseamos validar.

El problema de esta enumeración es que como su nombre indica, sólo contempla los grupos locales. Así que si queremos saber si pertenece a un grupo del dominio parece que tendremos que buscar el SID del grupo, o el nombre, y hardcodearlo ‘a mano’ en nuestra aplicación.

Feo verdad? Pues la verdad es que si, muy feo… vamos a investigar un poco más, a ver si encontramos otra forma.

Nota: Por motivos de rendimiento, para determinar la función del usuario se recomienda utilizar la sobrecarga de IsInRole(SecurityIdentifier) como sobrecarga preferible.

Ahora vamos a generar el SID del grupo de adminstradores del dominio y ya podemos volver a probar el método IsInRole:

WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent());
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.AccountDomainAdminsSid, null);
return wp.IsInRole(sid);

Ops! Nuestro gozo en un pozo… se necesita informar el segundo argumento del constructor para el SID del grupo:

DomainSidError_thumb

DomainSid

¿Y que kkgrnn$# representa que es este identificador? Pues según pone en la ayuda del constructor, debe proporcionarse el SID del dominio para que el constructor pueda devolver algunos identificadores de WellKnownSidType, entre los cuales está el de los administradores del dominio.

Dicho de otro modo, o sabemos el SID de nuestro dominio o todo lo anterior no vale para nada… 😦

¿Y cómo podemos saber el SID de dominio? Después de buscar un ratito, lo único que he encontrado es una utilidad de consola llamada PsGetSid, que forma parte de las PSTools del inefable Mark Russinovich. Basta descargar esta utilidad y ejecutarla desde la consola de este modo para saber el SID de nuestro dominio (el nombre de dominio en formato “microsoft.com” o “net.volvo.com”):

DomainSidConsole_thumb

Sin embargo, me niego a tener que hacer esto para saber el identificador del dominio. Así que vamos a probar si podemos recuperar esta propiedad del esquema de AD mediante un DirectoryEntry. Para ello utilizaremos la clase Domain:

Domain d = Domain.GetDomain(new DirectoryContext(DirectoryContextType.Domain, getDomainName()));
using (DirectoryEntry de = d.GetDirectoryEntry())
{
    byte[] domSid = (byte[])de.Properties["objectSid"].Value;
    string sdomainSid = sIDtoString(domSid);
    Console.WriteLine(sdomainSid);
}

Aquí necesitaremos dos funciones de apoyo, la primera nos devuelve el nombre del domino, y la segunda transforma el array de bits del SID en su representación textual:

public static string getDomainName()
{
    return IPGlobalProperties.GetIPGlobalProperties().DomainName;
}

public static string sIDtoString(byte[] sidBinary)
{
    SecurityIdentifier sid = new SecurityIdentifier(sidBinary, 0);
    return sid.ToString();
}

A todo esto el valor de la variable sdomainSid es el esperado!!! 😀

Poniéndolo todo junto

Al igual que el alegre bandolero, también soy un fanático de los métodos extensores, así que vamos a encapsular todo esto en un método que extienda la clase WindowsIdentity. Aquí va todo el código junto:

using System.DirectoryServices;
using System.DirectoryServices.ActiveDirectory;
using System.Net.NetworkInformation;
using System.Security.Principal;
 
namespace Alpha.Code
{
    public static class SecurityExtensions
    {
        public static bool IsDomainAdmin (this WindowsIdentity identity)
        {
            Domain d = Domain.GetDomain(new
                DirectoryContext(DirectoryContextType.Domain, getDomainName()));
            using (DirectoryEntry de = d.GetDirectoryEntry())
            {
                byte[] bdomSid = (byte[])de.Properties["objectSid"].Value;
                string sdomainSid = sIDtoString(bdomSid);
                WindowsPrincipal wp = new WindowsPrincipal(identity);
                SecurityIdentifier dsid = new SecurityIdentifier(sdomainSid);
                SecurityIdentifier dasid = new SecurityIdentifier(
                    WellKnownSidType.AccountDomainAdminsSid, dsid);
                return wp.IsInRole(dasid);
            }
        }
 
        public static string getDomainName()
        {
            return IPGlobalProperties.GetIPGlobalProperties().DomainName;
        }
 
        public static string sIDtoString(byte[] sidBinary)
        {
            SecurityIdentifier sid = new SecurityIdentifier(sidBinary, 0);
            return sid.ToString();
        }
    }
}

Y la forma de usarlo es tan sencilla como esto:

if (WindowsIdentity.GetCurrent().IsDomainAdmin())
{
    //Acciones a realizar si el usuario es administrador de dominio...
}

Un saludo desde las frías tierras de Andorra 🙂

Materiales de la charla sobre computación paralela en BcnDev

Posted on Updated on

Hola de nuevo,

Después de la charla del viernes en BCNDEV, lo prometido es deuda. Os comenté que había realizado las demos en forma de un pequeño proyecto web, para no tener que ir con un pedazo-de-pepino a hacer las demos (más que nada porque no lo tengo :-P). Así que sólo quiero dejaros el enlace al proyecto que usé para las demos de la TPL, por si alguno las quiere probar:

http://cid-f3a970280830b5fe.office.live.com/embedicon.aspx/AndorraDotNet/Events/DemoParallelWeb.zip

Os recuerdo que si el proyecto lo probáis en una máquina virtual poco paralelismo vais a ver, pero publicarlo en el host o en cualquier estación con varios cores y veréis la diferencia de rendimiento. En algunos casos no hay mucha ganancia, pero en algunos otros la diferencia es de 5 a 1 o más.

Aprovecho para dejaros la versión más reciente de la presentación, y os prometo que no la voy a actualizar más 🙂 que bastante lo he hecho en los últimos días:

Saludos a todos,