More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  Digital Northern WindsPhotosProfileFriendsMore Tools Explore the Spaces community
Updated 2/17/2008
Updated 4/20/2008
Updated 10/5/2005
Updated 7/1/2005

Digital Northern Winds

Extraterrestrial Intelligence
March 18

Techdays 2008 - DAT07 resources

No seguimento da apresentação que eu e o Hugo fizemos no Techdays (ver post anterior), deixo aqui os slides e as demos da mesma.

Das demos faz parte uma aplicação que expõe um web service, que acede a uma base de dados SQL Server 2008 e retorna GeoRSS ou GML, consoante os parâmetros passados na query string. No html podem ver como é construído o url para aceder a este serviço.

Para utilizarem esta aplicação com a vossa base de dados, terão de adaptar a aplicação com os nomes das vossas tabelas / colunas.

Qualquer questão, não hesitem em colocar.

March 07

Techdays 2008: Sistemas de Informação Geográfica e o SQL Server 2008

Aproxima-se o Techdays 2008 e muitos de vós andam já a ultimar o preenchimento das vossas agendas.

Aproveito para informar que no dia 13, logo no primeiro slot (para ajudar a acordar), vou estar a fazer uma sessão, em conjunto com o Hugo Vilardouro (meu colega de trabalho e que será o orador principal), onde se vai introduzir o tema dos GIS (ou SIG - Sistemas de Informação Geográfica) e apresentar o caso prático da utilização do SQL Server 2008 nestes sistemas.

A sessão é a DAT07 e tem o nome: "Sistemas de Informação Geográfica e o SQL Server 2008 - tipos de dados espaciais e indexação", um nome que indica na perfeição aquilo que vai ser abordado durante a sessão.

Se têm curiosidade em saber o que é um GIS, ou para que serve, ou ainda como se constrói / utiliza na prática, apareçam!

Como introdução, podem consultar o serviço de GIS, o serviço de mapas e os mapas do SAPO.

February 17

eScrum, TFS and RSS

Há uns dias andei a fazer uma aplicação que gerasse um feed RSS com as actualizações dos projectos Scrum existentes no nosso servidor TFS.

Como já disse há uns posts, nós utilizamos a ferramenta eScrum, que por sua vez utiliza a base de dados do TFS para guardar toda a informação que necessita. O facto desta ferramenta integrar com o TFS, o que à partida pode parecer uma grande vantagem, neste caso específico não sei se a vantagem será assim tão grande.

A única vantagem que vejo é a integração com os bugs, podendo ser criados bugs no próprio VS, que depois se podem associar a tasks do eScrum. Mas isto já eu disse da primeira vez que falei aqui desta ferramente e desde essa altura que não encontrei mais nenhuma vantagem que advenha do facto de exisitir integração com o TFS.

Não vou aqui falar das desvantagens / "non-documented features" do eScrum, mas o facto de integrar com o TFS impõe algumas restrições ao sistema de informação associado. Para melhor expôr o problema, pensemos nos constituintes do (e)Scrum: temos os projectos Scrum, que por sua vez têm produtos. Cada um destes produtos tem um Product Backlog, que por sua vez tem Backlog Items. Cada projecto tem também associados sprints e cada sprint contém alguns Backlog Items no Sprint Backlog e cada um destes contém as subtasks que irão ser realizadas durante esse sprint. Como é óbvio, para cada um destes itens que acabei de referir, existem vários detalhes associados, como por exemplo, nome , datas, descrição, nº de horas envolvidas, etc. Para além de todas estas coisas, existe o Product Owner, o Scrum Master, os membros da equipa e dentro destes, os que fazem parte de cada sprint.

Posto isto, podem imaginar um sistema de informação bem organizado, em que os itens a bold (e talvez mais alguns, dependendo da implementação) se podem transformar em tabelas. Agora esqueçam aquilo em que acabaram de pensar: o eScrum guarda isto tudo na tabela WorkItem da base de dados do TFS, onde as linhas têm referências de umas para as outras e as colunas correspondentes a essas referências mudam consoante aquilo que se quer referir. Nuns casos são usados IDs, noutros o nome, noutros outras colunas textuais. What a mess...

A meu ver, a suposta vantagem de integração com o TFS (pelo menos neste caso específico) é feita através de um "hack" que só complica o sistema, não trazendo vantagens significativas. Acho que tinha muito mais a ganhar, se o eScrum mantivesse os dados numa estrutura própria e bem organizada.

Existem casos em que por questões de optimização, é útil ter uma base de dados não normalizada, mas este não me parece o caso.

Depois de explicar a "complexa" organização do sistema de informação do eScrum, resta dizer que se torna um pouco complexo construir uma aplicação que leia a informação que lá está guardada. A certa altura já não se sabe se estamos a construir uma query que vai buscar o Product Backlog ou o Sprint Backlog...

Nada que a velha máxima da engenharia não resolva: todos os problemas de engenharia se resolvem adicionando um nível de abstracção. Passemos então à resolução do problema, que se ainda se lembram, era gerar um feed RSS com as actualizações dos projectos Scrum.

Esta aplicação usa WIQL (Work Item Query Language) para obter dados do TFS, que é uma linguagem de query semelhante a SQL.
Exemplo para obter as tasks do Product Backlog de um dado projecto:

                     SELECT
                        [System.Id],
                        [System.State],
                        [System.AssignedTo],
                        [Microsoft.VSTS.Common.Priority],
                        [Microsoft.eScrum.Common.Order],
                        [System.Title],
                        [Microsoft.eScrum.Common.Category],
                        [Microsoft.VSTS.Scheduling.BaselineWork],
                        [System.AreaPath]
                    FROM WorkItems
                    WHERE [System.TeamProject] = '<ProjectName>'
                        AND [System.WorkItemType] = 'eScrum Product Backlog Item'
                        AND [System.State] <> 'Deleted'
                    ORDER BY [System.Title]

Onde <ProjectName> é o nome do projecto. Para obtermos os sprints, temos a query:

                    SELECT
                        [System.Id],
                        [System.State],
                        [System.AssignedTo],
                        [System.IterationPath],
                        [Microsoft.eScrum.Sprint.StartDate],
                        [Microsoft.eScrum.Sprint.EndDate]
                    FROM WorkItems
                    WHERE [System.TeamProject] = '<ProjectName>'
                        AND [System.WorkItemType] = 'eScrum Sprint Details'
                        AND [System.State] <> 'Deleted'
                    ORDER BY [System.Id]

Como podem ver, são duas queries bastante semelhantes, para obter coisas completamente diferentes. Estes são os caso simples do Product Backlog e dos sprints. Para as tasks e subtasks dos sprints, o caso torna-se um pouco mais confuso.

Para executar a query, usa-se o método Query do objecto WorkItemStore:

TeamFoundationServer tfs = new TeamFoundationServer(serverURI, new NetworkCredential(username, password, domain));
tfs.Authenticate();
WorkItemStore workItemStore = new WorkItemStore(tfs);
string query = string.Format(sprintsQuery, project);
WorkItemCollection sprints = workItemStore.Query(query);

Identificadas as queries principais, a utilização das mesmas pode ser encapsulada em operações da aplicação, que tenham um nome mais user-friendly. Estas operações retornam colecções de objectos que depois facilmente se trabalham para construir o feed pretendido.

Para contruir o feed utilizei a biblioteca RSS.NET, que evita que tenhamos de construir o código XML, trabalhando em vez disso com objectos .NET.
A aplicação que construi, de cada vez que é executada, cria vários RSS, por projecto e com resumos de todos os projectos, ficheiros estes que são construidos totalmente de cada vez que o processo corre e não de uma forma incremental. Para isto utilizo a data associada a cada WorkItem, o campo ChangedDate. Usando o ID do WorkItem como GUID de cada item RSS e o campo ChangedDate do WorkItem como PudDate dos itens RSS, é possível detectar alterações em cada item.

Finalmente, criar um ficheiro RSS com os sprints de um dado projecto é tão simples como:

           RssChannel channel = new RssChannel(
                "Scrum Sprints - " + project,
                "Scrum Sprint's Updates",
                new Uri("http://myserver/escrum/"));
           channel.LastBuildDate = DateTime.Now;

            foreach (WorkItem sprint in sprints)
            {
                RssItem item = GetSprintRssItem(project, sprint);
                channel.Items.Add(item);
            }

            RssFeed feed = new RssFeed();
            feed.Encoding = Encoding.UTF8;
            feed.Version = RssVersion.RSS20;
            feed.Channels.Add(channel);
            feed.Write(filename);

O resultado final, para o feed de resumo, é algo como:

image

January 29

Estado dos serviços em Portugal...

É ridículo demais...

Parte 1

 

 

Parte 2

 

 

Parte 3

 
January 27

Get Nokia Software Updater (NSU) up and running

Today I had several issues when I tried to do an update to my phone's firmware.  When I run the NSU application, it just get stucked in the initial startup screen and freezed for about 60 seconds, showing then an error message saying: "Missing Software Components - Some critical components were missing, please reinstall", or something like that.

Let me just say that I'm running on Windows Vista, with the latest version of both Nokia PC Suite and Nokia Software Updater, and with a non-administrative account.

After some trial-and-error with no results, I've unninstalled both apps, reboot, log-in as THE Administrator (not a regular administrative account) and installed first Nokia PC Suite and than Nokia Software Updater. Et voilá! It's working! Now it works even in my non-administrative account! :)

Developers should get used to develop applications targeting non-administrative users. Although these apps need to install drivers, wich requires administrative privileges, installing them with a "run as" approach should be sufficient.

January 10

"The specified service has been marked for deletion"

Se desenvolvem Windows Services, existe uma grande probabilidade de já terem apanhado este erro, quando instalam um serviço.

Isto pode acontecer por exemplo se não pararmos o serviço antes de fazermos uninstall. Mas também pode acontecer se se verificarem algumas condições (lá estou eu e a mania do determinismo), as quais ainda não consegui descobrir.

Segundo o KB existente no site da Microsoft, isto é resolvido reiniciando o computador antes de reinstalar o serviço... Uau! Isto para quem desenvolve serviços e os instala e desinstala com frequência é uma valente m£#*@!

Felizmente, existe uma forma mais simples de resolver o problema. Parece que existe um problema qualquer com o facto de desinstalarmos o serviço tendo a janela services.msc aberta (mais uma vez, não sei que condições são precisas para isto se verificar, visto que não acontece sempre). Após fechar a janela, já conseguimos instalar o serviço novamente!

Não sei se esta solução resulta em todos os casos, mas para mim tem funcionado.

December 31

WCF, bindings and message size

Em WCF, quando definimos os bindings (quer declarativamente no ficheiro de configuração, ou programaticamente no código), existem muitas coisas que não especificamos, quer por estarmos satisfeitos com os valores que têm por omissão, quer por não estarmos preocupados com determinada definição, ou por outra razão qualquer.
 
Uma das definições diz respeito ao tamanho das mensagens recebidas. De modo a limitar a exposição a ataques DoS, o runtime WCF impõe um limite ao tamanho das mensagens que são recebidas e que consequentemente limita a quantidade de memória alocada para a recepção de mensagens. Esta definição está disponível declarativamente através de <binding maxReceivedMessageSize="..." > ou programaticamente na propriedade binding.MaxReceivedMessageSize e tem por omissão o valor de 64k.
 
Quando nos é enviada uma mensagem que excede este limite, a mensagem é rejeitada e o canal fica faulted, caso seja session-full. Mesmo quando utilizamos calbacks, caso este limite seja excedido o cliente é avisado recebendo uma CallbackException e sendo gerado o evento Faulted associado ao canal.
 
Para alguns bindings existe também a propriedade MaxBufferSize. Esta propriedade, para bindings com buffer é sempre igual a MaxReceivedMessageSize (o runtime lança excepção se não for) e para bindings streamed este valor limita o tamanho do header da mensagem (apenas o header necessita de ser bufferizado).
 
Caso estejamos a receber ou retornar XML em alguma operação exposta no contracto WCF, existe ainda outra propriedade à qual devemos ter atenção, MaxStringContentLength (disponível através de <binding> <readerQuotas maxStringContentLength="...">). Também por razões de segurança, esta propriedade limita o valor do buffer que é utilizado pelo XmlReader e por omissão o seu valor é de 8k. É preciso especial atenção a este valor, pois caso seja excedido, mas inferior a MaxReceivedMessageSize, o runtime não lança excepção, descartando a mensagem silenciosamente, sendo possível continuar a utilizar o mesmo canal.