Wednesday, 15 September 2004
Živě učí staré psy staré kousky
Živě zahájilo s obrozeneckým nadšením seriál o VB.NET. Nadšení serveru pro nové jazyky a polopatické vzdělávání svých čtenářů se ale ve své aktuální podobě stávají pro seriál sudičkami se smrtícími kletbami ve své bezzubé hubě.
Autor seriálu Milan Petřík se rozhodl, že postaví na hlavu všechna didaktická pravidla, která říkají, že vysvětlování nového tématu s odlišným viděním problému by nemělo být budováno na předchozích zastaralých znalostech, a raději nám předkládá svoji vizi "jednoduchého" VB jako chameleona proplouvajícího napříč technologiemi již léta skoro beze změny. To, že VB.NET je jen marketingový název Microsoftu pro jazyk budovaný na zcela jiných principech nez VB6 a nižší verze, který se svými zastaralými předchůdci sdílí některé méně významné syntaktické konstrukce, a že jen pro nepoučitelné nostalgiky je vytvořen jmenný prostor Microsoft.VisualBasic, s jehož pomocí je způsob kódování ve VB.NET degradován na hybridní VB6/.NET styl, nemusím návštěvníkům mého blogu asi připomínat.
Autor veškeré připomínky ke svému seriálu odmítá alibistickým poukazem na to, že prvních 10 dílů seriálu je určeno úplným začátečníkům, a proto nevysvětluje hned některé pokročilé, ale zásadní koncepty (třeba třídy, jmenné prostory), které přesahují ohraničený svět VB.NET. Alibistické je to proto, že se sice dle svých slov vyhýbá teoretickému vysvětlování některých pojmů, ale to mu nebrání, aby nás hned ve druhém dílu seriálu nepoučil o o logickém členění programu do modulů (Proč Microsoft před programátory skrývá své sladké tajemství, že modul ve VB.NET je jen třída se statickými metodami a syntaxe modulu je rozvinuta do třídy teprve kompilátorem?) a procedur a v zatím posledním díle se zase rozhodne, že jeho čtenáři jsou již dostatečně vyspělí, aby pochopili konstrukci Try - Catch (a to vše ještě před řídícími konstrukcemi jazyka!), ale aby jejich chápavé obvody v mozku nepřetížil, tak jim taktně zamlčí existenci klíčového slova Finally.
Dalšími lapsy jsou neustálé vypisování celé hierarchie jmenných prostorů nebo utvrzování začátečníka, že používání "magických" čísel místo konstant je v pořádku. Seriál je rozvleklý, těžkopádný a skáče bez jakékoli logické souvislosti z tématu na téma.
Shrnu-li to. Za seriálem není znát žádná myšlenková osnova a působí na mě dojmem, že si někdo v Živě řekl "No ten .Net už je docela rozšířenej, jeden děsnej seriál pro začátečníky o PHP už máme, a protože jsme server pro masového čtenáře, tak vytvoříme i podobný seriál ve VB.NET (jako bumerang se zde Microsoftu vrací, že VB má pověst lidového jazyka :), pozn. aut. ) a seženeme někoho, kdo dokáže žoviálně podat, jakej je ten VB.NET pohodovej jazyk fakt pro každou lamu".
Komu je seriál určen, opravdu netuším. Napadli mě jen ortodoxní příznivci programování v Basicu na nezastarávajícím stroji Didaktik Gamma, kteří se pod tlakem doby rozhodli migrovat na na PC a .NET. Ale že by tvořili tak početnou skupinu, aby se pro ně vyplatilo vytvářet seriál? :)
Wednesday, 15 September 2004 07:55:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | Ostatní
Monday, 13 September 2004
Http modul pro změnu URL adresy ve WSDL webové služby
Webové služby v ASP.NET generují dynamické WSDL, ve kterém je adresa služby (obsah elementu soap:address) dynamicky určena podle url původního požadavku. Například při použití reverzní proxy by se hodilo určit adresu ve wsdl dokumentu staticky a přitom stále ponechat na ASP.NET generování většiny elementů ve wsdl dokumentu.
K tomuto účelu jsem napsal http modul pro změnu adresy. V kódu se předpokládá, že nové url webové služby je zadáno ve web.config v sekci appSettings pod klíčem newUrl a že k službě je přistupováno pouze přes protokol SOAP.
using System;
using System.Web;
using System.IO;
using System.Xml;
using System.Diagnostics;
namespace RSTEIN.HttpModules
{
///
/// Modul pro změnu
///
public class ChangeUrlModule : IHttpModule
{
#region private constants
private const string WSDL_REQUEST = "wsdl";
private const string SOAP_NAMESPACE = "http://schemas.xmlsoap.org/wsdl/soap/";
private const string SOAP_PREFIX = "soap";
private const string LOCATION_NAME = "location";
private const string ADDRESS_NAME = "address";
#endregion private constants
#region private variables
private readonly string m_newServiceUrl;
#endregion private variables
#region Constructors
///
/// Konstruktor
///
public ChangeUrlModule()
{
m_newServiceUrl = System.Configuration.ConfigurationSettings.AppSettings["newUrl"];
}
#endregion Constructors
#region IHttpModule Members
///
/// Inicializace modulu - Součást rozhraní
///
///
public void Init(HttpApplication context)
{
if (m_newServiceUrl != String.Empty)
{
context.BeginRequest +=new EventHandler(context_BeginRequest);
context.EndRequest +=new EventHandler(context_EndRequest);
}
}
///
/// Součást rozhraní
///
public void Dispose()
{
}
#endregion
#region private methods
//Zapsání jiného URL
private void context_EndRequest(object sender, EventArgs e)
{
string path = HttpContext.Current.Request.RawUrl.ToLower();
if (isWSDLRequest())
changeUrl();
}
//Změna Url www služby
private void changeUrl()
{
HttpResponse response = HttpContext.Current.Response;
XmlDocument doc = new XmlDocument();
MemoryStream originalStream = ((FilterStream)response.Filter).InnerStream;
originalStream .Position = 0;
try
{
XmlTextReader reader = new XmlTextReader(originalStream);
doc.Load(reader);
}
catch (Exception e)
{
Trace.WriteLine("Invalid response");
return;
}
XmlNamespaceManager namManager = new XmlNamespaceManager(doc.NameTable);
namManager.AddNamespace(SOAP_PREFIX, SOAP_NAMESPACE);
XmlNode locationNode = getLocationAttribute(doc);
locationNode.Value = m_newServiceUrl;
response.Clear();
doc.Save(response.Output);
}
//Vyhledání atributu location elementu soap:address
private XmlNode getLocationAttribute(XmlDocument doc)
{
XmlNode addressNode = doc.GetElementsByTagName(ADDRESS_NAME, SOAP_NAMESPACE)[0];
return addressNode.Attributes["location"];
}
#endregion private methods
//přiřazení filtru na objekt Response
private void context_BeginRequest(object sender, EventArgs e)
{
if (isWSDLRequest())
HttpContext.Current.Response.Filter = new FilterStream(HttpContext.Current.Response.Filter);
}
//Kontrola, zda se jedná o WSDL požadavek
private bool isWSDLRequest()
{
string path = HttpContext.Current.Request.RawUrl.ToLower();
if (path.EndsWith(WSDL_REQUEST))
return true;
return false;
}
}
}
O významu http modulů a jejich registraci ve web.config se více dočtete v mém starším článku na Interval.cz.
Monday, 13 September 2004 15:12:00 (Central Europe Standard Time, UTC+01:00)
Web Services
Sunday, 12 September 2004
Několik zkušenosti s merge replikací na MSSQL proti SQL serveru CE (PDA)
Merge replikace na MSSQL proti SQL Serveru CE má svůj půvab, který ale odhalíte až po projití minového pole nástrah, o nichž v dokumentací naleznete jen pár sporadických zmínek. Spot jsem napsal proto, abych vás před nástrahami kapriciozních tvůrců CE replikací varoval a v některých případech nabídl i dočasné řešení.
1. Jestliže máte nainstalován na MSSQL Service Pack 3, nainstalujte podporu pro CE replikace na serveru z instalačního balíčku, který si můžete stáhnout zde.
2. Pro CE klienty je podporována jen "merge" replikace. Vytvoření publikace s podporou pro CE klienty je snadné - v průvodci "Create publication wizard" na formuláři "Specify subscriber types" zaškrtněte "Devices running SQL Server CE". Při manuálním vytváření publikace proceduru sp_addMergePublication nastavte argument @sync_mode na N'character' a povolte vytváření "subscription" anonymním klientům (@allow_anonymous = N'true').
3. Jestliže používáte dynamické filtry (to znamená, že filtrujete replikovaná data například podle Id uživatele), tak musí být v replikaci povolena optimalizace přenášených dat na klienta. V průvodci na formuláři "Optimize synchronization" zvolte "Yes, enable data optimization” . Alternativně v proceduře sp_addMergePublication nastavte argument @keep_partition_changes na true.
4. CE klienti NEPODPORUJÍ komprimované snapshoty, proto tuto volbu nikdy nezapínejte.
5. Po instalaci SQL Server CE 2.0 na serveru spustťe MMC konzoli SQL Server Connectivity Managament a vytvořte nový virtuální adresář. Na záložce Http Content Folder vyberte adresář, ve kterém je knihovna sscesa20.dll, která zpracovává požadavky na replikaci od PDA klientů. Virtuální adresář musí mit nastaveno právo Execute, takže MMC konzole vám toto právo nedovolí upravovat. Na záložce Http authentication si můžete vybrat vyžadovaný typ autentizace přistupujících klientů - jestliže se rozhodnete pro anonymní přístup, můžete kliknutím na tlačítko Edit... vybrat účet, pod kterým bude knihovna sscesa20.dll přistupovat ke zdrojům počítače. Na záložce NTFS permissions můžete upravit práva, která jsou přidělena účtu, pod kterým běží IIS - většinou ale není nutné s právy manipulovat, protože průvodce si sám nastaví potřebná práva a nedovolí je přes konzoli změnit. Jen pro upřesnění – IIS replikační agent nemusí být nainstalován na serveru, na němž běží MSSQL s publikací.
6. Dostupnost IIS aplikace si ověříte zadáním adresy souboru sscesa20.dll (například http://RSTEIN2/sqlserverce/sscesa20.dll). Jestliže je soubor správně nainstalován, zobrazí se text "SQL Server CE Server Agent". Když se vám zobrazí chybové hlášení nebo dokonce prohlížec nabídne stažení knihovny, přeregistrujte dll zadáním regsvr32 /i sscesa20.dll.
7. Do databáze s publikací musí mít uživatel povolen přístup a současně musí být uživatel přidán do PAL (Publication Access List) ve vlastnostech publikace. O jakého uživatele se ale jedná?
a) Jestliže používáte v IIS aplikaci anonymní autentizaci a pro přístup k MSSQL Windows autentizaci, přístup do databáze a umístění do PAL se týká uživatele, pod nímž běží IIS replikační agent (IUSR_NazevPocitace nebo účet vybraný v bodě 5).
b) Při "Basic" nebo "Integrated Windows" autentizaci uživatele v IIS aplikaci a Windows autentizaci do MSSQL, musí být povolen přístup do databáze a sočasně přidán záznam do PAL pro všechny uživatele, kteří replikaci provádějí.
c) Při SQL autentizaci do MSSQL je do PAL přidán příslušný SQL účet, kterému je také povolen přístup do databáze.
8. Snapshot publikace by měl být generován do vlastní složky, která je sdílena po síti a má nastavena minimální potřebná práva. Výchozí složka pro snapshoty je po síti totiž dostupná jen přes "administrátorské sdílení" (jméno disku se znakem dolaru na konci).
Složku se snapshotem určíte ve vlastnostech publikace na záložce Snapshot loation. Zaškrtněte volbu "Generate snapshots in this location" a do textového pole Folder zadejte název složky (například \\RSTEIN2\PDAREPLIKACE\PDA_FULL). Při zakládání publikace metodou sp_addMergePublication určete alternativní umístění snapshotu argumentem @alt_snapshot_folder. (@alt_snapshot_folder = '\\RSTEIN2\PDAREPLIKACE\PDA_FULL' ).
Na složce, do které je generován snapshot, musejí být nastavena tato práva.
a. Účty, pod kterými běží služby SQL Server a SQL Server Agent, musejí mít nastaveno plné řízení (Full control).
b. Jestliže používáte v IIS aplikaci anonymní autentizaci, musí mít anonymní účet právo "Read".
c. Jestliže používáte v IIS aplikaci "Basic" nebo "Integrated Windows" autentizaci, musejí mít všechny přistupující účty právo "Read".
9. Ke správě a řízení zařízení na PDA je možné vytvořit odlehčenou verzí replikačního manažera, kterého jsem popisoval v jiném spotu. CE replikační manažer má své zvláštnosti, protože například dotaz na dostupnost MSSQL je nesmyslný, poněvadž CE replikace komunikují jen s replikačním agentem v IIS. Namísto dotazu na MSSQL tedy vytvoříme GET požadavek na soubor sscesa20.dll a zkontrolujeme, jestli se nám vrátil řetězec "SQL Server CE Server Agent".
10. Nepříjemným omezením (chybou) v SQL serveru CE 2.0 je podpora pouze maximálně jedné "subscription" v jedné databázi. Přesněji řečeno - před začátkem práce na projektu jsem si ověřoval, jestli mi SQL CE server bude podporovat dvě "subscription", protože jsem chtěl vytvořit dvě publikace v jednoé databázi. Jedna z nich by byla filtrovaná, druhá nefiltrovaná, což je v souladu s doporučeními v MSDN, jež se zabývají optimalizacemi replikací. Vytvořil jsem tedy dvě zkušební "subscription" v jedné CE databázi a vše proběhlo bez problémů. Problém se vyskytl až při pokusu o první replikaci. První "subscription" byla úspěšně synchronizována se serverem a byl doručen snapshot, při synchronizaci druhé "subscription" byla vrácena chyba "Invalid subscription", která je ale natolik obecná, že jsem nejdříve několikrát generoval znovu snapshot na serveru a zkoušel zakládat nové "subscription". Jako poslední zoufalcovo gesto jsem prohodil pořadí synchronizace obou subscription - synchronizace druhé (původně první) "subscription" selhala. Takže i když se CE server „tváří“, že podporuje paralelně více subscription, nevěřte tomu a adekvátně upravte svůj návrh publikace.
11. API pro replikaci v compact .NET Frameworku představuje rozhraní třídy SqlCeReplication,
Příklad práce s objektem SqlCeReplication:
Vytvoříme pomocnou metodu, abychom měli v replikačním manažeru na jednom místě inicializaci vlastností instance třídy SqlCeReplication.
private SqlCeReplication getDefaultReplicationClass()
{
SqlCeReplication replication = new SqlCeReplication();
//Připojovací řetězec k CE databázi
replication.SubscriberConnectionString = m_connectionString;
//URL IIS agenta (souboru sscesa20.dll)
replication.InternetUrl= m_internetURL;
//Libovolný řetězec, který bude na serveru použit k filtrování tabulek (článků) - v MSSQL hodnotu vlastnosti vrátí funkce HOST_NAME.
replication.HostName = m_hostNameValue;
//Libovolný unikátní identifikátor jednoho PDA klienta
replication.Subscriber = m_subscriberValue;
//Když není prázdné heslo, tak je zvolena "basic" nebo "anonymní" autentizace V IISreplikačním agentovi
if ((m_internetUserPassword != String.Empty) &&
(m_internetUserPassword != null))
{
//Přihlašovací jméno uživatele (IIS replikační agent)
replication.InternetLogin = m_internetUserName;
//Heslo uživatele (IIS replikační agent)
replication.InternetPassword = m_internetUserPassword;
}
//Název databázoveho serveru s publikací
replication.Publisher = m_remoteServerName;
//Název databázoveho serveru s publikací
replication.PublisherDatabase = m_remoteDatabase;
//Název publikace
replication.Publication = m_publicationName;
//Typ autentizace k MSSQL (NT nebo SQL)
replication.PublisherSecurityMode = this.m_serverSecurityMode;
//Jestliže je zvolena SQL autentizace k MSSQL, doplníme jméno a heslo
if (m_serverSecurityMode == SecurityType.DBAuthentication)
{
//Přihlašovací jmeno k SQL serveru (SQL účet)
replication.PublisherLogin = m_serverLoginName;
//Heslo k SQL serveru (SQL účet)
replication.PublisherPassword = m_serverLoginPassword;
}
//Vrácení inicializovaného objektu SqlCeReplication
return replication;
}
Metoda pro spuštění replikace.
public bool RunReplication(bool reinitialise)
{
//Resetování členské proměnné,která nese informaci o počtu provedených změn při poslední replikaci
m_totalChanges = 0;
//Získání inicializovaného objektu SqlCeReplication SqlCeReplication ceReplication = getDefaultReplicationClass();
//Podmíněná reinicializace "subscription" (=vynucení si opětovného dodání snapshotu)
if (reinitialise)
{
ceReplication.ReinitializeSubscription(true);
}
try
{
//Metodou Synchronize spustíme replikaci dat. Předtím můžete ještě voláním ceReplication.CreateSubscription založit „subscription“ před první synchronizací. V replikačním manažeru spravují „subscriptions“ speciální metody.
ceReplication.Synchronize();
//Celkový počet změn je součtem změn provedených na klientovi a serveru
m_totalChanges += (ceReplication.PublisherChanges + ceReplication.SubscriberChanges);
return true;
}
catch (Exception e)
{
//Jestliže došlo k chybě, naplníme členskou proměnnou m_lastReplicationError s popisem chyby pro prostého uživateli
m_lastReplicationError = STATIC_REPLICATION_ERROR_MESSAGE + Environment.NewLine + e.Message;
return false;
}
finally
{
//Objekt SqlCeReplication používá neřízené prostředky, proto zavoláme jeho metodu Dispose.
if (ceReplication!= null)
{
ceReplication.Dispose();
}
}
}
Tento kód předpokládá, že MSSQL server s rolí „publisher“ je současně i „distributor“ publikace.
12. Jestliže chcete zjistit, jaké chyby při replikaci nastaly, tak po zachycení výjimky SqlCeException projděte její kolekci Errors, která obsahuje objekty SqlCeError, a zkontrolujte jejich vlastnosti Hresult, Message, NativeError a Source.
13. Na serveru můžete logovat činnost IIS replikačního agenta přidáním nového klíče do registrů pod větev HKLM\Software\Microsoft\MSSQLSERVERCE\Transport. Klíč musí být typu DWORD a jeho názvem musí být fyzická (!ne virtuální) cesta k adresáři, v němž je umístěn soubor sscesa20.dll, doplněná řetězcem LOGGING_LEVEL. Hodnota klíče musí být v intervalu od 0 do 3 (0 – logování vypnuto, 1 – logování chyb, 2 – logování chyb a varování, 3 – logování chyb, varování a všech informativních hlášení). Po zapnutí nebo změně úrovně logování musíte restartovat IIS. Soubor s logem je vytvořen v adresáři IIS replikačního agenta a jmenuje se Sscerepl.log. (klíč c:\Inetpub\Sqlce20Agent\ LOGGING_LEVEL s hodnotou 1 zapne po restartu IIS logování chyb do souboru c:\Inetpub\Sqlce20Agent\ Sscerepl.log).
14. V books online pro SQL CE 2.0 si pozorně prostudujte článek o mapování mezi datovými typy MSSQL a SQL CE 2.0 (MSSQL ), abyste již při návrhu databáze počítali se všemi omezeními SQL CE klienta. Článek má název Supported Data Types and Data Type Mappings.
Sunday, 12 September 2004 18:35:00 (Central Europe Standard Time, UTC+01:00)
(MS)SQL tipy a triky
Thursday, 09 September 2004
Interval - článek Návrh aplikací v jazyce UML - textová specifikace případů užití
Další článek o UML mi dnes vyšel na serveru Interval.cz. I když pojem UML je dnes v názvu článku použit spíše jen ze setrvačnosti a také respektu k celému názvu seriálu, protože se zabývám návrhem struktury šablony dokumentu, ve které je umístěn podrobný popis případů užití.
Tímto článkem jsem opustil problematiku případů užití a příště již přijde na řadu (IMHO) nejzajímavější diagram v UML - diagram tříd.
Thursday, 09 September 2004 08:35:00 (Central Europe Standard Time, UTC+01:00)
UML
Friday, 27 August 2004
Podílejte se na rychlém konci éry bastlířů softwaru. Objektovými principy a návrhovými vzory řízený design a vývoj kvalitních aplikací.
Ve spotu z minulého týdne jsem sliboval překvapení pro příznivce OOP, UML a návrhových vzorů a hlavně pro ty, kdo mi psali, že by ode mě chtěli konzultaci nebo školení v designu aplikací. I když někteří z vás nabízeli opravdu zajímavé podmínky, musel jsem vždy odepsat, že žádné školení ani konzultaci neposkytuji. Důvody byly stále stejné. Mám dostatek vlastní práce a k courání po externích firmách nemám důvod. Žádostí ale bylo čím dál tím více, takže jsem se rozhodl s naším školícím střediskem připravit cyklus přednášek o OOP, UML a návrhových vzorech doprovázený podrobnými praktickými příklady kódovanými v jazyce C#.
Orientační program kurzu:
1. den
- Přivítání účastníků kurzu.
- Úvodní informace o zaměření a organizaci kurzu.
- Základní pojmy OOP a UML..
- Mýty o OOP a UML.
- Vysvětlení rozdílů mezi business analýzou, systémovým designem a implementací aplikace na konkrétní platformě.
- Světlo v temnotách – Model Driven Architecture (MDA)
- Základní architektura a rozvrstvení aplikace.
- Statický pohled na systém – vytváříme základní diagram tříd a ověřujeme, že jsou v něm zaneseny všechny informace, jež jsou nám známy z případů užití.
- Zvolení složitosti diagramu tříd. Potřebujeme vždy flexibilní doménový model?
- Zapouzdření objektů, polymorfismus, návrh metod.
i. Důležitost principů kovariance a kontravariance.
ii. Různé typy soudržnosti metod.
iii. Rozhodnutí o typu viditelnosti u každého člena třídy.
iv. Jaké konstruktory by měl nabízet každý objekt z problémové domény? Jak určit vlastnosti pouze pro čtení.
v. Ověření bezpečného chování třídy vůči potenciálním klientům.
- Precizní definice vztahů mezi třídami. Asociace, kompozice, agregace, závislost, realizace, generalizace.
- Vysvětlení rozdílů mezi abstraktní třídou a rozhraním (interface).
i. Vztah mezi typem a podtypem.
ii. Rozpoznání primárního účelu (hlavního smyslu) třídy i jejich sekundárních odpovědností vynucených vztahy s objekty z různých vrstev.
- Praktický příklad - ukázka implementace vzorových vztahů mezi objekty, perzistence objektů z problémové domény a zobrazování dat. (jazyk C#)
- Separace kódu pro ukládání a obnovení objektů z perzistentního úložiště v samostatné vrstvě.
- Jak zajistíme, že v paměti počítače existuje nanejvýš jedna instance objektu se stejnou identitou.
- Ukázky různých způsobů mapování agregace, kompozice, generalizace a asociace do databáze.
- Zajištění existence maximálně jedné instance objektu v systému.
- Efektivní ukládání a nahrávání kolekcí.
- Jak se slučuje objektový přístup a přímé použití DataSetu (recordsetu) v uživatelském rozhraní?
- Odpovědi na dotazy frekventantů kurzu.
2. den
- Vysvětlení pojmu návrhový vzor.
- Kdy byste měli používat návrhové vzory?
- Základní vzory (GoF vzory)
- Vzory pro řízení vzniku objektů.
- Strukturální vzory.
- Vzory pro chování objektů.
- Začlenění návrhového vzoru do designu aplikace. Kreativní aplikace vzorů.
- Kompozice vzorů do vyšších sémantických celků.
- Příklady odvozených návrhových vzorů často používaných při designu informačního systému.
- Kdy byste neměli používat návrhové vzory?
- Příklad - ukázky implementace složitějších vzorů. (jazyk C#).
- Odpovědi na dotazy frekventantů kurzu.
3. den
- Typické problémy při modelování informačního systému a jejich řešení.
- Modelování složitých organizačních struktur.
- Výhody vytváření fasád (Facade) pro aplikace s více než jedním typem uživatelského rozhraní (lehký klient, těžký klient).
- Evidence kompletní historie objektu.
- Aplikační role a práva uživatelů.
- Modelování toku peněz (zboží) v systému.
- Vytvoření flexibilního systému, jehož chování je změněno bez rekompilace aplikace.
- Příklad – ukázky řešení problémů při modelování informačního systému. (jazyk C#).
- Odpovědi na dotazy frekventantů kurzu.
- Ukončení kurzu.
Kurz se koná 3.11 - 5.11 2004 a jeho lektorem je samozřejmě moje maličkost. Jestliže vás program kurz zaujal, podívejte se prosím na jeho oficiální stránku, na které se můžete přihlásit. A pokud si stejně jako já myslíte, že zlatokopeckou dobu vývoje softwaru, kdy neznalý zákazník byl ochoten platit za zpatlanou aplikaci jakémukoli bastlíři, který za svoje excelentní know how považuje znalost syntaxe nějakého triviálního programovacího jazyka, halí opar blížícího se "fin de siecle” a že v nové éře musí kódování předcházet kvalitní návrh, jemuž rozumí všichni vývojáři, tak je kurz určen právě vám. Máte-li nějaké dotazy, napište je prosím do diskuze.
Aktualizace: Kurz je již obsazen (takový zájem mě opravdu těší), ale právě dohadujeme další termíny, aby se dostalo na všechny zájemce ;)
Friday, 27 August 2004 16:08:00 (Central Europe Standard Time, UTC+01:00)
Kurzy UML a OOP | UML
Sunday, 22 August 2004
TMO má podivná pravidla pro účtování GPRS přenosů v den změny paušálu
Jak jsem psal nedávno ve spotu “TMO a vyřizování reklamace, tohle mi můj oblíbený operátore nemáš dělat”, lehce labilní a přidrzlá operátorka na TMO infolince se mě snažila při reklamaci podivného vyúčtování GPRS služeb odbýt poukazováním na skutečnost, že TMO se spletl v můj prospěch a že po změně GPRS tarifu z Unlimited na Basic ve 22.30 mi měl být naúčtován celý den tarifem Basic, nejen některé položky. Moje reklamace byla vyřízena v pátek a z rozhovoru s reklamačním oddělením vyplynulo:
1) Nový GPRS tarif platí opravdu od 00.01 hodin dne aktivace tarifu bez ohledu na přesnou dobu aktivace tarifu. Když byste přenesli přes tarif Unlimited 100 MB a večer přešli na tarif Basic, tak 100 MB vám bude účtováno tarifem Basic, což už je částka, kterou na faktuře poznáte. Nevěřil bych ani reklamačnímu oddělení, ale informaci o průběhu změny tarifu mi potvrdil zdroj blízký TMO, který si nepřál být jmenován :) Konkrétní odkaz na nějaký dokument, kde je toto pravidlo popsáno, jsem ale opět nedostal.
Docela přisprostlý způsob, jak oškubat nevědoucího zákazníka, a poskytnout mu službu za cenu, která nebyla ještě v době užívání služby v platnosti. Nevědoucích zákazníků bude asi většina, protože ani členové GSM SH konference, kteří se o mobilní komunikace a služby operátorů zajímají více než průměrný zákazník (ať už ten pojem znamená cokoli), o “progresivním” marketingovém žonglování s časem aktivace a užívání služby nic nevěděli.
2) Pravidlo pro změnu GPRS tarifu neplatí pro hlasové tarify. U hlasových tarifů je účtováno podle nového tarifu vždy v den následujícím po dni, kdy došlo ke změně hlasového tarifu. Marketingoví mágové asi teprve na vytváření matoucích pravidel pro změnu hlasových tarifů pracují. Škoda jen, že při zavádění nových pravidel nejsou vydávány bombastické tiskové zprávy s motivujícím sloganem "Pro váš lepší svět“, cash-flow si vylepšíme hned (poznámka pesimisty).
3) A na závěr to nejlepší. Tedy nejlepší jen z určitého pohledu. TMO mi přesto, že moje reklamace je neprávněná, peníze vrátí formou mimořádné individuální slevy v příším měsíci, protože faktura není v pořádku ;). Takže když se ozvete, TMO po pár ponižujících procedurách na infolince a po několikanásobném zaklínání se, že chyba je na vaší straně, uzná alespoň nepřímo, že pochybil sám.
Buď proto, že paradoxně zrovna na reklamačním oddělení sedí lidé, které zajímá více pověst TMO než pár stovek vytažených ze zákazníků marketingovým oddělením, u jehož zaměstnanců je asi nedostatek zdravého úsudku a skrupulí předpokladem pro dobrou kariéru, anebo jsem jen měl štěstí a v reklamačním oddělení TMO se náhodou moje stížnost dostala na stůl soudnému člověku s dostatečnými kompetencemi. Mně se nelíbí ani jedna možnost.
Na můj dotaz, jestli už TMO prověřil špatnou činnost billing centra nebo dalších fakturačních systémů a také zvážil, že by měl více informovat své zákazníky o podmínkách účtování datových tarifů, aby zamezil dalším reklamacím, protože snaha o vrácení několika stovek nebyla hlavním obsahem stížnosti, jsem už odpověď nedostal. Příběh bez pointy, ne mou vinou.
Sunday, 22 August 2004 16:52:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Tuesday, 17 August 2004
Interval - článek Návrh aplikací v jazyce UML - složitější diagram případů užití
Na Interval.cz se konečně objevil další díl seriálu o UML , ve kterém se zabývám generalizací a vztahy Include a Extend mezi případy užití.
Slovo konečně jsem v předchozí větě použil záměrně, protože jak jste si jistě všimli, dva měsíce jsem nepsal články, nepřispíval do blogu a jen občas jsem napsal nějakou odpověď do konference. Důvod je prozaický, role otce mě přes mé původní ambiciozní plány vytížila natolik, že místo psaní článků o analýze a vývoji jsem měl dostatek času připravit si v hlavě koncept neplánovaného a abundantní horoucí životní zkušeností naplněného eseje "Život mezi řevem, nespavostí, přebalováním a s absolutním nedostatkem času aneb poděkování manželkám, že si dovedou poradit v každé situaci”:) - vydavatelem finální verze by byl ale asi server eMimino, ne Interval . :)
Nyní jsem již většinu svých aktivit obnovil, i když si více vybírám komu a čemu budu věnovat svůj volný čas. Moje články o UML a .NET Frameworku by ale na Interval.cz měly vycházet stále.
A pro zájemce o UML , návrh aplikací a návrhové vzory, kteří byli zklamáni frekvencí článků o UML a psali mi motivující emaily :) jsem společně s DIGI TRADEm připravil jedno překvapení, o kterém ale napíšu více až příští týden. Myslím, že se máte opravdu na co těšit...
Tuesday, 17 August 2004 10:48:00 (Central Europe Standard Time, UTC+01:00)
UML
Monday, 16 August 2004
TMO a vyřizování reklamace, tohle mi můj oblíbený operátore nemáš dělat:(
V příspěvku není diakritika, protože text jsem původně posílal do konference
gsm@sh.cvut.cz
, do které se zásadně přispívá bez diakritiky.
Tak dnes me TMO pekne vytočil. Respektive jedna jeho pracovnice na infolince jmenem Richterova Petra.
Volal jsem, protože na cervencovem vyuctovani jsem nasel nesmyslne polozky za GPRS. Jak k tomu doslo?
30.7. Priblizne ve 22:30 jsem menil tarif GPRS Unlimited na GPRS Basic. Zmena probehla bez problemu.
31.7. Rano mi prisla SMS, ze mam aktivni tarif GPRS Basic.
Na podrobnem cervencovem vyuctovani se 30:7 objevily polozky, ktere byly uctovany tarifem Basic a /*mezi nimi*/ byly nezauctovane polozky.
Takto vypada muj podrobny vypis
GPRS prenosy z 30.7
O7:41 - 370 kB - cena 0,00
11:38 - 4 kB - cena 0,00
18:06 - 2517 kB - cena 151, 20
21:06 - 38 kB - cena 0,00
21:10 - 2 kB - cena 0,00
21:10 - 2 kB - cena 0,00
21:12 - 1780 kB - cena 106,80
22:45 - 45 kB - cena 0,00
22:01 - 2 kB - cena 0,00
22:02 - 10 kB - cena 0,00
22:03 - 381 kb - cena 0,00
Jak je patrne z vypisu, TMO si nauctoval 30.7. 2 datove prenosy, ostatni ne.
Nejprve jsem na infolince narazil na ochotnou slecnu, ktera rychle chapala, v cem je problem, a sdelila mi, ze v jejich systemu je zaevidovan datum zmeny tarifu 31.7 a ze jeste proveri vypis. Pak mi bohuzel spadlo spojeni s infolinkou (moje vina).
Pri druhem volani jsem mel potize vysvetolit operatorce zminene vyse, o jaky problem se vubec jedna, pak me nechala 2x nekolik (desitek) minut cekat, protoze pry "jeste neco overi".
Pote na me ale vytasila argumenty, ktere me dost konsternovaly a otrasly mou virou v kompetentnost TMO, se kterym jsem az do dneska nemel zadny problem - asi proto ze jsem nikdy nemusel zadnou fakturu reklamovat.
Mam pry byt rad (!), ze faktura je takova jaka je, protoze TMO se spletl ve svuj neprospech. Jak se to mohlo stat? Pry i kdyz jsem zadal o zmenu tarifu 30.7 nekdy kolem 11 hodiny vecer, tak cely den s datem 30.7 je uctovan jiz s tarifem Basic. Udajne toto pravidlo plati i pro hlasove tarify. Kdyz jsem slecnu pozadal, aby me odkazala na konkretni clanek ve Vseobecnych podminkach TMO nebo v jinem smluvnim dokumentu, ve kterem je toto pravidlo zmineno, slecna opacila ze "nema ted ani pozdeji moznost neco dohledavat, ale ze to tak urcite je".
Dale jsem se ji ptal, zda si nemysli, ze i kdyz by to bylo tak, jak rika, tak ma TMO chybu v systemu, protoze mi nebyly zapocitany vsechny polozky. Slecna rekla, ze s timhle nema co do cineni, ze to pro ni neni zajimavy, ze uz nedohleda, jestli vypadla databaze (sic!) a ze ja mam vlastne stesti, takze se o to nemusim dal starat, ale jestli chci, tak muzeme sepsat stiznost (minena reklamace?), ale ze pak doplatim zbytek prenosu za cele datum 30.7. Tak jsem rekl, ze me ta zbyvajici castka nevytrhne a ze bych rad vedel, na ci strane je pravda, takze stiznost sepiseme.
Slecna rekla, ze tak ucini a ja jsem se jeste zeptal, jak dlouho bude vyrizovani asi trvat. Jeji odpoved opet zachovala bodrou atmosferu celeho rozhovoru : "To vam nereknu, tohle se vyrizuje v jinem oddeleni v jinem meste a nikdo nevi, jak to muze dlouho trvat". Asi na doruceni stiznosti TMO z duvodu uspor pouziva postrelene holuby, protoze nechapu, jak se ve veku informacnich systemu muze tak velka firma jako TMO vymlouvat na to, ze ma nejake oddeleni v jinem meste. Pokud vim, TMO se ve Vseobecnych podminkach navic zavazuje, ze reklamace vyresi do 30 dnu. To opravdu slecny na infolinkach nemaji prehled ani o zakladnich smluvnich dokumentech?
Takze krome stiznosti se chci zeptat.
1) Je tu v konfere nekdo z TMO, koho zajima, jak pracuji jejich billing systemy a dokazal by proverit, v cem je opravdu zadrhel? Kdyz budete chtit podrobnosti, ozvete se mi prosim soukrome.
2) Nevite nekdo, jak je to opravdu s uctovanim po zmene tarifu?
3) A jedna polemicka. Tusite nekdo, proc operatori zamestnavaji tak neprofesionalni operatorky?
Monday, 16 August 2004 19:30:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Jedna špatná zpráva a dvě dobré ze světa PDA
Včera moje milované a hýčkané :) MDA II při vyjímání z pouzdra spadlo na zem a kryt, který je snad u všech prvních kusů MDA II (moje bylo koupeno 9.ledna - první den prodeje :) ) u vypínacího tlačítka od počátku naprasklý, se odlomil. Takže dnes jsem jej nesl do značkové prodejny TMO, kde mi sdělili, že tak 14 dní budu bez něj a že s 99% pravděpodobností mi závadu neuznají jako záruční. Na PDA jsem tak zvyklý, že se u mě jedná o malou tragédii, o jejíž tíhu jsem se musel podělit na blogu;).
Na serveru PocketGear se objevila informace o MDA IV. MDA III mě neláká, protože vestavěná liliputánská klávesnice ani podpora Wi-Fi nejsou dostatečným důvodem k výměně PDA.
MDA IV ale vypadá na jedno z "must have" zařízení příštího roku. Společnost HTC se pochlapila a hlavní vlastnosti MDA VI, které by nás měly donutit vybrat si právě tento model jsou:
- VGA displej (640x480) - na čtení e-knih ideální
- Processor XScale 624 MHz - současná špička v mobilních procesorech
- Quad-Band GSM
- Podpora UMTS
MDA IV by mělo být uvedeno v první polovině roku 2005, po zkušenostech s oddalováním dodávek MDA II odhaduji, že si radost udělám nejdříve o vánocích roku 2005.
Dalším špičkovým zařízením s Windows Mobile Phone Edition je Motorola MPX, která snad bude na trhu dříve než MDA IV.
Vybrané technické parametry:
- Procesor ARM OMAP 733 195 MHz
- Integrovaná klávesnice
- Unikátní skládací konstrukce (To se nedá popsat, koukněte se raději na obrázky)
- GSM Tri-Band ((900/1800/1900)
- Vestavěné Wi-Fi
Komu nečiní problémy francoužština, může si přečíst výbornou recenzi Motoroly MPX. na serveru Mobinaute.
Monday, 16 August 2004 18:33:00 (Central Europe Standard Time, UTC+01:00)
Mobilitky
Sunday, 15 August 2004
Windows služba pro pravidelné stahování souborů z Visual Source Safe databáze
I když je Visual Source Safe na mém soukromém žebříčku mizerných programů zcela zaslouženě na nelichotivém prvním místě a jeho programátory podezřívám, že byli do Microsoftu infiltrováni konkurenčními firmami a plní zde (nutno přiznat, že ale velmi úspěšně :) ) roli Trojského koně, musel jsem se smířit s tim, že ve firmě VSS stále používáme, byť všichni s kletbami na rtech. Protože ve VSS nemusí být ukládány jen zdrojové kódy, ale i dokumentace a analytické artefakty, o něž mají zájem i lidé*, kteří s VSS jinak nepracují a které nemá smysl nutit, aby instalovali a používali VSS klienta, rozhodl jsem se, že pro DIGI TRADE napíšu Windows službu, která vybrané projekty z VSS databáze v pravidelných intervalech uloží do adresáře v souborovém systému.
A protože se služba bude asi hodit více lidem, betu Windows služby si můžete zdarma stáhnout a otestovat.
Po rozbalení archivu musíte službu nainstalovat nástrojem InstallUtil.
installutil.exe DigiTrade.VSS.VSSService.exe
V konfiguračním souboru DigiTrade.VSS.VSSService.exe.config změňte cestu, kam má být ukládán "trace" log (hodnota atributu initializeData). Jestliže budete reportovat chyby, přiložte vždy prosím i "trace" log.
Účet, pod kterým běží služba, musí mít právo zapisovat do souboru s " trace" logem!
<add name="VSSListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\LOGS\VSSService.log"/>
Když chcete používat jiný soubor s VSS konfigurací (viz dále), změňte v souboru hodnotu klíče IniFile.
<add key="IniFile" value="VSSManagerConfig.xml"/>
Soubor s konfigurací VSS manažera (VSSManagerConfig.xml) má následující strukturu:
Element vssManager - kořenový element.
Povolený obsah - Elementy generalSettings, commonProjects a exactProjects
Element generalSettings - základní nastavení VSS služby.
Povolený obsah - žádný
Atributy
- vssIniFile - Cesta k ini souboru VSS databáze, se kterou má služba pracovat.
- userName - Jméno uživatele ve VSS, pod kterým se bude služba přihlašovat.
- password - Heslo uživatele ve VSS (v Betě není kryptováno!).
- saveAllItems - Pokud má atribut hodnotu true, tak se ignorují sekce commonProjects a exactProjects a dojde ke stažení všech projektů z VSS databáze.
- saveDirectory - Adresář, do kterého budou uloženy soubory z VSS.
- checkerInterval - Interval v minutách, po jehož uplynutí jsou stahovány soubory z VSS databáze.
Element commonProjects - projekty, které budou staženy vždy bez ohledu na jejich místo v hierarchii projektů ve VSS. Tuto sekci využijete například tehdy, když ve většině projektů máte podprojekty se stejným názvem.(například adresář DOC s dokumentací projektu).
Povolený obsah - element project
Element exactProjects - Projekty určené absolutní cestou (začíná znakem $), které mají být staženy z VSS.
Povolený obsah - element project
Element project - element reprezentující projekt ve VSS.
Povolený obsah - žádný
Atributy
Služba využívá přes interop COM knihovnu SSAPI.dll dodávanou s VSS.
Po instalaci doporučuji vytvořit pro službu nový Windows účet, pod kterým poběží a který bude mít přidělen jen nejnutnější práva - přístup k souboru s "trace" logem, přístup k VSS databázi a právo zapisovat do adresáře určeného atributem saveData. Vhodné je také vytvoření nového uživatelského účtu ve VSS.
Pro úplnost jen podotýkám, že vím o existenci konzolového nástroje ss.exe s desítkamí neintuitivních přepínačů, který je součástí VSS, ale správa desítek nebo stovek řádků v BAT souboru mě nelákala, a proto vznikla tato služba.
*Pro účely tohoto spotu jsem se rozhodl zjednodušeně považovat projektové manažery a obchodníky za lidi, i když u některých členů těchto kast mám o jejich pravé podstatě kvůli jimi bezskrupulózně projevované deficitní intelektuální potenci důvodné pochybnosti:)
Sunday, 15 August 2004 12:07:00 (Central Europe Standard Time, UTC+01:00)
.NET Framework | VSS Windows Service