Zamiast wstępu
Jakiś czas temu Tom Hollander napisał na swoim blogu zdanie, z którym ciężko się nie zgodzić: 'Jeśli to prawda, że kobiety są z Wenus, a mężczyźni z Marsa, to prawdopodobnie można powiedzieć, że programiści i spece od infrastruktury są z różnych galaktyk' (w swobodnym tłumaczeniu). Wypowiedź ta była wstępem do tekstu o Manageability Extensions dla Enterprise Library 2.0 – zestawu pomocniczych bibliotek pozwalających na centralne zarządzanie i wspierających instrumentację aplikacji wykorzystującej entlib. Ciągnąc myśl ówczesnego PM od EntLib myślę, że można powiedzieć, że .NET Framework jest tym dla developera piszącego w C#, co AD i Group Policy dla administratora systemów opartych o MS Windows. Brak rozwiązań wspierających administrację aplikacjami w produkcie typu 'Enterprise' był wyraźnym niedopatrzeniem projektantów biblioteki. Na szczęście błąd został naprawiony i do wersji 2.0 napisane zostały Manageability Extensions w postaci zewnętrznej biblioteki, które w wersji 3.0 znalazły swoje miejsce wewnątrz samego Enterprise Library. W dalszej części skupiam się już na rozszerzeniach poświęconych Group Policy w Enterprise Library 3.x.
Właściwie po co mi to?
Dla programistów to pytanie nie jest bezzasadne. Napisali rewelacyjny program odpowiadający na złożone potrzeby biznesowe firmy i zadowoleni ze swojej pracy przekazują go specjalistom od wdrożeń i administracji. Ci jednak stwierdzają, że do wdrożenia na 100 stacjach potrzebują mnóstwo czasu, ponieważ konfiguracja aplikacji na każdej stacji dla każdego użytkownika musi być przeprowadzona osobno i wszelkie zmiany w konfiguracji wykonywane są ręcznie. A zatem tak prosta czynność jak przejście z bazy testowej – ważnej podczas wdrażania nowej aplikacji – na bazę produkcyjną, wymaga ręcznej zmiany connectionstrings na wielu stacjach. Podobnie sprawa się ma z ustaleniem miejsca składowania informacji diagnostycznych i administracyjnych generowanymi przez aplikację, a także innymi elementami konfiguracyjnymi dostępnymi wraz z Enterprise Library.
Zlokalizowanie wielu aspektów konfiguracyjnych w jednym miejscu pozwala na sprawniejsze zarządzanie zmianami w infrastrukturze firmy. Więcej informacji o zaletach i sposobach użycia Group Policy można znaleźć na stronach MSDN.
Słowo o Group Policy
Group Policy jest mechanizmem infrastrukturalnym ściśle związanym z Active Directory, pozwalającym na centralne zarządzanie polisami aplikacji, zarówno na poziomie komputera jak i użytkownika. Enterprise Library zawiera mechanizmy śledzenia zmian w Group Policy w oparciu o funkcje z rodziny *GPNotification z userenv.dll (a nie komunikaty WM_SETTINGCHANGE), dzięki czemu zmiany w GP trafiają bezpośrednio do konfiguracji aplikacji, w czasie jej działania.
Zmiany w Group Policy ustawione przez administratora domeny (może lepiej AD) na poziomie poszczególnych kontenerów AD propagują się na stacje klienckie powodując zmiany w rejestrze. Na poziomie poszczególnych stacji możemy również definiować odpowiednie polisy w ramach zasad lokalnych, korzystając z przystawki 'Edytor obiektów i zasad grupy' (Win XP), co wykorzystamy za chwilę przy testach.
Szczypta GPO Internals w EntLib 3.1
W ramach Enterprise Library 3.1 dostarczane jest wsparcie dla GP do wszystkich bloków poza VAB oraz PIAB. Poszczególne bloki zawierają podprzestrzenie .Configuration.Manageability w których dostarczane są klasy dziedziczące po klasie abstrakcyjnej Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Manageability.ConfigurationSectionManageabilityProviderBase<T> nadpisując odpowiednie metody i właściwości. Klasa ManageabilityHelper zajmuje się koordynacją dostawców dostarczanych przez wspomniane klasy i w miarę konieczności zleca wykonanie integracji zmian w konfiguracji poszczególnych bloków.
Sposób użycia
Oto prosty przykład ilustrujący podstawową funkcjonalność związaną ze wsparciem dla GPO w Enterprise Library. Z dostępnych bloków do testu wybieram Logging, głównie ze względu na prostotę konfiguracji i użycia. Dzięki wsparciu tego bloku przez Manageability Extensions, będziemy mogli w łatwy i czytelny sposób wpłynąć poprzez GPO na wynik działającej aplikacji.
using System;
using Microsoft.Practices.EnterpriseLibrary.Logging;
namespace ZineNet.EntLibGPOTest
{
class Program
{
static void Main(string[] args)
{
LogEntry log = new LogEntry();
int i = 0;
while (true)
{
log.Message = "Ala ma kota! " + (i++).ToString();
Logger.Write(log);
System.Threading.Thread.Sleep(10000);
}
}
}
}
- Konfiguracja logowania.
- Do projektu dodajemy plik konfiguracji app.config, który od razu zamykamy. Uruchamiamy zewnętrzne narzędzie Enterprise Library Configuration i otwieramy w nim utworzony przed chwilą plik.
Tu uwaga – po zainstalowaniu Enterprise Library mamy możliwość edycji pliku konfiguracyjnego bezpośrednio w Visual Studio. W tym celu należy zamknąć plik app.config i korzystając z Solution Explorera wybrać z menu kontekstowego dla tego pliku pozycję 'Edit Enterprise Library Configuration'. Z mojego doświadczenia wynika jednak, że lepiej jest używać wersji samodzielnej tego narzędzia, ponieważ pliki konfiguracyjne wygenerowane w obu przypadkach różnią się i powodują różne działanie aplikacji :(.
- Zaznaczamy dodaną aplikację i z menu kontekstowego wybieramy New->'Logging Application Block'
- Zaznaczamy 'Formatters->Text Formatter', wchodzimy do edycji szablonu i pozostawiamy wyłącznie:Message: {message}
- Z sekcji 'Trace Listeners' usuwamy 'Formatted EventLog TraceListener', po czym dodajemy 'Rolling Flat File Trace Listener'. Ustawiamy:
Formatter: wybieramy z listy 'Text Formatter'
Header: <file>
Footer: </file>
- W sekcji 'Special Sources/Logging Errors & Warnings' zaznaczamy istniejący wpis 'Formatted EventLog TraceListener' i w 'ReferencedTraceListener' wybieramy 'Rolling Flat File Trace Listener'.
- Powtarzamy czynność dla sekcji 'Category Sources/General'.
- Zapisujemy konfigurację, przechodzimy do Visual Studio i robimy build. Nie zapominamy oczywiście o wymaganych referencjach do odpowiednich bibliotek Enterprise Library :).
W tym momencie powinniśmy mieć już aplikację (przyjmuję dalej, że nazywa się EntLibGPOTest.exe, plik konfiguracyjny EntLibGPOTest.exe.config), która co 10 sekund dopisuje do pliku tekstowego 'rolling.log' wpis postaci
<file> Message: Ala ma kota! 0 </file>
- Przygotowanie szablonu ADM.
- Otwieramy ponownie plik konfiguracyjny korzystając z narzędzia 'Enterprise Library Configuration'. Zaznaczamy dodany wpis i wybieramy 'New->Configuration Sources'.
- Pojawia nam się sekcja 'Configuration Sources', z której usuwamy domyślnie dodany wpis 'System Configuration Source', a następnie dodajemy 'Manageable ConfigurationSource'.
- 10. Zaznaczamy dodane źródło, po czym ustawiamy:
- ApplicationName: EntLibGPOTest
- EnableGroupPolicies: True
- EnableWMI: False
Atrybut File ustawiamy na docelowy plik konfiguracyjny (w naszym przypadku będzie to EntLibGPOTest.exe.config w katalogu /bin/Debug aplikacji).
- Zaznaczamy 'Configuration Sources' i w sekcji 'General/ Selected Sources' wybieramy z listy 'Manageable Configuration Source'.
- Zapisujemy zmiany.
- Z menu podręcznego dla sekcji 'Configuration Sources/Manageable Configuration Source' wybieramy 'Generate ADM Template' i zapisujemy jako 'EntLibGPOTest.adm' w dowolnym miejscu na dysku.
- Zapisujemy zmiany w pliku konfiguracyjnym i wykonujemy ponowny build aplikacji.
W tym momencie mamy już przygotowany szablon administracyjny, który możemy wykorzystać w przystawce gpmc.msc do konfiguracji naszej aplikacji poprzez zasady Group Policy. Tu uwaga. Przygotowany plik konfiguracyjny zawiera wiele zbędnych wpisów dotyczących rozszerzeń, z których w tej chwili nie korzystamy. W wersji produkcyjnej należy oczyścić plik konfiguracyjny, my jednak unikniemy błędów wykonania kopiując w dużym nadmiarze do katalogu naszej aplikacji wszystkie biblioteki z katalogu /bin instalacji Enterprise Library. W ramach ćwiczeń sugeruję pobawić się ustaleniem niezbędnego zestawu plików/ wpisów w konfiguracji do poprawnego działania aplikacji.
Rysunek 1 Narzędzie z Enterprise Library do edycji plików konfiguracyjnych
- Użycie przygotowanego szablonu
- (W systemie Windows XP Prof.) Z wiersza poleceń uruchamiamy Microsoft Management Console: mmc /a. Dodajemy przystawkę do obsługi polis, w naszym przykładzie wystarczą nam zasady lokalne.
- Przechodzimy do 'Konfiguracja użytkownika/Szablony administracyjne' i z menu podręcznego wybieramy 'Dodaj/usuń szablony'. Korzystając z 'Dodaj' dołączamy do listy szablonów utworzony przez nas wcześniej plik.
- Uruchamiamy przygotowaną przez nas aplikację. Korzystając z taila obserwujemy dołączane wpisy do pliku rolling.log.
- Przechodzimy do edytora zasad, rozwijamy sekcję 'EntLibGPOTest', przechodzimy do 'Logging/Listeners' i wchodzimy do 'Specify settings for listener 'Rolling Flat File Trace Listener''. Zaznaczamy 'włączone' i ustawiamy:
Header: <gpo>
Footer : </gpo>
Rysunek 2 Konsola z załadowanym edytorem zasad grupowych
Potwierdzamy zmiany klikając OK i obserwujemy zmiany w pliku konfiguracyjnym ciągle uruchomionej aplikacji testowej. Po chwili pojawiają się wpisy
<file>
Message: Ala ma kota! 5
</file>
<gpo>
Message: Ala ma kota! 6
</gpo>
A zatem wszystko działa poprawnie i aplikacja jest gotowa do centralnego zarządzania!