terça-feira, setembro 16, 2008

.NET + WEBSERVICES - SMS por E-Mail

Foi-me requisitado a análise e elaboração de uma aplicação activa de envio de sms's por e-mail.
Basicamente, o cliente envia um email para determinados números de telefone, por ex: 93456456@xxx.xx.pt e este é reecaminhado para o telémovel da pessoa a contactar.

Coloca-se desde logo um problema. Visto que deverá correr como serviço num servidor, pois quero que a aplicação se active independentemente do facto de existir alguém logado ou não no sistema, apenas este facto leva-me a pensar que terei de criar um Windows Service de propósito. Mas não.... Felizmente sou adepto fervoroso do Code Project e lá encontrei uma aplicação fantásticamente simples que faz aquilo que queria. Na verdade, o xyntservice faz isso. Vale a pena ver.


Finalmente e após análise dos requisitos, elaborei a base de dados para MSSQL.
Todo o programa foi desenvolvido em vb.net e usei como classes de manuseio de e-mail, umas antigas adaptadas que tinha no meu cofre de programas. 

A operadora de telecomunicações, forneceu o WEBSERVICE que propicia a interface de envio de smss. Basicamente teria de formatar a informação.

Mais tarde, desenvolvi uma aplicação de gestão para gerar relatórios para os clientes de numero de mensagens...etc.

A aplicação passou nos curtos testes e neste momento corre já à 2 meses sem grandes problemas.

Tempo de desenvolvimento: 1 mês e 15 dias
Plataforma de desenvolvimento: Windows + Visual Studio 2008
Linguagem de programação: vb.net
SGBD: MSSQL 2005



domingo, setembro 17, 2006

Networking Windows 2003 server

Mais um trabalho, mais uma dor de cabeça. Desta vez prende-se com o facto de migrar toda uma rede antiga assentada em tecnologia NT e Linux para Windows 2003.

A rede assenta em vários sectores com dois controladores de dominio (1 avariado), 2 servidores de aplicações, um proxy + mail (Linux) e 2 maquinas com aplicações partilhadas.

Redefenindo tudo, acordei com o cliente, uma rede com recursos Active Directory (Desde W2000), com partilha DFS, Storage server, Exchange e dois DC.

Os controladores de dominio serão 2 constituindo assim uma redundância segura em caso de falha de um deles. Os disco estão em raid por software.

Um aplication server, onde no fundo será também um file server, onde serão instaladas todas as aplicações do cliente (alguma bem antigas), aplicações essas que sofreram alguns testes de compatilidade, todos com sucesso.

Um Exchange Server com 3 discos em raid.

Um Storage server com o Windows 2003 Storage Server também com algumas aplicações de interesse, tais como o interface Web de Administração do Storage Server.

Um dos servidores antigos será constituido como um servidor de suporte a avarias.

Em vez do proxy, concluá que uma appliance Firewall, com gateway antivirus + RBL filter seria boa escolha.

Por fim, deslocalização do WWW portal para a zona DMZ.

Colocarei um desenho da solução aqui mais tarde.

Tempo de desenvolvimento: 1 mês e 15 dias
Plataforma de desenvolvimento: Windows 2003 R2 + Linux RedHat
Linguagem de programação: N/A
SGBD: N/A

segunda-feira, setembro 04, 2006

WRT54G3G - OPERACIONAL!!!!

Ok. Desta vez parece que ficou funcional. De 10 em 10 minutos ia abaixo mas com a alteração de última hora de usar o PROTO TCP em vez de PROTO UDP, resolveu a questão.

Clientes desligam VPN 3G

Mas que grande imbróglio. Após ter conseguido a ligação VPN, ao ligar um cliente especifico VPN, a ligação perde-se passados 10 minutos ou 1 hora. Porquê? Penso que tem a ver com o facto de não estar a fragmentar o tamanho dos pacotes enviados.
A testar nas configurações cliente/servidor:

Colocar TCP em vez de UDP;
Colocar fragment XXX em ambos os lados cliente e servidor;
Colocar mssfix xxx;

A ver como me saio. O cliente em questão é um automato que gera um volume de trafego substancial.

quinta-feira, agosto 24, 2006

WRT54G3G - ligando 2 routers 3G com openvpn

Finalmente. Após longas horas de compilação de firmware (openwrt) + configurações openvpn, lá consegui colocar os dois routers a comunicar. É uma solução única onde optei pelo modo de funcionamento em bridge. Cria uma ligação segura com certificados 128 bits mais tls authentication.

Tempo de desenvolvimento: 1 semana
Plataforma de desenvolvimento: Linux Fedora Core 5 + OpenWrt ToolChain
Linguagem de programação: Shell Scripting
SGBD: N/A

terça-feira, junho 20, 2006

Router 3g com HSDPA + OPENVPN - Parte 2

Consegui pingar hoje o router atraves da ligação VPN. O que não se consegue com Linux!!
Com esta configuração usei o OpenWrt , um firmware opensource em fase experimental especifico para o router wrt54g3g, router 3G/UMTS.
Segui recomendações de Documento disponivel em OpenWRT para compilar o Openwrt para wrt54g3g com especificações HSDPA (Nova tecnologia sem fios para telecomunicações que permite larguras de banda até 3,5 Mbps). A partir daqui foi só instalar pacotes adicionais de suporte para openVPN e fazer a ligação ao servidor de VPN , também OpenVPN em Windows.
Works like a charm...

segunda-feira, junho 19, 2006

Router 3g com HSDPA + OPENVPN

Nova tarefa, novo desafio. Desta vez prende-se com o facto de o cliente desejar efectuar uma ligação VPN a um automato atraves de um router 3g. De facto o router permite a ligação 3g, mas colocam-se alguns problemas.
  1. A ligação tem de ser efectuada por uma operadora especifica, não a que o aparelho traz configurados por defeito;
  2. O router faz somente VPN pass-through, o que quer dizer que não faz ligações vpn-ssl, apenas deixa passar;
  3. O código GPL para compilar o firmware deste aparelho não está completo e apenas permite compilar o que vem por defeito;
  4. O router permite apenas UMTS e GPRS e não HSDPA;

Soluções: Alterar os scripts do programa firmware concorrente, adicionar drivers nozomi (HSDPA Option), adicionar package de openvpn para compilação e testar.

Darei resultados no fim desta semana. A ver como corre...

sexta-feira, junho 16, 2006

ASP.NET Index and length must refer to a location within the string. Parameter: Length

Estamos na fase de testes da extranet elaborada para um cliente e um erro aconteceu logo no primeiro teste do cliente. Já me tinham dito que para testar, nunca pode ser o programador a faze-lo, pois temos tendência inconsciente de não testar o que provavelmente poderia gerar erro.

Pois o erro aconteceu e desde logo foi corrigido. No meu caso, uso muitas chamadas a subtrings que permite retirar caracteres de uma dada expressão. Um deles não estava a testar o tamanho da string antes de retirar a porção definida. Logo, quando apanhava uma expressão mais pequena do que o numero de carecteres que mandava retirar este gerava um erro.

If imovelbi.ToString.Length > 58 Then
imovelbi2 = imovelbi.ToString().Substring(0, 58)
Else
imovelbi2 = imovelbi
End If


Impus a condição anterior de apenas fazer substring até 58 caracteres se realmente tiver mais de 58 caracteres.

quinta-feira, junho 15, 2006

Cluster Step by step

Eis o local escolhido que irá acolher o bastidor que por sua vez irá acondicionar o Cluster Dl380s + ml350 + cablagem. Como se pode ver, a unica coisa que existe ainda são uns cabos pendurados ligados a um router.

Aqui já temos o bastidor colocado, assim como um primeiro esforço de colocar a cablagem.

Esteve-se também a certificar a cablagem. A cerificação é efectuado por um fluk que corre varios testes e conforme a nossa tabela de valores minimos aceitaveis por cabo, todos eles passaram com exito.


Em baixo fotos do meu local de trabalho para esta solução. Podemos ver o bastidor arranjado com as ups + ml350 + Cluster em pleno funcionamento.
Todo este trabalho foi efectuado em 2 dias sempre a correr. É uma solução que tinha algumas condicionantes e uma delas era por tudo em pleno funcionamento com o minimo tempo de paragem.




Replicação Transacional - SqlServer 2000

Hoje tenho de preparar uma replicação entre dois servidores de uma base de dados. Este cliente gere muita informação diáriamente e a aplicação de gestão que usam deve ser separada entre departamentos. No fundo pretende-se um género de Load Balance. Temos as caixas do supermercado e a área administrativa.
Neste momento, sempre que pretendem fazer uma análise de facturação ou outra do género, as caixas sofrem com a perda de perfomance. Sugeri uma replicação de base de dados, visto terem até dois servidores.
A replicação consiste na criação de réplicas de tabelas, seguindo o modelo publish-subscribe. Um publisher é um servidor de dados replicados. Um subscriber replica dados publicados pelos publishers. Entre eles há um distribuidor, que é responsável por obter os dados nos publishers e entregá-los aos subscribers. Aquela que vou usar é a transacional replication. Transacional: Um instantâneo inicial dos dados é enviado aos subscribers, e quando modificações de dados são feitas no publisher, as transações são propagadas para os subscribers. Este tipo de replicação garante as propriedades ACID (Atomicidade, consistência, isolamento, durabilidade). O tamanho da base de dados deste clientes excede já os 45 Gb (em ano e meio de actividade).
Bom, mais logo escrevo aqui as conclusões.

VIEWSTATE - ASP.NET Bug meu, Bug meu, diz-me tu quem é pior programador que eu?

Após o lançamento da minha última página, aliás com grandes alterações a nível de estruturação da programação, lancei-a para o servidor público na expectativa de não ocorrer nenhum erro. Deixem que vos diga algo importante. A pior pessoa que nós podemos pedir para testar a página, somo nós próprios, porque de maneira inconsciente não testamos da melhor maneira as partes que achamos que provavelmente tenham maior risco de erro. Peçam sempre a alguém de fora da vossa comunidade de programadores para testarem a página.

Após o envio, já estava a ocorrer um erro. A página nunca mais arrancou, ficando esta infinitamente num estado de procura, como quando esperamos que carregue uma página. Que teria acontecido? Liguei-me por FTP ao servidor remoto e reparei que a base de dados em ACCESS tinha um registo bloqueado (podemos sabe-lo se estiver no mesmo local um ficheiro do tipo .LDB). Estranho. O pior é que não havia maneira de apagar esse ficheiro pois dava sempre o erro de estar a ser usado por um outro processo. A única forma era drástica. Telefonar para o departamento técnico do alojamento e pedir-lhes para REINICIAR O IIS para libertar o serviço !!!!ehe...Simpáticos os tipos aliás. Isto é perigoso para eles porque iriam não só desactivar a minha página como também desactivar todas as outras que estavam ligados com aquele IIS. Após desactivarem os serviços lá consegui colocar a página no ar. O que teria acontecido??

De facto as alterações na página relativamente a todas as outras que fiz, tem a ver com o método LoadControl do controlo Placeholder. Agora em vez de ter varias páginas com usercontrol tenho uma página que faz o load dinamicamente do controlo. Isto provoca algumas alterações nos ViewStates das páginas. Se estes não forem guardados na variavel local , não poderei ter certas interacções com o usercontrol usado, pois o viewstate não é guardado. Resolução??

If Not Me.ViewState("ctrlPath") Is Nothing And Request.QueryString("data") = "" Then
PlaceHolder1.Controls.Add(LoadControl(Me.ViewState("ctrlPath")))
endif


Imaginemos a seguinte situação. Temos uma página que dinamicamente carrega um controlo responsável pela pesquisa no site. Esse controlo tem um botão que despoleta eventos. Carregamos a página juntamente com o controlo e carregamos no botão para pesquisar por exemplo, em produtos. Fantástico. Se nós não guardasse-mos o viewstate desse controlo a página provavelmente nem carregaria se fosse chamada de outro usercontrol. Se não guardasse o viewstate da página e a carregasse novamente com o veiwstate guardado anteriormente, então nada acontecia e seria como se ela carregasse de novo.

Erro ao Iniciar IIS - 0x8ffe2740

Estava a trabalhar sossegado no meu pc, no Visual Studio, pois estava a finalizar uma página, quando um amigo me telefona a perguntar como está o trabalho. Queria mostrar-lhe, e para isso precisava redefinir o endereço IP atribuido ao meu router no IIS servidor web. Tudo correcto, mas o meu amigo não conseguia ver nada. Reparei que o IIS tinha um ícon de erro e encontrava-se desactivado. Ao tentar reinicia-lo, enviava-me para o ecran este erro: 0x8ffe2740 . O mais estranho, é que aquilo aconteceu a meio do trabalho, pois para poder-mos trabalhar em paginação web no VS, temos de ter o IIS a laborar. Verifiquei logs, eventos e nada me apontava o caminho. pesquisei na internet e de facto dizia-se que poderia ser um conflito na porta 80. Conflito na porta 80????
De facto, após fazer um levantamento dos programas que poderiam estar a causar o erro, reparei que uma das opçoes do Skype (Telefone grátis pela Internet), tinha como configuração, a porta 80 como porta alternativa em caso de bloqueio das portas normais do Skype. Retirei a checkbox da porta 80, desliguei o Skype, reiniciei o IIS e tudo voltou ao normal. Só não entendi porque terá acontecido.

quarta-feira, junho 22, 2005

Cluster em Cabo Verde

Faz algum tempo que não venho para estes lados escrever as minhas aventuras. Estou em Cabo Verde num cliente onde faz algum tempo, instalamos um servidor cluster HP com storage Area Network. Fantastica esta maquina, e não somos muitos os que têm a oportunidade de trabalhar e mexer num "monstro tecnológico" como esta máquina. A intalação e configuração demora muito tempo, e num negócio de alto risco, onde não existe espaço para paragens, a noite é a nossa companhia. Passei a noite em branco, para configurar esta máquina. Windows enterprise nos dois nós, configurar dns, dhcp, contas de utilizador, unidades organizacionais,administrador de cluster e por fim o sql developer. Poderia ser o enterprise também. O standard não suporta instalações em cluster. No fundo o que um cluster faz, é partilhar recursos nas duas máquinas, de forma a que quando uma for abaixo por um qualquer motivo, a outra entra em funcionamento, serviço este denominado por Fail-over cluster.
Enganem-se aqueles que disserem que é um serviço de load-balance, pois não é. No fundo uma máquina está desactiva e só entra em funcionamento após falha da primeira. Existe uma paragem minima de 1 minuto ou 2.Bom, mais tarde especifico o assunto que aqui abordei.

quinta-feira, junho 02, 2005

Andei perdido

Pois, isto de ter uma base de dados de conhecimentos perde-se algum tempo, coisa que não tive durante estes dias desaparecido. Tive bastante trabalho, algum dele delicado. Tive duas semanas a lançar 2 páginas, a elaborar 2 base de dados para um software de gestão conhecido, a instalar um servidor com bastantes serviços e ainda guardei tempo para ir ao "Get Ready for SQL Server 2005 RoadShow" que decorreu na antiga FIL, no Centro de Congressos de Lisboa. A organização foi boa e o tema foi separado por salas entre diversas sessões. Recomendo a darem uma espreitadela nas melhorias e novidades deste poderoso Sistema de Gestão de Base de Dados. Escrevo algo sobre isto mais à frente. Andei num enorme rodopio.
Elaborei uma página em tempo recorde de 5 dias sem dormir 2 pois tinhaprazo estipulado até dia 30. Lancei com alguns Bugs, mas somente na zona de administração (Zona responsável pela colocação de artigos, eventos, configurações gerais, etc...), pensando eu que essa zona não iria ser mostrada no briefing de apresentação... Erro meu. O briefing não correu da melhor maneira. Links perdidos, erros de escrita na base de dados (também 2 dias sem dormir não se podia pedir melhor). Bom, de qualquer maneira já está no ar e agora vou fazer a última actualização do dll criado. Um grande BUG meu, que tem uma resolução fácil, mas díficil de chegar até ela sem informação dísponivel.

sexta-feira, maio 13, 2005

IIS com Framework .NET para sistema de Suporte ao Cliente

Hoje vou instalar uma plataforma de suporte ao cliente numa das empresas para qual trabalho, que consiste num sistema de apoio ao cliente e de base de dados de conhecimento para os técnicos. Vou começar por preparar um servidor Web para integrar na DMZ da empresa com IIS 6, plataforma .NET windows server 2000.
Poderia tentar o windows server 2003 , mas a compatibilidade da base de dados do active directory 2000/2003 não me oferece confiança. Sei do comando adprep/domainprep (Infrastructure Master) e adprep/forestprep (schema master) para actualizar e preparar os controladores de dominio, mas as coisas por vezes não são tão lineares quanto isso. O interface gráfico vou programa-lo em asp.net com base de dados MSSQLSERVER. E ver vamos como fica.

quarta-feira, maio 11, 2005

Perda de dados em tabelas de ERP

Hoje fui a um cliente apressadamente porque a aplicação de gestão, não estava a reportar-lhe os extractos bancários. Achei estranho, mas lembrei-me que na 2º feira tinham-me ligado dessa empresa a dizer que uma alteração a uma transferência bancária, tinha demorado mais do que o costume, 20 minutos mais do que o costume.
Pensei que tivesse algo a ver com updates de tabelas, pois a aplicação tinha sofrido um upgrade à pouco tempo. Cheguei lá e constatei que todos os movimentos de tesouraria, todas as linhas, tinham sido actualizadas com os dados da alteração à transferência bancária. Que fazer?? Backup???...apesar de terem sido avisados mais do que uma vez, a verdade é que o último backup que havia era de julho de 2004. Sorte a minha e do cliente, que quando fiz o upgrade, tinha efectuado uma cópia de segurança (IMPORTANTÍSSIMO!!), só que com 1 mês de atraso. Apaguei as tabelas de movimentos de tesouraria e extractos bancários e copiei as duas tabelas da cópia de segurança para a base de dados que estava a ser usada. Antes disso certifiquei-me que os triggers estavam desactivados (pois as duas tabelas tinham triggers para insert, update e delete.), fiz truncate table xxxx (Reinicia a tabela) e passei os dados para as tabelas vazias. Muito bem...Mantiveram documentos, transferências, recibos, pagamentos etc, apenas teriam de processar novamente (fazendo o desprocessamento/processamento) para que o movimento fosse novamente inserido na tabela de movimentos e extractos.
Agora é esperar e ver se não me esqueci de algo importante. Ainda para mais a base de dados está na plataforma MSDE, que como suspeitam, limitava-me muito as tarefas que tinha de realizar.Porque aconteceu e o quê??... Bem liguei para a linha de apoio a cliente do softwre em causa, e estes limitavam-se a dizer pois...acho que sim, enquanto colocava o problema, expunha a solução e ainda lhe explicava porque tinha acontecido. O que de facto tinha acontecido, foi ao gravar um registo, um campo que funciona como chave primária de regist e que se relaciona com outras tabelas, tinha ficado em branco.
Daí até ao problema, foi um clique...

domingo, maio 08, 2005

Cannot perform an aggregate function on an expression containing an aggregate or a subquery

Deparei hoje com este erro quando estava a construir um mapa de analise para um cliente. Precisava somar todos os valores decorrentes de um conjunto de condicionantes (Case when end) mas n MS Sql não é possivel somar agregações. Não envio a query toda para aqui, pois é muito grande e complicada, mas dou um exemplo daquilo que falo:

select avg(count(ip)) from pagehits where [month] = 2 group by ip daria o seguinte erro "Cannot perform an aggregate function on an expression containing an aggregate or a subquery" e a unica maneira de dar a volta é usar o que se chama "Tabelas derivadas".

select avg(ipcount) from (select count(ip) ipcount from pagehits where [month] = 2 group by ip) as sub

Devo dizer que não existe muita informação quando se trata de queries bem mais complicadas.