Mostrando entradas con la etiqueta Timer Job. Mostrar todas las entradas
Mostrando entradas con la etiqueta Timer Job. Mostrar todas las entradas

miércoles, 1 de julio de 2015

Cómo crear un Timer Job de SharePoint desde Visual Studio 2010

La creación de Timer Jobs en SharePoint es una potente herramienta para el desarrollo de aplicaciones personalizadas en SharePoint, gracias a los cuales, podemos ejecutar de forma desatendida y planificada el código que deseemos, y además, ejecutarlo fuera del IIS (interesante para código que pueda necesitar ejecuciones de larga duración). El presente artículo describe cómo crear un Timer Job de SharePoint 2010 paso a paso con Visual Studio 2010.

Un Timer Job es una tarea ejecutable que corre sobre uno o varios servidores de forma desatendida en base a una planificación, un concepto similar a los Jobs del Agente de SQL Server. Los Timer Jobs resultan de gran utilidad para descargar al IIS de las tareas de larga ejecución y de las tareas periódicas, que pasarán a ser gestionadas por el servicio SharePoint 2010 Timer. Existen multitud de Timer Jobs que vienen OOB con el propio producto, que varían en función de la edición de SharePoint que se trate, y adicionalmente, podemos desarrollar nosotros nuestros propios Timer Jobs, por lo que en consecuencia también podremos encontrar muchos Timer Jobs correspondientes a aplicaciones de terceros.
Cada Timer Job tiene un alcance (Scope), es decir, un tipo de objeto que indica a qué nivel jerárquico trabajará el Timer Job, existiendo tres posibilidades:
  • La Granja.
  • Un Servidor.
  • Una Base de Datos de Contenido.
Es decir, un Timer Job se ejecutará una vez por Granja, una vez por Servidor, ó una vez por Base de Datos de Contenido. De hecho, esto queda reflejado en los tres posibles valores de la enumeración SPJobLockType:
  • Job. El Job se ejecuta una vez por Granja. Un ejemplo sería el Job CEIP data collection job.
  • None. El Job se ejecuta una vez por Servidor. Cada servidor de la Granja tiene/posee (no se muy bien cómo describirlo) una Instancia del Job. Un ejemplo, sería el Config Refresh job.
  • Content Database. El Job se ejecuta una vez por Base de Datos de Contenido. Un par de ejemplos serían el Job de Immediate Alerts Jobs y el Job de Recycle Bin cleanup.
Para crear un Timer Job, deberemos crear una clase del tipo SPJobDefinition, la cual deberá tener un par de constructores, además de sobrescribir el método Execute(). Finalmente, necesitaremos una Característica (Feature), para a través de los Eventos de Activación y Desactivación de la misma (FeatureActivated y FeatureDeactivating) registrar y deregistrar nuestro Timer Job en la Granja de SharePoint sobre la que estemos desplegando nuestra Solución.

Creación de un Timer Job paso a paso con Visual Studio 2010

En el siguiente ejemplo, vamos a crear paso a paso un Timer Job que se ejecutará una vez por Granja (Scope Farm), utilizando Visual Studio 2010.
Crearemos un nuevo Proyecto en Visual Studio 2010 de tipo Empty SharePoint Project, asegurándonos de seleccionar el Net Framework 3.5 y asignaremos el nombre que deseemos para el Proyecto (en nuestro caso, lo llamaremos MyTimerJob). En el Wizard para la creación del Proyecto, seleccionaremos la opción Deploy as a farm solution.
Seguidamente crearemos una nueva clase pública (no olvidar añadir el modificador de acceso public) que herede de SPJobDefinition, para lo cual deberemos crear un par de constructores y sobrescribir el método Execute(), además de añadir al menos un par de sentencias using.
Seguidamente crearemos una nueva clase pública que herede de SPJobDefinition
De los dos constructores:
  • El constructor por defecto no lo modificaremos.
  • En el otro constructor, llamaremos al constructor base, pero deberemos especificar el nombre del Job (Title). También deberemos especificar el tipo de bloqueo del Job utilizando la enumeración SPJobLockType, lo cual está relacionado con el alcance (Scope) del propio Job (lo comentamos al principio de este artículo). En nuestro caso de ejemplo, como deseamos crear un Job para ejecutarse una vez por Granja,utilizaremos el tipo de bloqueo SPJobLockType.Job. Y por último, para el parámetro Server del constructor base, deberemos especificar una instancia de la clase SPServer si el Job tiene de alcance un Servidor (Scope Server) o null si el Job no está asociado a ningún Servidor (en nuestro caso especificaremos null).
Por otro lado, el método Execute() recibe como parámetro un objeto de tipo GUID, el cual, cuando el alcance (Scope) del Job es la Base de Datos de Contenido representará una referencia a la Base de Datos de Contenido sobre la que se está ejecutando la instancia actual del Job. En el resto de casos (como en el nuestro), será null.

Despliegue del Timer Job

Una vez que ya hemos desarrollado la clase de nuestro Timer Job, tenemos que preparar su despliegue. Para ello, añadiremos una Característica (Feature) a nuestro Proyecto de Visual Studio 2010, la configuraremos con un alcance a nivel de Aplicación Web (Scope Web Application), y añadiremos un Event Receiver a nuestra Característica, donde incluiremos el código para el despliegue y eliminación de nuestro Timer Job (FeatureActivated y FeatureDeactivating).
Añadiremos una Característica (Feature) a nuestro Proyecto, sobre la que añadiremos un Event Receiver
A continuación podemos ver un código de ejemplo para la activación y desactivación de un Timer Job.
FeatureActivated y FeatureDeactivating

Despedida y Cierre

Hasta aquí llega el presente artículo, en el cual hemos intentado presentar la forma de desarrollar un Timer Job de SharePoint 2010 con Visual Studio 2010, una tarea que puede resultarnos de utilidad en multitud de ocasiones. Por último, antes de acabar, aprovecho para añadir algunos enlaces de interés, para quien desee ampliar más información:

domingo, 21 de julio de 2013

SharePoint 2010 - Depurar Timer Jobs

En este post vamos a explicar cómo poder depurar nuestros Timer Jobs. Como Timer Job de ejemplo vamos a usar el que creamos en el post anterior.

Lo primero que debemos de hacer es ponernos encima del nombre del proyecto, pulsar botón derecho del ratón y pulsar la opción Implementar para instalar nuestro Timer Job.


Lo siguiente que debemos hacer es añadir el punto o puntos de interrupción en nuestra clase de definición del Timer Job.

Una vez hecho eso vamos al menú Herramientas > Asociar al proceso…


Se nos mostrara una ventana con los procesos corriendo actualmente en el equipo. La primera tarea a realizar en tener marcadas las opciones Mostrar los procesos de todos los usuarios y Mostrar los procesos de todas las sesiones. Una vez marcadas estas opciones buscamos el procesoOWSTIMER.EXE y pulsamos el botón Asociar.


Después solo queda esperar que el Timer Job se ejecute o sino directamente ir a la Administración Central de SharePoint e iniciar el Timer Job manualmente. Para iniciarlo manualmente ir a Administración Central de SharePoint > Supervisión > Trabajos del temporizador > Revisar definiciones de trabajo. Buscamos nuestro Timer Job y pulsamos sobre él.


Nos aparecerá una pantalla con información sobre el Timer Job. Pulsamos el botón Ejecutar ahora y ya solo queda esperar unos segundos para que la ejecución del Timer Job pare en nuestro primer punto de interrupción.

SharePoint 2010 - Crear un Timer Job

SharePoint 2010 - Crear un Timer Job

Vamos a explicar cómo crear un Timer Job para SharePoint 2010. Un Timer Job es un proceso el cuál corre en background y es lanzado cada cierta frecuencia de tiempo de igual manera que los servicios Windows.

Los Timer Jobs son manejados a través de un servicio de Windows llamadoSharePoint 2010 Timer, el cuál por defecto esta iniciado.



SharePoint 2010 dispone por defecto de bastantes Timer Jobs. Para una completa descripción de estos Timer Jobs visitad el siguiente enlace de la MSDN:

Timer Job reference

Ahora vamos a explicar cómo crear nuestro Timer Job. En el ejemplo vamos a crear un Timer Job el cuál cada 5 minutos minuto va a escribir un registro en la lista de Tareas.

Lo primero que debemos de hacer es abrir Visual Studio 2010 y crear un Proyecto vacío de SharePoint.

En la pantalla de qué tipo de solución crear elegimos la opción Implementar como solución de granja de servidores.

Una vez creado el proyecto agregamos una clase que será la definición de nuestro Timer Job. Esta clase debe heredar de la clase SPJobDefinitionubicada en el espacio de nombres Microsoft.Sharepoint.Administration. 

Code:
using Microsoft.SharePoint.Administration;

namespace JobDefinitionExample
{
    /// <summary>
    /// Heredamos de la clase SPJobDefinition
    /// </summary>
    public class JobDefinitionExample1 : SPJobDefinition


Agregamos 2 constructores a la clase. El primero sin parámetros y el segundo con parámetros que será el cuál usaremos.

Code:
 public JobDefinitionExample1()
            : base()
        {

        }

        public JobDefinitionExample1(string jobName, SPWebApplication webApplication)
            : base(jobName, webApplication, SPServer.Local, SPJobLockType.Job)
        {
 
                this.Title = "Timer job de ejemplo";
        }


Después debemos redefinir el método Execute que es donde deberemos incluir nuestra lógica, en nuestro caso escribir un registro en la lista de Tareas.

Code:
 //Sobreescribimos método Execute el cuál contiene la lógica del job.
        public override void Execute(Guid targetInstanceId)
        {
            
            //Obtenemos la referencia a la aplicación web

            SPWebApplication webApp = this.Parent as SPWebApplication;

            //Obtenemos referencia al sitio principal de nuestra colección de sitios
            SPWeb web = webApp.Sites[0].RootWeb;

            //Obtenemos una referencia a nuestra lista tareas
            SPList taskList = web.Lists.TryGetList("Tareas");

            //Creamos un nuevo registro en la lista
            SPListItem item = taskList.AddItem();

            item["Title"] = string.Format("Timer job de ejemplo paso a las {0}", DateTime.Now);

            //Persistimos en la BD de contenido
            item.Update();

        }


El siguiente paso es crearnos una característica cuyo ámbito debe serWebApplication, es decir la caraterística estará activada para todos los sitios de la aplicación web. Para cambiar el ámbito pulsar dos veces sobre el nombre de la característica y nos aparecerá la ventana de propiedades.



Una vez cambiado el ámbito a la característica le agregamos un receptor de eventos. Lo que vamos a hacer es al activar la característica instalar el Timer Job y al desactivarla eliminar el Timer Job.

El código a incluir en el método FeatureActivated para instalar el Timer Job sería el siguiente:

Code:
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {

            //Obtenemos una referencia al web application
            var webApp = properties.Feature.Parent as SPWebApplication;

            //Recorremos todos los Timer Job del web application
            foreach (var jobDefinition in webApp.JobDefinitions)
            {
                //Si nuestro Timer Job existe lo borramos
                if (jobDefinition.Name == JobName) jobDefinition.Delete();
            }

           //Instanciamos nuestra definición de Timer Job
            var listLoggerJob = new JobDefinitionExample1(JobName, webApp);


            //Definimos la opciones de inicio del Timer Job
            var schedule = new SPMinuteSchedule();

            schedule.BeginSecond = 0;
 
            schedule.EndSecond = 59;

            //Cada cuanto debe ejecutarse el TimeJob.
            //En este caso cada 5 minutos
            schedule.Interval = 5;
 
            listLoggerJob.Schedule = schedule;

            listLoggerJob.Update();

        }


Respecto cada cuanto está programado que se ejecute el Timer Job decir que en el ejemplo decimos que se debe ejecutar cada 5 minutos, por ello usamos la claseSPMinuteSchedule.

La cuestión es que podemos hacer que el Timer Job se ejecute en otro espacio de tiempo, por lo cual debemos usar otras clases diferentes a SPMinuteSchedule.

Todas las clases de las que disponemos son:

Clase SPOneTimeSchedule: Ejecuta el Timer Job en un rango de tiempo especificado. Referencia

Clase SPMinuteSchedule: Ejecuta el Timer Job en un número determinado de minutos (cada minuto o cada 200 minutos por ejemplo). Referencia

Clase SPHourlySchedule: Ejecuta el Timer Job cada hora. Referencia

Clase SPDailySchedule: Ejecuta el Timer Job diariamente. Referencia

Clase SPWeeklySchedule: Ejecuta el Timer Job semanalmente. Referencia

Clase SPMonthlySchedule: Ejecuta el Timer Job mensualmente. Referencia

Clase SPYearlySchedule: Ejecuta el Timer Job una vez al año. Referencia

El código a incluir en el método FeatureDeactivating para desinstalarlo sería:

Code:
      public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            //Obtenemos una referencia al web application
            var webApp = properties.Feature.Parent as SPWebApplication;

            //Recorremos todos los Timer Job del web application
            foreach (var jobDefinition in webApp.JobDefinitions)
            {
                //Si nuestro Timer Job existe lo borramos
                if (jobDefinition.Name == JobName) jobDefinition.Delete();
            }


        }


Una vez hecho esto ya solo queda activar la característica.

Para comprobar que el Timer Job está funcionando iríamos a la Administración Central de SharePoint > Supervisión > Trabajos del temporizador > Revisar definiciones de trabajo. Una vez dentro buscamos dentro de la lista nuestro Timer Job.