wtorek, 4 marca 2014

Tworzenie konta mailowego w MS Exchange

Od pewnego czasu, jako jedno z moich zadań pobocznych dostałem "opiekę administracyjną" nad zewnętrznym serwerem, na którym oprócz aplikacji CRM jest również zainstalowany serwer mailowy. "Opieka administracyjna" obejmuje również opiekę nad serwerem "exchange", czyli serwer pocztowy.

W niniejszym wpisie, opiszę procedurę tworzenia/konfigurowania nowego użytkownika, ponieważ co jakiś czas zachodzi taka potrzeba, a podręczny manual z instrukcją obsługi zawsze lepiej mieć, niż nie mieć ;).

Zaczynamy od otworzenia aplikacji do zarządzania użytkownikami oraz komputerami 'Active Directory". W tym celu, w "kafelkach" w wyszukiwarce wpisujemy "active", a nast. wybieramy odpowiedni program:


W programie "Użytkownicy i komputery usługi Active Directory" do grupy "Users" dodajemy nowego użytkownika:

i uzupełniamy jego dane

na 'moim' serwerze był problem z 'wygasaniem' haseł, więc zaznaczam opcję, aby hasło nigdy nie wygasało:

Później już tylko okienko z podsumowaniem i zatwierdzenie stworzenia nowego usera.

Teraz otwieramy aplikację do usługi serwera pocztowego Exchange:

W ustawieniach serwera pocztowego tworzymy nową skrzynkę pocztową:


nast, wybieramy "User Mailbox",
Existing users, a nast. usera którego wcześniej utworzyliśmy:


później już tylko "next, next" i... mamy gotowe poczto kontowe.


Konto pocztowe możemy przetestować za pomocą przeglądarki internetowej wpisując do adresu przeglądarki:
https:/webmail.myexchangeemail.com/owa/
W moim konkretnym przypadku było to:
https://mail.nazwaHosta.pl/owa/auth/logon.aspx

 Blog, na którym bardziej szczegółowo opisano jako zrobić opisane jest tutaj. Do logowania się, przez przeglądarkę używamy samego loginu konta (bez małpy).

Teraz, kiedy mamy utworzone i działające konto pocztowe powiązane z kontem w AD, może zajść potrzeba dodania usera do grupy np. "wszyscy", "działX", "departamentY". Jeżeli grupy zostały utworzone w podobny sposób, to możemy to zrobić w AD:

Wybieramy naszego użytkownika, prawy przycisk myszy na "właściwości, a nast. zakładka "Członek grupy"
Wybieramy przycisk "Dodaj...", w polu tekstowym wpisujemy nazwę naszej grupy, nast. klikamy przycisk "Sprawdź nazwy" (jeżeli grupa istnieje, to jej nazwa w polu tekstowym zostanie podkreślona)
oraz "OK".

Teraz we właściwościach wybranego użytkownika, w zakładce "Członek grupy" powinna się pojawić nazwa grupy, do której użytkownik został dodany.



P.S. Jestę adminę  :-D

AutoMapper

    Jednym z ćwiczeń praktycznych podczas "Zaawansowanego szkolenia z .NET 4.0" organizowanego przez Comarch (opis szkolenia tutaj), było napisanie własnego "AutoMappera" na kilka możliwych sposobów (refleksja, dynamic).
    A czym właściwie jest "AutoMapper"? AutoMapper to biblioteka, która udostępnia funkcjonalność automatycznego przepisywania wartości pól jednej klasy do drugiej. Potrzeba posiadania takiej funkcjonalności często zachodzi w sytuacji wykorzystywania w projekcie ORM. Zamiast pisać kod, służący do mapowania pól/właściwości z jednej klasy do drugiej, lepiej jest wykorzystać gotowe, darmowe rozwiązanie jakim jest AutoMapper, szczególnie, że jego wykorzystanie jest banalnie proste:

Najpierw, przed pierwszym użyciem tworzymy konfigurację mapowania (w jednym miejscu dla całego AppDomain). Najczęściej będzie to 'global.asax' lub 'bootstraper', ale może być też bezpośrednio przed metodą:
public static IMappingExpression<TSource, TDestination> CreateMap<TSource, TDestination>();
np.: Mapper.CreateMap<ClassA, ClassB>();

a nast. w kodzie produkcyjnym do mapowania wykorzystujemy metodę Map:
public static TDestination Map<TDestination>(object source);
np: ClassA classAB = Mapper.Map<ClassA>(classAA);  
//classAA will be copied to classAB and both will have values of classAA

Testowanie:
Najpierw musimy zainicjować konfigurację mapowania (np. poprzez wywołanie Bootstrapera), a nast. wywołać metodę:
Mapper.AssertConfigurationIsValid();

Linki:
Kod źródłowy znajduje się na github, a udost. jest na licencji MIT.
AutoMapper Getting-started
Artykuł na Visual Studio Magizne opisujący bardziej zaawansowane przypadki użycia: link

środa, 26 lutego 2014

NancyFx - Polskie znaki

Podczas pracy nad nowym projektem, z wykorzystaniem frameworka Nancy (NancyFx) zauważyłem, że mam problem z wyświetlaniem polskich znaków w widoku (Razor). Rozwiązaniem okazało się dodanie metataga <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> do części <head>

Przykładowa część strony wygląda więc tak:

<head>
    <title>Input</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>

 Źródło, z którego wziąłem rozwiązanie.

środa, 19 lutego 2014

MS SQL - Edycja wierszy w edytorze wg. zapytania SQL

W MS SQL Managment Studio istnieje opcja, aby edytować wiersze w edytorze. Standardowo, jest to opcja na edytowanie pierwszych 200 wierszy (top 200 rows), jednak edytor udostępnia możliwość, aby edytować wiele, dowolnie wybranych wierszy.

Aby tego dokonać, należy, najpierw wybrać standardową opcję "Edit Top 200 Rows", a nast. na uzyskanym zbiorze wynikowym, prawy przycisk myszy, "Pane->SQL", a nast. edytujemy zapytanie SQL tak, aby uzyskać zakres danych, który chcemy później edytować w edytorze.

Link do pytania na stackoverflow.com/

wtorek, 11 lutego 2014

Szkolenie Comarch - Programowanie .NET 4.0 - kurs zaawansowany

W dniach od 05.02.2014 do 07.02.2014 (3 dni) miałem przyjemność wziąć udział w szkoleniu, zorganizowanym przez firmę Comarch nt. ' Programowanie .NET 4.0 - kurs zaawansowany'.

Szkolenie przeprowadził Marcin Najder (techblog), ale zanim przejdę do konkretów najpierw kilka spraw "formalnych". Szkolenie odbyło się w Warszawskiej siedzibie firmy, przy ul. Leśna 2 (przecznica ul. Puławskiej 525), czyli... na Ursynowie, przy ul. Puławskiej, drugie światła od zjazdu z południowej obwodnicy Warszawy, czyli... bardzo dobra lokalizacja dla zmotoryzowanych (w okoliczny jest gdzie zaparkować).

Co do oferty szkoleniowej, to można ją przejrzeć tutaj, natomiast szczegóły szkolenia, na którym ja byłem, można obejrzeć tutaj. Pod każdym szczegółowym opisem szkolenia jest niebieski przycisk "Terminarz i Rejestracja", więc jeżeli ktoś jest zainteresowany, to wiadomo co i jak.

Jeżeli chodzi o samo szkolenie, to nie będę ukrywał, że cena 3 dniowego szkolenia, była jak na Warszawę bardzo konkurencyjna  (w promocji, 1400zł + VAT).

A jak wyglądało samo szkolenie?
    Należy zacząć od tego, że sam prowadzący, to bardzo sympatyczny, a przy tym doświadczony programista. Prawdziwy pasjonat w swoim fachu, fan zarówno języków funkcyjnych jak i obiektowych i to m.in. próbował nam przekazać podczas szkolenia. Ponieważ w naszej 7 os. grupie, były os. o bardzo zróżnicowanym doświadczeniu programistycznym, Marcin musiał się nieco wysilić, szczególnie że był niemal przez cały czas pod porządnym gradobiciem pytań.
     Były więc os. zaraz po studiach (i kursie podstawowym), które prosiły o więcej wyjaśnień związanych z lambdami, delegatami itp., jak i doświadczony programista PHP pragnący spróbować swoich sił w .NET, jak i 2-3 bardziej doświadczonych programistów, pytających co chwila o bardziej zaawansowane tematy oraz różnego rodzaju "wątki poboczne".
     Na wszystkie te tematy, prowadzący odpowiadał spokojnie i rzeczowo. W efekcie, w trakcie kursu, przerobiliśmy też fragment "kursu podstawowego", to co było w agendzie związane z zaawansowanymi aspektami programowania w .NET (linq, lambdy, refleksja, więcej lambd, T4, wzorce projektowe, programowanie współbieżne, jeszcze więcej lambd itp. ;)), ale również tematy okołoprogramistyczne, takie jak np. rozproszone kontrole wersji (github, bitbucket), "NoSQL" (MongoDb, RavenDb), JSON, frameworki javascriptowe (Angular.JS, Node.JS). Wspomniany został nawet ServiceStack (niestety aktualnie płatny) Jeżeli doliczymy do tego ćwiczenia praktyczne z wykorzystaniem nUnit oraz Resharpera, oraz rozmowy programistyczne oraz  około programistyczne, czy w czasie kursu, czy też w czasie wspólnego posiłku to daje nam naprawdę intensywnie spędzone 3 dni..
     Wprawdzie to nie Ja płaciłem za szkolenie(firma płaciła), ale uważam, że naprawdę warto było pójść na to szkolenie. Fajnie jest przebywać w towarzystwie inteligęnych (i nierzadko mądrzejszych) ludzi od siebie i tak "na spokojnie" się czegoś nowego dowiedzieć/nauczyć. Taki miłe urozmaicenie w stosunku do samotnego przerabiania tutoriali / dokumentacji / oglądania podcastów w domu ;)

Z tego co Marcin mówił, to obok pracy na etacie, prowadzi również szkolenia ASP.MVC, programowanie reaktywne, jak i kurs podstawowy. Inna sprawa, że kurs podstawowy, czasami prowadzi też inna zupełnie inna osoba.

To tyle. Gdyby ktoś kiedyś miał okazję udać się na takie szkolenie, to szczerze polecam. Fajnie było :)

wtorek, 28 stycznia 2014

Rysowanie diagramów UML z ArgoUML

Czym jest UML wie zapewne każdy. Czy, a raczej kiedy należy go stosować zależy w dużej mierze od projektu oraz zdrowego rozsądku. Są sytuacje, gdy stworzenie kilku diagramów UML może stanowić ważny element dokumentacji projektowej, a są też sytuacje, gdy tworzenie zbyt dużej ilości może się okazać zwykłą stratą czasu.

W momencie, w którym zdecydujemy, że warto wzbogacić naszą dokumentację techniczną o diagram(y) UML warto użyć do tego odpowiedniego narzędzia, szczególnie, że niektóre z nich posiadają takie opcje, jak np. autogenerowanie części kodu źródłowego.

Przy wyborze narzędzia, ważne jest to, jakiej funkcjonalności oczekujemy od narzędzia, tj. czy chcemy rysować, modelować, eksportować wyniki do metamodeli, a może jednak najważniejsze jest generowanie fragmentów kodu z diagramu? Bardzo dobry przegląd narzędzi, ze względu na rodzaje funkcjonalności znajduje się w jednym z pytań na forum stackoverflow.com.

W moim przypadku, właśnie skończyłem pracę nad rozbudowanym architektonicznie projektem, w którym mieliśmy 4 nasze serwery, z czego 3 schowane za "firewallem" oraz 6-7 usług zewnętrznych, z którymi porozumiewały się różne serwery. Diagram wdrożeniowy pokazał istniejące zależności w sposób jasny i klarowny, pozwalając zrozumieć istniejące zależności nawet nowym osobom w projekcie.

Do narysowania diagramu użyłem darmowego programu ArgoUML dostępnego na licencji Eclipse Public License - v 1.0.

ArgoUML w porównaniu ze swoim głównym konkurentem Visio:
- jest darmowy
- jest prosty, a szata graficzna lekko spartańska
- można za jego pomocą wygenerować tylko 6 typów diagramów (klas, przypadków użycia, sekwencji, maszyny stanowej, czynności, wdrożeniowy)
- nie do końca spełnia (implementuje) wszystkie standardy języka UML
- posiada możliwość generowania kodu w językach takich jak java, c++, c#, itp.
- posiada możliwość inżynierii wstecznej plików JAR

dodatkowo, wynik naszej pracy możemy eksportować do:
- XML
- pliku graficznego

Pełny opis na http://en.wikipedia.org/wiki/ArgoUML

Mnie osobiście ArgoUML przekonało funkcjonalnością, oraz darmowością. Program, mimo iż nie jest w 100% zgodny ze standardami UML, oraz posiada nieco spartańską oprawę graficzną, to jednak, Moim zdaniem jest wystarczająco dobry do zobrazowania "clou problemu" i zwyczajnie 'robi swoją robotę'.

poniedziałek, 20 stycznia 2014

Testowanie ConfigurationManager (xUnit, FakeItEasy)

Tworząc testy jednostkowe ważne jest, aby testy działały bardzo szybko, oraz niezależnie od zewnętrznych zasobów, takich jak np. web servicedostęp do plików itp. Mówi o tym, m.in. Roy Osherove podczas swoich szkoleń, np. Understanding Test Driven Development

Jednym z takich zewnętrznych zasobów dla aplikacji internetowych, jest plik konfiguracyjny web.config. Przykładowy sposób, jak skutecznie zastosować DI oraz testy jednostkowe dla tego rozwiązania pokazuje na swoim blogu KAZI MANZUR RASHID. Niestety dla mnie, Kazi pokazuje to z wykorzystaniem "Mock", natomiast Ja, pod wpływem postów Macieja Aniserowicza jako narzędzie 'mockujące' postanowiłem wykorzystywać FakeItEasy.  Poniżej prezentuję działające rozwiązanie wykorzystujące bibliotekę FakeItEasy.

Ponieważ zmieniam tylko bibliotekę 'Mock' na "FakeItEasy' to podstawowe klasy, pozostały takie same, jak w kodzie Kazi Manur'a

    public interface IConfigurationManager
    {
        NameValueCollection AppSettings
        {
            get;
        }
        string ConnectionStrings(string name);
        T GetSection<T>(string sectionName);
    }
    public class ConfigurationManagerWrapper : IConfigurationManager
    {
        public NameValueCollection AppSettings
        {
            get
            {
                return ConfigurationManager.AppSettings;
            }
        }
        public string ConnectionStrings(string name)
        {
            return ConfigurationManager.ConnectionStrings[name].ConnectionString;
        }
        public T GetSection<T>(string sectionName)
        {
            return (T)ConfigurationManager.GetSection(sectionName);
        }
    }
Aby pokazać bardziej realistyczny przykład użycia, utworzyłem klasę BL (Business Logic), która do swojej pracy wykorzystuje dane, pobrane z web.config. Założyłem również, że plik web.config posiada wpis o nazwie customAppSetting z wartością "test".

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
public class BL
{
    private readonly IConfigurationManager configuration;
public BL()
{
        this.configuration = new ConfigurationManagerWrapper();
}
    public BL(IConfigurationManager configuration)
    {
        this.configuration = configuration;
    }
    public string GetAppSetting(string customAppSettingName)
    {
        string customAppSetting = configuration.AppSettings[customAppSettingName];
        //TODO: some business logic
        return customAppSetting;
    }
}
Praktyczne wykorzystanie klasy BL przez solucję produkcyjną:
    private void ProductionWebConfig()
    {
        BL businessLogic = new BL(new ConfigurationManagerWrapper());
        string customAppSetting = businessLogic.GetAppSetting("customAppSetting");
    }
Praktyczne wykorzystanie klasy BL przez bibliotekę testującą:
    [Fact]
    public void GetAppSetting_PositiveString_StringTest()
    {
        var customAppSetting = new NameValueCollection { { "customAppSetting", "test" } };
        IConfigurationManager fakeConfiguration = A.Fake<IConfigurationManager>();
        A.CallTo(() => fakeConfiguration.AppSettings).Returns(customAppSetting);
        BL bl = new BL(fakeConfiguration);
        string fakeString = bl.GetAppSetting("customAppSetting");
        string realString = "test";
        Assert.Equal(fakeString, realString);
    }