Ostatnio wspomniałem o walidowaniu pól w formularzach, teraz pora przejść do jeszcze fajniejszej funkcjonalności :) a mianowicie wykonywaniu analizy określonej X rzeczy w SharePoint 2010. Dlaczego X? dlatego, że jest to ograniczone tylko do waszej kreatywności :)

Zacznijmy od podstaw. SharePoint 2010 wprowadza tak zwane Health Analysis Rules, które są odpowiedzialne za chociażby sprawdzenie czy SPS został poprawnie skonfigurowany – można na to patrzeć jak webowy Best Pratices Analyzer, ale także jako maszynę, która umożliwia nam programistą weryfikowanie stanów naszej aplikacji. Jedynym mankamentem tego rozwiązania jest to iż działa ono wyłącznie po stronie Central Administration – jest to plus i minus, ale czy to trudne jest stworzyć sobie stronę dla site collection, która będzie wyświetlała odpowiednie informacje z Central Administration?

Jak otworzymy stronę Central Administration to w sekcji Monitoring mamy opcję Review problems and solutions.

sps_001

Możemy się do niej także dostać poprzez kliknięcie w lewym menu na Monitoring a następnie z sekcji Health Status kliknąć na Review problems and solutions.

sps_002

Teraz to co widzimy to są zasady, które zostały już uruchomione i wygenerowały informacje, że coś jest nie tak. Na przykład może to wyglądać tak:

sps_003

Na ekranie widzimy możliwość przejścia do definicji zasady poprzez View (w inny sposób Health Status ->Review rule definitions) oraz mamy dostępne tak naprawdę cztery akcje:

  1. Reanalyze Now – powoduje przeanalizowanie zasady jeszcze raz (wywołanie jej). Ogólnie nie udało mi się tego wykonać, po kliknięciu przycisk znika i nic :) ale to tylko jakaś tam beta więc się nie przejmuje :)
  2. Fix Automatically – powoduje wywołanie zaimplementowanej funkcji naprawy – o tym później. Ogólnie nie spotkałem się by to już działało :)
  3. Run Health Report – pewnie chodzi o uruchomienie/wygenerowanie raportu, ale to nie działa;
  4. Health Report Repair – dla śmiechu mówię, ze ta opcje to napraw raport, który nie działa ;) a skoro nie działa mi raport to zawsze klikam w tą opcję, która też nie działa :)

sps_004

To zanim przejdziemy jeszcze do opcji jak to zrobić z kodu, warto zajrzeć na szczegóły definicji zasady, która umożliwia nam definiowanie, kiedy zasada ma być uruchamiana i na jakich zasadach, oraz czy ma być automatycznie naprawiana.

sps_005

Warto wiedzieć, że nasze ustawienia będzie można potem zmieniać :) No ale to co tam jest, jest a lista nie umożliwia dodawania nowych elementów, dlatego tutaj wchodzimy z naszymi zdolnościami programistycznymi :)

Jak odkryłem jak się tworzy własne zasady

Stwierdziłem, że przed rozpoczęciem prac warto sobie zrobić listę pytań na które muszę znać odpowiedź, zanim napiszę pierwszą linię kodu (jeżeli w ogóle do tego dotrze):

1) Czy da się stworzyć własną zasadę?

2) Jak są zaimplementowane zasady, które istnieją?

3) Gdzie one są zaimplementowane?

4) Czy istnieje klasa bazowa czy jest to element na liście?

5) Jak stworzyć taką klasę/dodać element na listę?

6) Jak wgrać rozwiązanie na SharePoint?

Po pierwsze spojrzałem na adres URL: /Lists/HealthReports/AllItems.aspx, który za dużo nic nie mówi, ale podał mi nazwę, HealthReports. Następnie już z nazwą zajrzałem do .NET Reflectora i przeszukałem dllki SharePointowe w poszukiwaniu słowa kluczowego Health.

sps_006

Jest tego trochę, ale na liście znalazła się pozycja SPHealthAnalysisRule, która zwróciła moją uwagę.

sps_007

I wszystko stało się jasne, wystarczy klasę przeciążyć pomyślałem, jednakże jeszcze jedna rzecz nie dawała mi spokoju – brak funkcji napraw. Pomyślałem, że to może dlatego mi to nie działało, jednak przejrzałem jeszcze przestrzeń nazw Microsoft.SharePoint.Administration.Health i znalazłem klasę SPRepairableHealthAnalysisRule, która dziedziczy po SPHealthAnalysisRule i udostępnia opcję napraw:

sps_008

Jak już odkryłem to, to teraz pozostało mi jeszcze jedno pytanie jak to zainstalować? Przeszukałem wszystkie features, które zostały wgrane przy instalacji i nic nie odkryłem. Zaczynałem wątpić w możliwość wgrywania swoich zasad, do póki znów nie przyjrzałem się .NET Reflectorowi. Znalazłem tam klasę SPHealthRulesList, która dziedziczy po SPList. Bingo! To było to, zobaczyłem, że jest własność Local, która zwraca instancje listy, na którą mogę dodawać elementy.

Czyli wiedziałem już wszystko co wiedzieć powinienem :) zabrałem się za kodowanie. Na początku poszła zasada:

using Microsoft.SharePoint.Administration.Health;
using Microsoft.SharePoint.Administration;

namespace Gutek.SharePoint.Administration.Health
{
    public class DefaultSiteCollectionExist : SPHealthAnalysisRule
    {
        public override SPHealthCategory Category
        {
            get { return SPHealthCategory.Custom; }
        }

        public override SPHealthAnalysisRuleAutomaticExecutionParameters AutomaticExecutionParameters
        {
            get
            {
                SPHealthAnalysisRuleAutomaticExecutionParameters parameters = new SPHealthAnalysisRuleAutomaticExecutionParameters();
                parameters.Schedule = SPHealthCheckSchedule.Daily;
                parameters.Scope = SPHealthCheckScope.All;
                parameters.ServiceType = typeof(SPTimerService);
                return parameters;
            }
        }
 

        public override SPHealthCheckStatus Check()
        {
            bool error = false;

            // implementacja

            if (!error)
                return SPHealthCheckStatus.Passed;
            else
                return SPHealthCheckStatus.Failed;
        }

        public override SPHealthCheckErrorLevel ErrorLevel
        {
            get { return SPHealthCheckErrorLevel.Warning; }
        }

        public override string Explanation
        {
            get { return "User would not be able to access SharePoint by typing default URL address."; }
        }

        public override string Remedy
        {
            get { return "Create default site collection and a site."; }
        }

        public override string Summary
        {
            get { return "Rule checks if default site collection exists and contains a site."; }
        }
    }
}

Następnie instalacja jej za pomocą SPFeatureReceiver:

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration.Health;

namespace Gutek.SharePoint.Administration.Health
{
    public class HealthFeatureEventReceiver : SPFeatureReceiver
    {
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            // dodajemy nasz rule
            SPHealthRulesList.Local.AddItem(new DefaultSiteCollectionExist(), true);
        }

        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            // kasujemy wszystkie rule z danego assembly? a nie da sie pojedynczo?
            SPHealthRulesList.Local.DeleteItems(typeof(DefaultSiteCollectionExist).Assembly);
        }

        // not used feature methods
    }
}

Potem standardowe operacje na stsadm i boom :) zasada dodana i działa poprawnie – o dziwo :)

Podsumowanie

Ogólnie uważam tą funkcjonalność za wyśmienity dodatek, tak jak mnie wkurzyła walidacja i brak możliwości dodawaniu wielu walidatorów tak tutaj naprawdę MS pomyślał. Osobiście widzę mega zastosowanie tych zasad, na przykład mając kompleksowy produkt w oparciu o SharePoint możemy w łatwy sposób sprawdzać i informować administratorów o problemach konfiguracyjnych/wydajnościowych i innych. Dla większości klientów u których aplikacje SharePointowe były wdrażane czy to przeze mnie czy też przez firmę w której pracuje, było jedno wymaganie: użytkownik nie może zrobić kompletnie nic innego niż to na co mu nasza aplikacja zezwala, ale użytkownik ten może być administratorem – dziwne ale takie wymagania były. I teraz zdarzały się sytuację, że taki administrator potworzył sobie 50 list, dodał 10K elementów i sprawdzał sobie wydajność serwera. Taka zasada, może (1) poinformować tych mądrych adminów o tym, że ktoś się bawi na stronie, (2) naprawić automatycznie problem (kasując listy), (3) odciąć danemu użytkownikowi prawo do wejścia na stronę. Jak dla mnie bomba. Innym rozwiązaniem może być walidacja konfiguracji zapisanej w WebConfig, dla naszej aplikacji, pomysłów mam wiele i z chęcią jak będę mógł będę tą możliwość wykorzystywał w SharePoint.

A wy co o niej sądzicie? Nadaje się? :)