czwartek, 10 lipca 2014

Nie testuj na serwerze testowym!!!

Ten oto wpis, to nic innego jak konkluzja z ost. kilku dni w pracy. I broń boże, nie wykonuj na tych danych, żadnych aktualizacji "notowań, kursu walut" ani innych "co nocnych" jobów. Taka niestety nasuwa się konkluzja z ost. kilku dni.

A co to dokładnie oznacza?
Ano nic innego, ze Piotrek nie umie rozmawiać z ludźmi. Przejmując x syst. informatycznych po swoich poprzednikach, nie zawsze potrafił się dopytać, czy wersje testowe (aplikacji oraz bazy danych) służą do tego, aby programiści mogli na nich cokolwiek testować i broń boże puścili na tym, jakiś update. Szczególnie taki, który działa co noc na prod. i kilka dni temu się wysypał, a ja własnie zrobiłem na niego fixa. O to to nie. Aplikację powinno się przetestować lokalnie, a później, po stwierdzeniu że "u mnie działa" wgrywać od razu na produkcję :/

Jakiś czas temu, podjąłem się zadania przejęcia całej infrastruktury programistycznej w pewnej firmie po tym, gdy odszedł z niej ost. programista i przez kilka tyg. żadne ze stanowisk programistycznych nie było obsadzone. Dużo ich nie było, tj. 2, ale w zasadzie przejmowałem 12 mniej lub bardziej rozbudowanych syst,. informatycznych (największa baza 16 GB danych), a w praktyce żyjący własnym życiem mechanizm naczyń połączonych. Oczywiście, większość aplikacji miała swoich opiekunów biznesowych. O ile miałem parę spotkań z moim poprzednikiem, jednak w praktyce najczęściej koncentrowały się one wokół spraw bieżących, lub przyszłego, nowego syst. który trzeba dopiero napisać.

O ile, z ludźmi z IT rozmawiałem i... np. Adam mnie uprzedził, ze w jego syst. aplikacje "test" oraz "test2" nie są dla mnie dostępne (i stworzył mi inne środ. testowe) o tyle ludzi "biznesowych", którzy zazwyczaj obrażają się o to, ze mówię techniczne słowa, których nie rozumieją, o takie zmiany za bardzo nie podejrzewałem. I masz tu babo placek.

Wysypał się job robiący aktualizację. Znalazłem błąd, poprawiłem go i sru na test. Na teście przeszło to na prod. Fix zrobiony, sprawa rozwiązana i super. A tu niestety nie ma tak dobrze. Opiekun biznesowy, który nie umie pisać skryptów (bo po co mu to), ani tym bardziej zrobić backupu bazy... miał tam jakieś swoje dane, który nocny import mu nadgrał.

Oj Piotrek, Piotrek, I co żeś ty uczynił?
I co ważniejsze? Co też masz teraz zrobić? Porobić własne instancje testowe wszystkich działających usług, skryptów, aplikacji, baz danych? Co noc backupować bazy testowe? A może jednak rozwiązaniem jest, aby dziennie spędzać więcej czasu  na tel. rozmawiając z opiekunami biznesowymi, niż na faktycznym kodowaniu tych systemów?

Normalnie murarz, tynkarz, akrobata...

czwartek, 29 maja 2014

Task Scheduler - Windows Server 2000 vs 2008R2

Przenosząc skrypty .bat pomiędzy serwerami z serwera Windows 2000 na Windows 2008r2 napotkałem pewne problemy. Dlaczego warto robić skrypty .bat można się dowiedzieć choćby z książki A.Hunt, D.Thomas Pragmatyczny programista. Od czeladnika do mistrza w rozdziale "Wszechobecna automatyzacja".

Przenosząc te skrypty, miałem okazję spotkać się z dwoma niemiłymi dla mnie niespodziankami. 
Po pierwsze, zmienił się format daty, jaki stosuje się w skryptach. Aby uzyskać format daty yyyy-MM-ss (rok-miesiąc-dzień) w starszym windowsie (win xp, win server 2000) wystarczyło podać:
echo %DATE:~0,4%-%DATE:~5,2%-%DATE:~8,2%

W windows 7 oraz server 2008r2 trzeba to zrobić nieco inaczej:
@echo off
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
@echo on
echo  %mydate%


UWAGA: echo to... taki Console.Writeline w bashu... czyli... komenda na wypisanie zmiennej na ekran konsoli.


Drugim problemem z jakim się napotkałem to... uruchomienie programu w task schedulerze. Aby nie było zbyt łatwo, w ustawieniach (settings) task schedulera nie można podać pełnej ścieżki skryptu/programu tylko trzeba... wykorzystać 2 osobne, przeznaczone do tego pola (osobne pole na nazwę skryptu, osobne na nazwę programu):




P.S. Z innych spraw, jakie wynikły przy okazji przenoszenia tych skryptów na inny serwer, to ustawianie uprawnień do baz danych, linked serwerów i innych kwestii bezpieczeństwa, ale... to by trzeba było ustawić niezależnie typów serwerów (źródłowych/docelowych).
















sobota, 24 maja 2014

KeePass – przechowuj hasła bezpiecznie

Jednym z problemów, z jakimi spotykają się różni użytkownicy komputerów, posiadający dostęp do wielu zasobów (np. aplikacji internetowych, baz danych itp.) jest problem związany z ilością potrzebnych loginów i haseł. W teorii hasło do każdego konta powinno być inne, jednak w praktyce bardzo trudno jest pamiętać 20-50 różnych haseł do różnych kont. Na szczęście, z pomocą przychodzi nam darmowa aplikacja "KeePass", która będzie przechowywała za nas odpowiednie loginy i hasła w sposób bezpieczny (zaszyfrowany). My, jako użytkownicy, jedynie potrzebujemy znać hasło do naszego pliku z zaszyfrowanymi danymi w KeePass (który możemy przenosić między komputerami, np. za pośrednictwem pendrive), a już szczegółowe loginy i hasła do konkretnych stron, aplikacji, usług, baz danych znajdować się będą w KeePass-ie. 

Linki: 

środa, 14 maja 2014

Korzystanie z kilku plików konfiguracyjnych (*.config)

Jak powszechnie wiadomo, w jednej solucji możemy mieć wiele projektów. Każdy z tych projektów może posiadać własny plik konfiguracyjny. Problem może się pojawić w sytuacji, gdy w jednej solucji chcemy korzystać z wielu plików konfiguracyjnych. Przyjrzyjmy się pewnemu realnemu scenariuszowi.

Mamy nasza przykładową aplikację konsolową, która poprawnie działa. Zaszła jednak potrzeba wykorzystania web serwisu (WCF). Zgodnie z dobrymi praktykami, do obsługi WCF tworzymy nowy, osobny projekt jako bibliotekę DLL ('class library'). Aplikacja konsolowa, posiadała już swój plik konfiguracyjny (App.config), więc próba odwołania się konfiguracji naszej biblioteki za pomocą obiektu "ConfigurationManager" spowodowała przeglądanie pliku konfiguracyjnego aplikacji. Ponieważ chcemy oddzielić konfigurację biblioteki od konfiguracji aplikacji potrzebujemy mieć oba pliki rozdzielone oraz możliwość czytania z obu plików.

Jak to należy zrobić?
Rozwiązanie można podzielić na dwa etapy. Konfiguracyjny oraz programistyczny:

W projekcie:
a) zmieniamy nazwę pliku konfiguracyjnego biblioteki, aby oba pliki konfiguracyjne miały różne nazwy
b) we właściwościach pliku konfiguracyjnego biblioteki ustawiamy właściwość "Copy to output Directory" na "Copy always"
c) w projekcie z aplikacją ustawiamy referencję na projekt z biblioteką

W kodzie biblioteki, będziemy się odwoływać do nowego pliku konfiguracyjnego w "niestandardowy" sposób. Pisząc "niestandardowy" mam na myśli w sposób inny niż za pomocą obiektu "ConfigurationManager".

W kodzie, wykorzystujemy obiekt Configuration (System.ServiceModel.Configuration) poprzez wykorzystanie jego właściwości. Przykładowa klasa, za pomocą której będziemy korzystali z nowego pliku konfiguracyjnego wygląda tak:

    public class ConfigurationManagerWrapper
    {
        private Configuration cfg;
        public ConfigurationManagerWrapper()
        {
            var path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            var fileMap = new ExeConfigurationFileMap
            {
                ExeConfigFilename = string.Concat(path, "\\mail.config")
            };
            cfg = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
        }
        public string GetSetting(string key)
        {
            AppSettingsSection section = (cfg.GetSection("appSettings") as AppSettingsSection);
            var value = section.Settings[key].Value;
            return value;
        }
        public ChannelEndpointElement GetClient(string key)
        {
            var serviceModel = ServiceModelSectionGroup.GetSectionGroup(cfg);
            var endpoints = serviceModel.Client.Endpoints;
            if (endpoints.Count > 0)
                return endpoints[0];
            return null;
        }
        public T GetSection<T>(string sectionName)
        {
            return (T)ConfigurationManager.GetSection(sectionName);
        }
    }
Bardziej zaawansowany przykład wykorzystania takiego pliku .config można zobaczyć w przeznaczonym do tego projekcie na github mojego autorstwa stworzonym w celu demonstracji kodu.

Pomocne linki:
stackoverflow.com - how-do-i-retrieve-appsettings-from-the-assembly-config-file
weblogs.asp.net - cibrax - getting-wcf-bindings-and-behaviors-from-any-config-source.aspx

poniedziałek, 17 marca 2014

Szata kolorystyczna Visual Studio (VS color theme)

Przez bardzo długi okres czasu, programowałem na standardowych ustawieniach kolorów Visual Studio. Niedawno zobaczyłem u kolegi zupełnie inne ustawienie motywu graficznego, tj. kolorowe litery na czarnym tle. Poszukałem nieco po necie i znalazłem kilka stron, z gotowymi motywami:
galeria z motywami na blogu Scota Hanselmana
galeria z motywami na studiostyle.es

Interesuje okazało się pytanie na forum stackoverflow.com, które doprowadziło mnie do postu na blogu Jeffa Atwooda, z bardzo interesującą skórką zenburn. Jak na razie, ta skórka mi się podoba najbardziej, ponieważ jasno można odróżnić 0 od O oraz I od 1 (kolorami), a przy tym, kolory są bardzo stonowane (oszczędzają wzrok przy dłuższej pracy).

Git

Czym jest Git, mam nadzieję, że każdy szanujący się programista doskonale wie, a pozostałym przypomnę, że jest to rozproszony system kontroli wersji. Git powszechnie uważany jest, za najlepszy, dostępny na rynku system kontroli wersji. Porównanie Git-a z TFS, jakiś czas temu napisał mój ulubiony bloger .NET, czyli Maciej Aniserowicz -> 'w-czym-git-jest-lepszy-od-tfs'

Pomijając już wszelkie 'ohy i ahy' Maćka, które wygłasza za każdym razem, gdy tylko ktoś pozwoli mu się odezwać, Git ma kilka zalet, które na chwilę obecną bardzo mi się podobają:
- możliwość pracy off-line -> niestety w przeszłości, zdarzyła nam się syt., w której padł nam dysk na serwerze, na którym mieliśmy nasz serwer SVN. Dysk, a dokładniej dane dało się w końcu odzyskać, jednak te kilka dni programowania bez kontroli wersji do najprzyjemniejszych, a przynajmniej do najbardziej komfortowych nie należały. Wrzucając kod na git-a, można pracować 'off-line', a po podłączeniu się 'on-line' mamy pewność, że serwery będą działały tak jak należy i nie musimy się martwić o "spalenie się dysku"
- możliwość umieszczenia mojego kodu źródłowego w bardziej przyjaznej programiście formie, niż wklejanie go tutaj, co delikatnie mówiąc było lekko "wieśniackie".

Jako hosting, na pierwszy ogień poszedł GitHub ponieważ dla publicznych repozytoriów, jest darmowy link. Owszem, Github nie jest monopolistą i  istnieje konkurencja w postaci Bitbucket, który w dodatku pozwala na kilka prywatnych repozytoriów, ale od czegoś trzeba zacząć. Zawsze najpierw trzeba zrobić ten pierwszy krok.

Możliwe, że kiedyś się przeniosę na Bitbucket, albo inne podobne rozwiązanie, ale puki co, zapraszam na moje konto na github, gdzie w miarę możliwości będę się starał wrzucać moje programistyczne wypociny.

czwartek, 6 marca 2014

Przekierowanie poczty MS Exchange

Tak jak już wspomniałem w moim poprzednim wpisie nt. tworzenie konta mailowego w ms-exchange jako jedno z dodatkowych zadań dostałem opiekę administracyjną nad serwerem, na którym oprócz aplikacji CRM, zainstalowany jest również serwer pocztowy Exchange.

W poprzednim poście opisałem jak utworzyć nowe konto, oraz dodać je do grupy. W tym opiszę przypadek przekierowywania (forwardowania) maili do innej skrzynki pocztowej.

Jeżeli chcemy zrobić forward dla klienta wewnątrz domeny, to dobrze jest dla niego utworzyć konto w AD, jeżeli jednak mamy do czynienia forwardem do skrzynki pocztowej po za naszym AD, wtedy należy utworzyć nowy kontakt mailowy.

Na pocz. otwieramy klienta ms exchange i przechodzimy do zakładki "Recipient Configuration", gdzie tworzymy nowy kontakt mailowy ("New mail contact"). Uwaga: wykonujemy to na zakładce  'Recipient Configuration", a nie "Mail":

New contact, next, a nast. w oknie wpisujemy odpowiednie dane:

Teraz wchodzimy we właściwości (properties) istniejącego kontaktu, dla którego chcemy dołożyć forward.
Z opcji wybieramy "Mail Row Settings", a nast. zaznaczamy "Delivery Options" i właściwości (Properties). W nowo utworzonym okienku wybieramy "Browse", a nast. utworzony przez nas przed chwilą kontakt mailowy:

Nast. zaznaczamy (lub nie) checkbox z, czy maile mają przychodzić na obie skrzynki pocztowe, czy tylko na nową skrzynkę ("Deliver message to both forwarding address and mailbox").

Ok. Apply i... już działa nam nasz forward wiadomości.