SharePoint Saturday Madrid. Sesión sobre Azure Search

Muy buenas a todos!

Llevo unos meses sin actualizar el blog, y pido disculpas por ello. La verdad, es que el trabajo está ocupando gran parte de mi tiempo y no encuentro el momento de seguir contándoos cosas sobre desarrollo que encuentro muy interesantes.

Ayer se celebró la primera SharePoint Saturday en Madrid que ha estado organizada por las comunidades de usuarios y que fue un rotundo éxito. Tuve la oportunidad de participar no solo como parte del Staff y de la organización del evento (aunque debo reconocer que me hubiera gustado poder colaborar más) sino también como Speaker con la sesión «Using Azure Search to build Office 365 search driven solutions». Os dejo una foto de todo el staff y speakers, que han hecho posible que el nivel del evento sea increíble, !Gracias a todos!.

Ch3kvCiWwAEr5y6

Quiero aprovechar la oportunidad para agradecer a todos los asistentes a la sesión, espero que os gustara y la encontrarais interesante. Para los que no pudisteis asistir he subido tanto el contenido de la presentación como el código de las demos que realicé para que las tengáis disponible.

Presentación de la sesión

Código en GitHub

https://github.com/jcroav/AzureSearch-Office365

 

Espero poder retomar el blog en las próximas semanas, a partir del evento de ayer, ya tengo varios temas que creo que son muy interesantes compartir con todos.

Saludos, hasta la próxima

[Eventos]: Azure Search. ¿Qué es y cómo podemos usarlo en nuestros proyectos con Office 365?

Muy buenas a todos,

El próximo 16 de Marzo a las 16:00h, tendré la oportunidad de hacer mi primer WebCast en colaboración con la Comunidad de Office 365, el Grupo de Usuarios de SharePoint de España (SUGES) y la Office Platform Technical Community de Madrid (MadPoint).

En dicho WebCast podremos conocer el servicio que Azure nos proporcionar para desarrollar una experiencia de búsqueda robusta en nuestros proyectos. Además no solo veremos como configurarlo y ponerlo en marcha sino como combinarlo con la API Microsoft Graph para Office 365, de manera que podamos indexar contenido de servicios de Office 365 en el servicio de búsqueda de Azure.

Os dejo los datos del WebCast, os espero a todos, y por supuesto espero que os guste lo que vamos a ver .

Datos de Interés

Como os decía espero veros por ahí, y que disfrutéis con el contenido.

Un saludo a todos y gracias a todas las comunidades por darme la oportunidad de participar en este WebCast

Indexando contenido en el Servicio Azure Search

Muy buenas a todos.

En anteriores post, comenzamos a trabajar con el servicio de Azure Search. Concretamente, vimos como crear índices en una instancia del servicio creada en Azure.

Primeros pasos con Azure Search: Los índices

A continuación, ¿Cuál es el siguiente paso?, una vez que hemos creado el índice, tenemos que indexar documentos en ese índice y eso es lo que vamos a hacer en esta entrada.

La indexación de contenidos, una vez que tenemos creado el índice es muy sencilla. En primer lugar, vamos a crear una aplicación de consola y vamos ejecutar desde la consola de Nuget el siguiente  comando para añadir las referencias a la SDK de Azure:

Install-Package Microsoft.Azure.Search -Pre

Esta aplicación va a tener el siguiente código de ejemplo


class Program
{
static void Main(string[] args)
{
int option;

do
{
option = menu();
switch (option)
{
case 1:
PopulateIndexUsingSDK();

break;
default:
break;
}
}
while (option != 0);
}

private static void PopulateIndexUsingSDK()
{
SearchIndexClient indexClient = GetSearchIndexClient();

UploadDocuments(indexClient);
}

private static SearchIndexClient GetSearchIndexClient()
{
string serviceName = ConfigurationManager.AppSettings["SearchServiceName"];
string apiKey = ConfigurationManager.AppSettings["ApiKey"];

SearchIndexClient indexClient = new SearchIndexClient(serviceName,"files", new SearchCredentials(apiKey));

return indexClient;
}

private static void UploadDocuments(SearchIndexClient indexClient)
{

try
{
var files = new files[]{
new files(){
DocumentId = "1",
Name = "Example Document Title 1",
Url = "http://www.example.com/mydocument1",
CreatedDate = "2012-02-01"
},
new files(){
DocumentId = "2",
Name = "Example Document Title 2",
Url = "http://www.example.com/mydocument2",
CreatedDate = "2012-02-01"
},
new files(){
DocumentId = "3",
Name = "Example Document Title 3",
Url = "http://www.example.com/mydocument3",
CreatedDate = "2012-02-01"
}
};
var batch = IndexBatch.Upload(files);
indexClient.Documents.Index(batch);
}
catch (IndexBatchException e)
{

Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}

// Wait a while for indexing to complete.
Thread.Sleep(2000);
}

private static int menu()
{
int value = 0;

Console.WriteLine("-----------------------------------");
Console.WriteLine("1.- Populate index using .NET SDK");
Console.WriteLine("0.- Exit");
Console.WriteLine("-----------------------------------");

do
{
Console.WriteLine("Enter a valid option: ");
value = Int16.Parse(Console.ReadLine());
}
while (value < 0 && value > 1);

return value;
}
}

Vamos a ver los elementos clave de este código. Obviamente, los métodos más importantes de nuestra aplicación de consola son 2.

SearchIndexClient()

Este método crea un nuevo objeto del tipo SearchIndexClient que nos va a permitir operar con el índice en cuestión. Para ello, obtiene del App.Config los datos relacionados con el servicio de búsqueda (api-key y servicename) y a continuación en el constructor de la clase ServiceIndexClient indica: el nombre del servicio de búsqueda, el nombre del índice y las credenciales para acceder al servicio.

UploadDocuments()

Este método se encarga de hacer la subida de documentos propiamente dicha. Para ello crea un array de objetos de tipo files, que tienen la siguiente definición:


class files
{
public string DocumentId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string CreatedDate { get; set; }
}

Una vez ya se ha generado el array,  lo primero que se hace es crear un batch con la petición que se quiere hacer por medio de método IndexBatch.Upload(files).

A continuación por medio de la función indexClient.Documents.Index(batch) se hace la subida de los documentos al servicio Azure.

Se usa, para esperar y darle tiempo a que la indexación de documentos finalice correctamente Thread.Sleep(2000)

Ahora, podemos ejecutar la aplicación y ver los resultados. Si accedemos después al servicio de búsqueda de Azure, podemos ver que los elementos se han añadido correctamente la índice.

Captura de pantalla 2016-02-02 a las 22.24.17

Captura de pantalla 2016-02-02 a las 22.24.35

Os voy a dejar algunos enlaces que he usado para la entrada de hoy:

https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/

https://msdn.microsoft.com/en-us/library/azure/dn951165.aspx

Y esto es todo por hoy, en próximas entradas, veremos como usamos esto que hemos aprendido hoy y lo que vimos en la entrada anterior.

Autenticación app-only para usar la API Microsoft Graph en webjobs de Azure

para indexar contenido de Office 365 en este servicio Azure Search

Espero que os haya resultado interesante.

 

Autenticación app-only para usar la API Microsoft Graph en webjobs de Azure

Muy buenas a todos

En entradas anteriores, hemos visto cómo empezar a trabajar con el servicio de búsqueda de Azure, creando los índices. Dentro de mi objetivo a la hora de trabajar con este servicio, estaba el de indexar contenido de Office 365 usando la API Microsoft Graph por medio de webjobs. Y es aquí donde entra lo que os quiero contar hoy.

El flujo habitual de autenticación para usar la API Microsoft Graph en nuestras aplicaciones está basado en el protocolo OAuth2. Este protocolo parte de un token que hace una delegación de una serie de permisos específicos para un usuario concreto. Para obtener este token, es necesario que el usuario se identifique en Office 365 al menos una vez, por lo que tiene que introducir sus credenciales en una pantalla de autenticación que se muestra en pantalla.

Sin embargo, hay una serie de aplicaciones en las que este flujo de autenticación no es posible, aplicaciones que ejecutan tareas en background y en las que no hay un usuario como pueden ser los webjobs. Para este tipo de aplicaciones, el protocolo OAuth2 proporcionar un flujo adicional de autenticación y es el que vamos a usar para acceder a la API de Microsoft Graph en una aplicación que se va a ejecutar en un webjob de Azure. Podemos usar este flujo de autenticación, de momento, para obtener acceso a las API de contactos, mail y calendario. He estado probando y para OneDrive aún no está soportado.

Antes de nada, os voy a dejar los enlaces donde he encontrado toda la información y el tutorial para poder configurar la aplicación y todo lo que hay que hacer en Azure para que funcione correctamente.

http://www.eliostruyf.com/building-daemon-or-service-app-with-the-microsoft-graph-api/

http://blogs.msdn.com/b/exchangedev/archive/2015/01/21/building-demon-or-service-apps-with-office-365-mail-calendar-and-contacts-apis-oauth2-client-credential-flow.aspx

Creando los permisos para la aplicación en AAD

El primer paso que tenemos daremos será configurar los permisos de nuestra aplicación en Azure Active Directory.

1.- Accedemos a Azure, el portal clásico y vamos a la sección de Azure Active Directory. Una vez ahí nos vamos al apartado de aplicaciones, donde añadiremos una nueva aplicación.

Captura de pantalla 2016-01-24 a las 16.28.51

2.- Seleccionamos la opción de «Agregar una aplicación que mi organización está desarrollando» y de tipo «Aplicación Web y/o API Web» ya que la otra opción no soporta el tipo de autenticación app-only que vamos a configurar.

Captura de pantalla 2016-01-24 a las 16.29.04

Captura de pantalla 2016-01-24 a las 16.29.28

3.- Indicamos la URL de inicio de sesión y la URI de la aplicación. El primero de los dos valores, no es importante, en este caso hemos añadido la url donde el webjob estará alojado.

Captura de pantalla 2016-01-24 a las 16.30.49

4.- Vamos a la nueva aplicación que hemos añadido y en la pestaña «Configuración», vamos a la parte final, de permisos, ahí añadimos permisos para Microsoft Graph.

Captura de pantalla 2016-01-24 a las 16.31.30

Captura de pantalla 2016-01-24 a las 16.31.42

5.- Una vez añadidos, tenemos que indicar en el desplegable de «Permisos de la Aplicación» (ya que los permisos los vamos a conceder directamente a la aplicación), los servicios para los que tendrá permisos.

Captura de pantalla 2016-01-24 a las 16.31.57

6.- Una vez terminado pulsamos Guardar.

Creando y configurando los certificados

A continuación necesitamos generar los certificados y configurarlos en nuestra aplicación web (que también tendremos que crear) y en la aplicación que acabamos de crear en nuestro AAD.

1.- En primer lugar, abrimos la consola de comandos y creamos el certificado, sustituyendo Tenant y AppName por los valores que correspondan

makecert -r -pe -n «CN=Tenant AppName Cert» -b 11/25/2015 -e 11/25/2017 -ss my -len 2048

2.- A continuación, vamos a exportar dicho certificado como PFX y CER. Para ello primero abrimos el Microsoft Management Console (mmc.exe).

3.- Una vez aquí, vamos a archivo->Agregar o quitar complemento y ahí añadimos la opción certificados.

cer1

4.- A continuación, buscamos el certificado que acabamos de crear y hacemos click sobre el botón derecho del mismo y seleccionamos Todas las tareas->exportar

cer3

Tenemos dos opciones de exportación, «Exportar la clave privada» y «No exportar la clave privada», ejecutaremos la exportación dos veces y completaremos el asistente para cada una de éstas opciones, generando los dos certificados.

5.- Ahora, volvemos nuevamente a la aplicación que hemos creado en Azure Active Directory para configurar el certificado en la misma. Esto no se puede hacer a través de una interfaz gráfica, por lo que habrá que hacerlo modificando el manifest. Para ello, lo primero que debemos hacer es recuperar las claves del certificado CER que hemos obtenido, esto lo podemos hacer por medio del siguiente script de powershell:


$certPath = Read-Host "Enter certificate path (.cer)"
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($certPath)
$rawCert = $cert.GetRawCertData()
$base64Cert = [System.Convert]::ToBase64String($rawCert)
$rawCertHash = $cert.GetCertHash()
$base64CertHash = [System.Convert]::ToBase64String($rawCertHash)
$KeyId = [System.Guid]::NewGuid().ToString()
Write-Host "base64Cert:" $base64Cert
Write-Host "base64CertHash:" $base64CertHash
Write-Host "KeyId:" $KeyId

Este script nos devuelve las tres claves que nos hacen falta.

6.- Ahora, descargamos el manifest de la aplicación:

Captura de pantalla 2016-01-24 a las 17.46.09

Captura de pantalla 2016-01-24 a las 17.46.25

7.- Y sustituimos la siguiente cadena:


"keyCredentials": []

por


"keyCredentials": [
 {
 "customKeyIdentifier": "base64CertHash",
 "keyId": "KeyId",
 "type": "AsymmetricX509Cert",
 "usage": "Verify",
 "value": "base64Cert"
 }
],

Sustituyendo los valores «base64CertHash», «KeyId» y «base64Cert», por la cadena correspondiente obtenida de la ejecución del script powershell anterior.

8.- Ahora tenemos que volver a cargar el manifest modificado en la aplicación con lo que habremos terminado de configurar los permisos de nuestra app en Azure Active Directory.

9.- A continuación, creamos una aplicación web de Azure y cargamos el certificado PFX en la misma.

Captura de pantalla 2016-01-24 a las 17.57.36

Es necesario escalar la aplicación web a nivel básico

Captura de pantalla 2016-01-24 a las 17.58.28

En la pestaña configuración de la aplicación web, hacemos click en Cargar un certificado

Captura de pantalla 2016-01-24 a las 17.59.15

Captura de pantalla 2016-01-24 a las 18.01.35

En la sección de configuración de aplicación, añadimos el valor WEBSITE_LOAD_CERTIFICATES con la huella digital que hemos obtenido al cargar el certificado.

Captura de pantalla 2016-01-24 a las 18.07.42

Y por fin, habremos configurado los certificados en Azure. Ahora no solo nos queda publicar y probar el WebJobs.

Creando y publicando el webjob en Azure 

Vamos a crear una nueva aplicación de consola con el código del WebJob que vamos a publicar.

Para esta aplicación hay que añadir las siguientes referencias:

  • System.Configuration

Y Añadir a través de Nuget la librería ADAL y RestSharp.

Además en el app.config, debemos añadir las siguientes propiedades:


 <appSettings>;
 <add key="GraphUrl" value="https://graph.microsoft.com"/>;
 <add key="ClientId" value="clientidaad"/>;
 <add key="Thumbprint" value="thumbprint"/>;
 <add key="Authority" value="https://login.windows.net/tenant.onmicrosoft.com/"/>;
 </appSettings>;

Debemos de sustituir el clientidaad por el ClientId de la aplicación que hemos creado en el Azure Active Directory, el valor de thumbprint por la huella obtenida al cargar el certificado en la aplicación web y por último sustituir el valor tenant por el nombre de nuestra organización.

Lo que nos queda ahora, es el código de la aplicación de consola de ejemplo, que es el siguiente:


class Program
 {
 private static readonly string GraphUrl = ConfigurationManager.AppSettings["GraphUrl"];
 private static readonly string ClientId = ConfigurationManager.AppSettings["ClientId"];
 private static readonly string Authority = ConfigurationManager.AppSettings["Authority"];
 private static readonly string Thumbprint = ConfigurationManager.AppSettings["Thumbprint"];

static void Main(string[] args)
 {
 //&nbsp;Recuperar el certificado
 var certificate = GetCertificate();

//&nbsp;Recuperar el token de acceso
 var token = GetAccessToken(certificate);

//&nbsp;Obtener los contactos
 var client = new RestClient(GraphUrl);
 var request = new RestRequest("/v1.0/users/&lt;userid&gt;/contacts", Method.GET);
 request.AddHeader("Authorization", "Bearer " + token.Result);
 request.AddHeader("Content-Type", "application/json");
 request.AddHeader("Accept", "application/json");

var response = client.Execute(request);
 var content = response.Content;

Console.WriteLine(content);

}

private static X509Certificate2 GetCertificate()
 {
 X509Certificate2 certificate = null;
 var certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
 certStore.Open(OpenFlags.ReadOnly);
 var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, Thumbprint, false);

 if (certCollection.Count &gt; 0)
 {
 certificate = certCollection[0];
 }
 certStore.Close();
 return certificate;
 }

private static async Task&lt;string&gt; GetAccessToken(X509Certificate2 certificate)
 {
 var authenticationContext = new AuthenticationContext(Authority, false);
 var cac = new ClientAssertionCertificate(ClientId, certificate);
 var authenticationResult = await authenticationContext.AcquireTokenAsync(GraphUrl, cac);
 return authenticationResult.AccessToken;
 }
 }

El último paso es publicar la aplicación como un WebJob de Azure. Para ello, haciendo click en botón derecho sobre el proyecto de consola, seleccionaremos la opción Publish as Azure WebJob

public1

A continuación, indicamos la planificación del WebJob:

public2

Seleccionamos la aplicación web a la que queremos asociar el WebJob:

public3

Por último publicamos el WebJob.

public4

Y esto es todo, podemos probarlo ejecutando una vez el WebJob en Azure y ver que al final, se devuelven los contactos del usuario que le hemos indicado.

Captura de pantalla 2016-01-24 a las 19.05.09

Hasta aquí el post de hoy. Con lo que hemos visto en este post, podemos consumir información de Office 365 desde aplicaciones en background que no nos permiten usar el flujo habitual de autenticación del protocolo OAuth2.

Espero que os haya resultado interesante, en futuros post usaremos todo lo que hemos visto hoy para indexar contenido de Office 365 en Azure Search a través de un WebJob como el que hemos creado hoy.

Hasta la próxima

 

 

Primeros pasos con Azure Search: Los índices

Muy buenas a todos.

Hoy, quiero empezar a hablar sobre un servicio al que tenía muchas ganas de dedicarle un tiempo, el servicio Azure Search. A lo largo de los próximos días haremos un overview completo sobre este servicio y veremos cómo funciona y qué podemos hacer con él.

El servicio Azure Search permite añadir una robusta experiencia de búsqueda a nuestras aplicaciones usando una API REST o una SDK .NET sin gestionar la infraestructura de búsqueda o llegar a ser un experto en búsqueda.

En el siguiente enlace, podréis ver una descripción más profunda sobre este servicio:

https://azure.microsoft.com/en-us/documentation/articles/search-what-is-azure-search/

En el post de hoy, vamos a  ver cómo configurar el servicio de búsqueda y el primer paso a la hora de poder comenzar a trabajar con el mismo, los índices.

Configurando el servicio de búsqueda en Azure

Lo primero que debemos hacer es aprovisionar el servicio de búsqueda. Para ello, en el nuevo portal de Azure, iremos a Nuevo->Datos y almacenamiento->Búsqueda de Azure, como se ve en la siguiente imagen.

Captura de pantalla 2016-01-16 a las 16.08.41

A continuación, tenemos que indicar los datos básicos de configuración del servicio: el nombre del servicio, el grupo de recursos al que pertenece, la ubicación y el nivel de precios.

Captura de pantalla 2016-01-16 a las 16.11.14

Para este servicio disponemos de dos niveles de precios, con diferentes características que harán que en función de la finalidad del uso del servicio, elijamos uno u otro.

Captura de pantalla 2016-01-18 a las 23.27.48

Una vez configurados todos los parámetros, pulsamos sobre crear y el servicio se aprovisionará, con lo que ya lo tendremos listo para usar.

Los índices en Azure Search

Un índice es el medio principal para organizar y buscar documentos en el servicio de búsqueda de Azure, similar a cómo se organizan los registros en una tabla de una base de datos. Cada índice tiene una colección de documentos que cumplen el esquema de índice (nombres de campo, tipos de datos y propiedades), pero los índices también especifican construcciones adicionales (proveedores de sugerencias, perfiles de puntuación y configuración de CORS) que definen otros comportamientos de la búsqueda.

Por tanto es necesario, como paso previo a subir documentos al servicio de búsqueda, definir un índice y su estructura, que no es más que una estructura de tablas que acepta datos y consultas. Los índices en el servicio de búsqueda de Azure, se pueden crear de tres formas, o desde el propio portal de Azure o por medio de código usando una SDK de .NET o una API REST.

A continuación, vamos a ver como crear un índice por medio de la SDK y la API REST en un solución de consola de Visual Studio.

Creando índices en Azure Search

Para ello, vamos a crear una aplicación de consola en Visual Studio. Una vez creada, tenemos que añadir las referencias a la SDK de Azure Search. Esto lo conseguiremos ejecutando en la consola de Nuget el siguiente comando:

Install-Package Microsoft.Azure.Search -Pre

Nos instalará todas las referencias necesarias para poder trabajar con la SDK correspondientes. Además, para el resto del ejemplo necesitaremos añadir otras dos referencias:

System.Configuration (Con la que tendremos la posibilidad de hacer referencia al App.Config de nuestra aplicación)

System.Net (Necesaria para poder llamadas REST desde la aplicación de consola).

Una vez añadidas todas las referencias, podemos pasar a ver el código. Para la aplicación de consola hemos creado un sencillo menú que nos permite elegir entre las dos opciones que tiene nuestra aplicación, crear un índice usando la SDK, o crear un índice por medio de API REST. Este es el código que implementa el menú:


class Program
 {
 static void Main(string[] args)
 {
 int option;

do
 {
 option = menu();
 switch (option)
 {
 case 1:

SearchServiceClient serviceClient = GetSearchServiceClient();

DeleteIndexIfExists(serviceClient,"files");
 CreateIndexUsingNetSDK(serviceClient,"files");

Console.WriteLine("Index successfully created");

break;
 case 2:

SearchServiceClient serviceClient2 = GetSearchServiceClient();

DeleteIndexIfExists(serviceClient2,"files");

CreateIndexUsingRESTAPI("files");

break;
 default:
 break;
 }
 }
 while (option != 0);
 }

private static int menu()

 {
 int value = 0;

Console.WriteLine("-----------------------------------");
 Console.WriteLine("1.- Create an index using .NET SDK");
 Console.WriteLine("2.- Create an index using REST API");
 Console.WriteLine("0.- Exit");
 Console.WriteLine("-----------------------------------");

do
 {
 Console.WriteLine("Enter an valid option: ");
 value = Int16.Parse(Console.ReadLine());
 }
 while (value &lt; 0 &amp;&amp; value &gt; 2);

return value;
 }

}

Como veréis, este código hace referencia a cuatro funciones, que son la clave de este post y que son en las que nos vamos a centrar para describir a continuación.

GetSearchServiceClient: Esta función nos va a devolver un objeto de tipo SearchServiceClient que es el que nos permite interaccionar con el servicio de búsqueda.

private static SearchServiceClient GetSearchServiceClient()
{
string serviceName = ConfigurationManager.AppSettings["SearchServiceName"];
string apiKey = ConfigurationManager.AppSettings["ApiKey"];

SearchServiceClient serviceClient = new SearchServiceClient(serviceName, new SearchCredentials(apiKey));

return serviceClient;
}

Este método solo se encarga de crear un nuevo objeto de tipo SearchServiceClient. El constructor de esta clase, recibe dos parámetros: el nombre del servicio que podemos obtener de la URL del servicio (https://%5Bnombreservicio%5D.search.windows.net) y la api-key para la autenticación del servicio. Ambos parámetros, para el ejemplo, los he almacenado en el App.Config de la aplicación de consola.

DeleteIndexIfExists: Una buena práctica, es comprobar si el índice existe previamente antes de crearlo y si es así, eliminarlo. De esto se encarga la función que vamos a ver a continuación:

private static void DeleteIndexIfExists(SearchServiceClient serviceClient, string indexName)
{
if (serviceClient.Indexes.Exists(indexName))
serviceClient.Indexes.Delete(indexName);
}

CreateIndexUsingNetSDK: Este método, crea un índice usando la SDK .NET de Azure Search.

private static void CreateIndexUsingNetSDK(SearchServiceClient serviceClient, string indexName)
{
var index = new Index()
{
Name = indexName,
Fields = new[]{
new Field("DocumentId",DataType.String) { IsKey = true, IsRetrievable = true, IsFilterable = true},
new Field("Name", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true},
new Field("Url", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true},
new Field("CreatedDate", DataType.String) { IsRetrievable = true, IsSearchable = true, IsFilterable = true}
}
};

serviceClient.Indexes.Create(index);
}

El método recibe como parámetros el objeto que hace referencia al servicio de búsqueda y el nombre del índice que vamos a crear. A continuación crea un objeto de tipo Index y le indica el nombre y los campos que va a tener dicho índice.

Cada campo se crea por medio de un objeto de tipo Field. El constructor de dicho objeto tiene dos parámetros, el nombre del campo y el tipo del mismo. Luego, podremos indicar otras propiedades de cada campo, como se ve en el ejemplo.

Por último, se crea el índice propiamente dicho con la llamada serviceClient.Indexes.Create(index) que vemos al final de la función.

CreateIndexUsingRESTAPI: La última función, crea un índice por medio de una llamada API REST.:

private static void CreateIndexUsingRESTAPI(string indexName)
{
string serviceName = ConfigurationManager.AppSettings["SearchServiceName"];
string apiKey = ConfigurationManager.AppSettings["ApiKey"];

string body = @"{
'name': '" + indexName + @"',
'fields': [
{'name': 'DocumentId', 'type': 'Edm.String', 'key': true, 'searchable': true},
{'name': 'Name', 'type': 'Edm.String'},
{'name': 'Url', 'type': 'Edm.String'},
{'name': 'CreatedDate', 'type': 'Edm.String'}
]
}";

using(var client = new HttpClient())
{
client.BaseAddress = new Uri("https://" + serviceName + ".search.windows.net");

client.DefaultRequestHeaders.Add("api-key", apiKey);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = client.PostAsync("/indexes?api-version=2015-02-28", new StringContent(body,Encoding.UTF8, "application/json")).Result;

if(response.IsSuccessStatusCode)
{
Console.WriteLine("Index successfully created");
}
else
{
Console.WriteLine("HTTP Status: " + response.StatusCode.ToString() + " - Reason: " + response.ReasonPhrase);
}
}
}

Esta función en primer lugar, crea una cadena de texto con la estructura JSON del índice, y la almacena en la variable body. A continuación, establece la URL base del servicio REST de Azure Search (https://%5Bnombreservicio%5D.search.windows.net).

Tras esto, hace la llamada haciendo uso de la clase HttpClient. A esta llamada, de tipo POST y con la URL (/indexes?api-version=2015-02-28), hay que añadirle en las cabeceras la api-key del servicio.

Una vez que se recibe la respuesta, podremos comprobar si hemos recibido un estado correcto, en cuyo caso el índice se habrá creado correctamente, o no.

Probando el ejemplo
Una vez terminado el código, si depuramos el ejemplo nos aparece una pantalla como la siguiente:

test

Pulsando sobre cualquier de las dos opciones, veremos que se ejecuta correctamente, y si accedemos posteriormente al portal de Azure, al servicio de búsqueda, veremos que el índice se ha creado.

Captura de pantalla 2016-01-18 a las 20.44.17
Os voy a dejar algunos enlaces en los que me he basado y que os pueden resultar de interés.

https://azure.microsoft.com/en-us/services/search/

https://azure.microsoft.com/en-us/documentation/articles/search-get-started/

https://azure.microsoft.com/en-us/documentation/articles/search-howto-dotnet-sdk/

https://azure.microsoft.com/en-us/documentation/articles/search-create-service-portal/

Y esto es todo hasta aquí, en este post, hemos configurado y puesto en marcha el servicio de búsqueda creando los índices. En próximos posts, comenzaremos a indexar contenido y veremos cómo podemos hacerlo y consumiremos el servicio de búsqueda con todas las opciones de que disponemos para trabajar con el mismo.

Espero, como siempre, que os haya resultado interesante.

Hasta la próxima.

Desplegando Logic Apps desde Visual Studio

Hola de nuevo a todos,

Continuamos con la actividad del blog en este 2016, hablando sobre servicios de Azure. En anteriores entradas, os había hablado mucho sobre las Logic Apps de Azure:

https://elblogdelprogramador.wordpress.com/2015/10/10/azure-logic-apps-i-primeros-pasos/

https://elblogdelprogramador.wordpress.com/2015/10/11/azure-logic-apps-ii-que-mas-puedo-hacer/

https://elblogdelprogramador.wordpress.com/2015/10/24/azure-logic-apps-iii-creando-conectores-personalizados-las-api-apps/

Una duda que me surgió mientras probaba este servicio de Azure tenía que ver con la posibilidad de crear las Logic Apps desde Visual Studio, frente a la opción de hacerlo desde el portal de Azure usando el diseñador, como había estado haciendo en todas las entradas anteriores.

Obviamente, la posibilidad de usar Visual Studio no es un simple capricho. Esto, nos da la oportunidad de integrar las Logic Apps en el ciclo ALM de nuestro proyecto, poder usar nuestro Control de Código Fuente, gestionar las versiones de desarrollo y pruebas de una forma automatizada, etc.

En la entrada de hoy vamos a ver cómo podemos desplegar una Logic App desde Visual Studio. Para poder hacer esto, antes de nada, debemos tener instalada la SDK de Azure en nuestro equipo, que se puede descargar de aquí.

Una vez instalada, vamos a crear el proyecto en Visual Studio: New Proyect->Cloud->Azure Resource Group

Captura de pantalla 2016-01-16 a las 12.56.18

Captura de pantalla 2016-01-16 a las 12.57.40

Una vez indiquemos la opción de la plantilla de proyecto de Visual Studio, nos aparece una pantalla que nos solicita la plantilla de recurso de Azure que queremos seleccionar. En este paso, seleccionaremos Logic App

Captura de pantalla 2016-01-16 a las 12.58.10

Con esto nos crea el proyecto con la plantilla adecuada y con una estructura como la siguiente:

Captura de pantalla 2016-01-16 a las 12.58.36

La parte importante de esta plantilla son los archivos dentro de la carpeta Templates. Como podéis ver, hay dos archivos:

  • LogicApp.json: en este archivo se define toda la Logic App, la definición de los parámetros necesarios para su configuración y el código propio de la Logic App. Este archivo json incluye una sección llamada definition donde se puede añadir el código de la Logic App. Como ya comenté en anteriores entradas, las Logic Apps se pueden crear por medio del diseñador del portal de Azure, o por medio de un archivo json donde se indicarán los conectores que la componen y demás. Este código es el que podemos incluir en la sección definition de este archivo.
  • LogicApp.parameters.json: es un archivo adicional donde se especifica el valor de los parámetros de configuración de la Logic App

Si lo que queremos, es deplegar nuestra Logic App, haremos lo siguiente:

Captura de pantalla 2016-01-16 a las 13.14.15

Esto, nos va a desplegar una pantalla como la siguiente, en la que especificaremos, la subscripción de Azure donde queremos publicar la Logic App, el grupo de recursos al que pertenece y los ficheros con la definición y parámetros de la Logic App que vimos anteriormente.

Captura de pantalla 2016-01-16 a las 13.14.52

Antes de publicar la Logic App, deberemos hacer click sobre la opción «Edit Parameters» para establecer los parámetros obligatorios para que la Logic App se pueda desplegar correctamente, (el nombre de la Logic App y el Plan de Servicios de la misma).

Captura de pantalla 2016-01-16 a las 13.15.03

Tras esto, guardamos y ya podemos publicar la Logic App haciendo click en la opción Deploy.

Y esto es todo, de esta manera podremos trabajar con las Logic Apps desde Visual Studio, con las opciones que eso nos ofrece para poder integrarlas correctamente en nuestros ciclos de desarrollo.

Os dejo un enlace al artículo de Azure donde encontré la información sobre cómo hacer esto:

https://azure.microsoft.com/en-us/documentation/articles/app-service-logic-deploy-from-vs/

Espero que os haya resultado interesante.

Hasta la próxima.

[Evento] Potencia tus desarrollos de SharePoint con Azure

Muy buenas a todos, y antes de nada Feliz Navidad a todos los que habitualmente entran a «El blog del programador».

Hoy os quiero hablar del próximo evento que se va a celebrar, organizado por la comunidad de usuarios de SharePoint de Madrid, MadPoint, y que tendrá lugar el próximo 15 de Enero en Wayra en la calla Gran Via, 28.

En dicho evento, tendremos la oportunidad de profundizar en las oportunidades que nos ofrece Azure para usarla en nuestros desarrollos de SharePoint, tanto OnLine como OnPremise. Os dejo el enlace de la página de madpoint donde encontraréis toda la información sobre el evento

http://www.madpoint.net/2015/12/23/evento-potencia-tus-desarrollos-de-sharepoint-con-azure/

La agenda del evento, en donde tendré la oportunidad de aportar mi granito de arena, es la siguiente:

  • 16.00 – 16.15: Bienvenida e introducción
  • 16.15-16.50: Diseña tu propio Office 365 con Azure IaaS y PaaS
    • En esta sesión teórica, Miguel Tabera (MVP de Office Servers and Services) nos enseñará, desde el punto de vista de arquitectura, cómo es posible utilizar máquinas virtuales y servicios como las web apps, Azure Search, Media Services y Application Insights para diseñar nuestro propio servicio similar a Office 365 en el que proporcionemos SharePoint, Exchange, Office Vídeo, etc.
  • 17.00-17.50: Logic apps o el futuro de los flujos de trabajo
    • ¿Qué son las logic apps? ¿Cómo las podemos utilizar? ¿Se convertirá en el motor para desarrollar nuestras lógicas de negocio y flujos de trabajo en el futuro? En esta sesión, Jose Carlos Rodríguez Avilés, nos enseñará qué podemos hacer con este servicio de Azure y cómo podemos usarlo para implementar lógicas de negocio interconectando entre si la amplia gama de herramientas que usamos hoy en día.
  • 18.00-18.50: Timerjobs y eventos en SharePoint Online usando Hangfire
    • Cristian Ruiz nos mostrará un ejemplo práctico de cómo crear timerjobs y eventos remotos (evitando los límites de tiempo de SharePoint online) utilizando el motor de tareas programadas.

Como podéis ver, las ponencias son muy interesantes, os animo a seguir de cerca la información del evento, y a que participéis en el mismo. Poco a poco, desde MadPoint iréis recibiendo más información, desde twitter, linkedin y la página de web, para todos aquellos que podáis estar interesado.

Un saludo, y por si acaso que tengáis una muy buena entrada del año 2016.

 

Versión 1.0 de la API de Office 365: Microsoft Graph

Muy buenas a todos.

Hace unos meses, desde Microsoft se lanzó lo que se denominó «Office 365 unified API» en su versión preview. El objetivo, era agrupar en un mismo endpoint, todas las APIs que permitieran el acceso a los distintos servicios en la nube que se ofrecen y hacerlo siguiendo el estándar de la industria, por medio de una API REST. Esto supuso un importante avance en la forma en que se podía acceder a los servicios en la nube. Sobre todo esto hablé en una entrada del blog, en la que os contaba cómo usar esta API, que os dejo a continuación:

La nueva API de Office 365 Unificada

Lo que os quiero contar hoy, es que recientemente, se ha publicado la v1.0 de esta API que desde ahora pasará a llamarse Microsoft Graph y que incluye una serie de servicios que dejan de estar en Preview y que según nos dicen pueden ya ser usados con todas las garantías en nuestros proyectos finales.

Today-at-Connect-1

Como dice en la página principal de la documentación y de la que os dejo el enlace más adelante:

One endpoint to rule them all
No more obtaining separate tokens for different services or calling a different endpoint for each API.
Leverage the power of Microsoft Graph, a unified API endpoint, for accessing data, intelligence, and insights coming from the Microsoft cloud.

Más que entrar en detalle en cómo podemos usarla, quería dejaros una serie de enlaces interesantes e información sobre la misma, ya que la forma de uso sigue siendo muy similar a la que ya os comenté en el artículo al que me he referido anteriormente.

Para usar esta primera versión, lo único que tendremos que hacer es cambiar el endpoint. Si antes accedíamos a la API a través del siguiente enlace:

https://graph.microsoft.com/beta

Ahora lo haremos a través de este:

https://graph.microsoft.com/v1.0

La versión beta sigue estando disponible, y es donde encontraremos todo el conjunto de opciones disponibles, los que ya han pasado a la primera versión, y los que aún se encuentran en preview. Evidentemente se puede seguir usando esta preview, aunque desde Microsoft no recomiendan hacerlo para proyectos finales (como cualquier versión de estas características). En el siguiente enlace podéis ver los distintos servicios que se ofrecen en una versión y otra:

http://graph.microsoft.io/docs

Y aquí entra otro de los motivos que más me ha sorprendido, y es la cantidad de documentación que Microsoft se ha encargado de generar para que la adopción de esta API sea relativamente rápida. Y  no es que desde Microsoft no se genere documentación suficiente sobre cómo usar sus SDK´s o todo lo que ponen a disposición de los desarrolladores, es que para Microsoft Graph lo han hecho de una forma ligeramente diferente, que a mi particularmente me gusta (me recuerda más a como encontramos la documentación para la cantidad de proyectos que tenemos disponible para desarrolladores hoy en día, por decirlo de alguna forma, más actual).

Toda la información sobre esta API la podemos encontrar en:

http://graph.microsoft.io

En Channel 9 tenéis este vídeo, muy recomendable, donde podéis ver en 11 minutos bastante información sobre Microsoft Graph:

https://channel9.msdn.com/Events/Visual-Studio/Connect-event-2015/301

Si queréis testear y probar los endpoint, encontraréis a vuestra disposición este enlace:

https://graphexplorer2.azurewebsites.net/

Y bueno, os dejo, una serie de enlaces más para que podáis encontrar más información:

https://blogs.office.com/2015/11/18/today-at-connect-introducing-the-microsoft-graph/

http://dev.office.com/getting-started/office365apis

http://dev.office.com/chooseapiendpoint

Y esto es todo por hoy, espero que lo encontréis interesante y os animo a que le echéis un vistazo a toda la información que hay.

Un saludo a todos

Paginando en SharePoint 2013 con API REST

Muy buenas a todos,

Hoy quería contaros un tema con el que me he estado peleando hoy en mi proyecto con el que estoy haciendo un uso bastante intensivo de la API REST de SharePoint con AngularJS. Una experiencia que os debo decir, me está encantando.

El tema ha venido a la hora de «paginar» una consulta en SharePoint que estaba haciendo vía API REST. Según pensaba, usando las opciones $top y $skip se podría hacer la paginación sin problemas. Para ello pensaba usar el endpoint que habitualmente uso para trabajar con las listas de SharePoint

http://<misitio>/_api/web/lists/getbytitle(‘lista&#8217;)/items

Mi sorpresa ha sido darme cuenta que con este endpoint la opción $skip no funciona. Indagando un poco he descubierto que efectivamente, esta opción no funciona para lista de elementos, solo funciona para colecciones de datos como colecciones de listas.

http://sharepoint.stackexchange.com/questions/45719/paging-using-rest-odata-with-sp-2013

https://msdn.microsoft.com/en-us/library/office/fp142385.aspx

Para hacer la paginación via API REST podemos usar el antiguo endpoint OData V2 listdata.svc. Con esta versión si funciona la opción $skip correctamente:

http://<misitio>/_vti_bin/ListData.svc/<lista&gt;

Ejemplo: http://<misitio>/_vti_bin/ListData.svc/<lista&gt;?$top=2&$skip=2

Salvando este inconveniente sobre el endpoint que debemos usar, usando estas dos opciones $top y $skip, podremos paginar nuestras consultas de una forma muy sencilla.

Y esto es todo por hoy, espero que os resulte útil, como siempre, y que si os habéis encontrado con esta problemática, tardéis menos tiempo en resolverlo.

Saludos.

[OffTopic]

No suelo acostumbrar a hacer nada de esto. Pero hoy ha nacido mi sobrino, del que tendré la oportunidad además de ser su padrino. Así que esta entrada de hoy va dedicada a él y a sus padres. Aunque no lo podré conocer hasta dentro de 15 días porque me ha salido «conejero» y está en Lanzarote, que ilusión más grande.

Usando el nuevo modelo de desarrollo para SharePoint con PowerShell

Muy buenas a todos,

Hace unos meses, escribí acerca del nuevo modelo de desarrollo para SharePoint OnLine y SharePoint OnPremises propuesto por Microsoft e incluso una de mis colaboraciones en CompartiMOSS giró en torno a este tema.

Nuevo modelo de desarrollo de Sharepoint. Adaptando nuestras soluciones de granja

Número #24 de CompartiMOSS y nueva colaboración con la revista

Como ya decía en aquella ocasión, trabajar con las API cliente se podría hacer tanto por medio de la API REST, con la API CSOM o JSOM o incluso PowerShell. Tenía muchas ganas de ver cómo se podría trabajar con éste último y para un proyecto en el que estoy trabajando recientemente decidí que ya era el momento.

La primera intención, fue desarrollar mis propios Cmdlets o mis propios Scripts con funciones para realizar las distintas operaciones que fuese necesitando. Finalmente decidí previamente indagar por la cuenta de GitHub de OfficeDev/Pnp, donde encontré un gran trabajo especifico sobre PowerShell, proporcionando una gran cantidad de Cmdlets desarrollados que permiten trabajar con las API Cliente, concretamente CSOM, y PowerShell. Por supuesto, trabajo que decidí utilizar, y que os recomiendo a todos.

https://github.com/OfficeDev/PnP-powershell

En el artículo de hoy, os quiero mostrar cómo instalar y configurar en nuestro servidor estos Cmdlets y cómo se pueden usar algunos de ellos a modo de ejemplo. No obstante, en la página de Pnp hay una documentación muy buena sobre todas las opciones de que disponemos.

Instalando los Cmdlets en el servidor

Para poder tener disponibles todos los Cmdlets de PowerShell tendremos que seguir los siguientes pasos:

1.- En primer lugar descargar el proyecto Visual Studio desde la cuenta de GitHub de OfficeDev/Pnp-PowerShell.

download

2.- Para poder instalar el proyecto, es necesario descargar e instalar las WiX Tools en nuestro equipo.

wix

3.- A continuación abrimos la solución que descargamos anteriormente y para poder crear la solución, necesitamos agregar dos paquetes desde Nugets. El primero de ellos es el OfficeDev Core para SharePoint Online o OnPremises, en función de para qué lo vayamos a usar.

coreoffice

4.- El siguiente paquete es la librería ADAL para la autenticación.

identity

5.- Tras esto ya se puede hacer el build del proyecto lo cual dejará instalados los Cmdlets en nuestro equipo

install

Si ahora abrimos por ejemplo el IDE de PowerShell, en la lista de comandos disponibles, si ponemos en el cajón de búsqueda SPO, filtrará todos los comandos que se han añadido.

Usando los nuevo Cmdlets

A continuación voy a mostrar un breve ejemplo de cómo podríamos usar los nuevos Cmdlets con PowerShell.

Connect-SPOnline -Url $url -Credentials (Get-Credential)

Add-SPOField -DisplayName "Example" -InternalName "Example" -Group "ExampleSPO" -Type Integer
Add-SPOField -DisplayName "Example1" -InternalName "Example1" -Group "ExampleSPO" -Type Text
Add-SPOField -DisplayName "Example2" -InternalName "Example2" -Group "ExampleSPO" -Type Choice -Choices "uno","dos","tres"

Add-SPOContentType -Name "ContentTypeExample" -Description "Description to Content Type" -Group "ExampleSPO"

Add-SPOFieldToContentType -Field "Example" -ContentType "ContentTypeExample"
Add-SPOFieldToContentType -Field "Example1" -ContentType "ContentTypeExample"
Add-SPOFieldToContentType -Field "Example2" -ContentType "ContentTypeExample"

New-SPOList -Title "List Title" -Template GenericList -EnableContentTypes
Add-SPOContentTypeToList -List "List Title" -ContentType "ContentTypeExample" -DefaultContentType

En el código de ejemplo se muestra cómo conectarse a un sitio de SharePoint OnLine, crear columnas de sitio, un tipo de contenido y asociarlo a una lista que se ha creado previamente.

Y esto es todo por hoy, por si aún no lo conocíais, espero que os sea de utilidad y que en la medida de lo posible, podáis usarlo en vuestros proyectos.

Hasta la próxima.