quinta-feira, 30 de janeiro de 2020

Implementando SonarQube para Análise de Código de Projetos C#/VB.NET

Implementando SonarQube para Análise de Código de Projetos C#/VB.NET

O SonarQube é uma ferramenta (plataforma de código aberto) para inspeção da qualidade do código, detectar bugs, melhorias de código e vulnerabilidades de segurança em linguagens de programação.

Neste tutorial vamos criar um servidor de SonarQube para que seja possível executar a validação de um código de um projeto que esteja acessível localmente na máquina.

Passo 1 » Instalação e Configurando o Server de SonarQube

Vamos utilizar o portal do Azure para criar uma instância de contêiner para hospedar e rodar nosso servidor do SonarQube, será através desse servidor que será possível referenciá-lo no projeto ou Pipeline do Azure DevOps e também verificar os resultados das análises.

1. Acessar o Portal do Azure
2. Pesquisar um recurso “instância de contêiner”



3. Adicionar uma instância e definir dados Básico



Importante no preenchimento: 
Nome da imagem: sonarqube (esse é nome da imagem para criação do contêiner)
Tamanho: alterar para 2 vcpus e 3.5 de memória para suportar a instância

4. Na parte de rede é importante criar a Porta 9000/TCP e remover a porta 80/TCP



Importante no preenchimento: 
Rótulo do nome DNS: esse nome será endpoint do servidor SonarQube

5. Efetuar a revisão e criação da instância



6. Aguardar a implantação do recurso



Passo 2 » Configuração a Plataforma SonarQube e Criando o Projeto

7. Acessar a plataforma SonarQube no servidor criado
    Para acessar basta utilizar o endereço (FQDN) seguindo pela porta 



8. Utilizar o login e senha (admin/admin) para logar na plataforma

9. Iniciar um novo projeto para conectar com seu código fonte que irá ser analisado



10. Defina a chave do projeto, essa chave será utiliza para localizar o repositório do SonarQube para armazenar os resultados



11. Agora é necessário a geração do token que será utilizado para geração da analise



12. Selecione a linguagem C# or VB.NET



13. Faça o download do Scanner for MSBuild


14. Selecione o tipo de projeto e faça o download do pacote



Importante:
Para a execução dessa validação, o SonarQube Scanner necessita que o Java 11 esteja instalado (http://www.google.com/search?q= java+jdk+11)

15. Faça a extração o arquivo baixado para a pasta “C:\Arquivos de Programas\...”



16. É importante definir esse diretório no %PATH% do Windows, veja como em (http://www.google.com/search?q=Add+directory+to+your+PATH+environment+variable+windows)

Passo 3 » Execute a validação de código no Projeto

17. Agora basta acessar o “Developer Prompt de Comand for VS ????” e acessar a diretório onde está a solução do projeto que deseja gerar a análise


 18. Agora basta executar os comandos que foram exibidos no previamente no passo 12 



19. Ao final todos os dados coletados estarão à disposição para análise no portal do SonarQube




Numa próxima matéria, vamos implementar o SonarQube na esteira (CI/CD) do Azure DevOps.

Marcelo Goberto de Azevedo
Arquiteto na GFT Brasil
https://marcelogoberto.blogspot.com/


segunda-feira, 27 de janeiro de 2020

Evolução da Arquitetura de Software

Evolução da Arquitetura de Software


A cada época é possível escolher a "melhor" arquitetura a ser usada, porém como saber qual é a melhor de verdade? Essa pergunta sempre persegue os arquitetos e desenvolvedor no dia a dia, porque são tantas opções e opiniões que na maioria das vezes simplesmente escolhemos a opção mais utilizada no mercado atual.

Definitivamente o ponto mais importante na escolha de um modelo de arquitetura, é o domínio da mesma. Não adianta nada escolher algo que estão em alta no mercado, porém não se tem um profundo conhecimento do seu funcionamento, configurações e características. você estará provavelmente incorrendo em grande chances de perder o controle e gerar problemas futuros, por falta de domínio da arquitetura.

O primeiro passo para escolher a arquitetura é conhecer teoricamente seu modelo. Hoje o acesso ao conteúdo é vasto, simples e muito fácil, afinal a internet está ai para isso, porém importante descartar, é que estudar não é simplesmente achar uma solução, copiar, colar e testar, o conceito de estudar é tomar para si conhecimento e saber utilizá-lo na obtenção de resultado com ciência de seu funcionamento.

Com o conhecimento técnico adquirido, o próximo passo é efetuar a prática do modelo, por que ela irá lhe atribuir outros conhecimentos além da teoria, a cada nova implementação você terá a oportunidade de realizar o conhecimento, a possibilidade de descobrir novos pontos que aumentaram sua confiança na utilização da referida arquitetura, aumentando seu nível de experiência.

Por fim, compartilhar esse conhecimento, na maioria das vezes, é praticamente impossível ter todos os conhecimentos e nuances sobre uma solução. Pelo meio do compartilhamento podemos preencher essas pequenas lacunas com a experiência alheia e ainda, fornecer informações para que outros possam acelerar seu processo de maturação. Ou seja podemos fomentar melhores profissionais criando um ambiente corporativo com mais qualidade.

E claro, mesmo que você tenha o autoridade sobre um ou mais modelo de arquitetura, nunca se esqueça que, em tecnologia o "melhor" de hoje, inevitavelmente se tornará o "obsoleto" no amanhã. Por isso jamais deixe de continuar adquirindo conhecimento, experimentando novos modelos, por assim além de um arquiteto de completo,  você se tornará um grande profissional com o perfil dinâmico.

Marcelo Goberto de Azevedo 
Arquiteto na GFT Brasil

https://marcelogoberto.blogspot.com/




segunda-feira, 20 de janeiro de 2020

COMPREENDENDO INNER JOIN, LEFT JOIN, RIGHT JOIN e FULL OUTER JOIN




O conceito é bem simples, todos nós aprendemos na escola a teoria dos conjuntos, logo a extração de informação com interseção no SQL é simplesmente gerar um subconjunto do conjunto universo.

Digamos que tenhamos duas tabelas, sendo uma de CLIENTE e outra de PEDIDO, conforme a estrutura abaixo:

CLI_CLIENTE
CLI_N_CODIGO
CLI_C_RAZAO
CLI_C_PAIS
1
Acne Ltda
Brasil
2
Limofer Industria
China
4
Kimber Partner S/A
EUA

PED_PEDIDO
PED_C_CODIGO
PED_CLI_N_CODIGO
PED_D_DATA
PED_N_VALOR
100/2019
1
2019-05-01
300,00
101/2019
1
2019-09-12
550,00
102/2019
4
2019-09-24
1000,00
100/2020
5
2020-01-01
600,00

INNER JOIN

Forma clássica de retorno do subconjunto somente com o que é comum na ligação (ON) entre as tabelas.

SELECT CLI_N_CODIGO, CLI_C_RAZAO, PED_C_CODIGO, PED_D_DATA, PED_N_VALOR
       FROM CLI_CLIENTE
              INNER JOIN PED_PEDIDO
                    ON CLI_N_CODIGO = PED_CLI_N_CODIGO

CLI_N_CODIGO
CLI_C_RAZAO
PED_C_CODIGO
PED_D_DATA
PED_N_VALOR
1
Acne Ltda
100/2019
2019-05-01
300,00
1
Acne Ltda
101/2019
2019-09-12
550,00
4
Kimber Partner S/A
102/2019
2019-09-24
1000,00

LEFT E RIGHT JOIN

Retorna somente a partir da tabela que e direção que está sendo usado, no caso do LEFT (a primeira tabela) e RIGHT (a segunda tabela) do JOIN.

SELECT CLI_N_CODIGO, CLI_C_RAZAO, PED_C_CODIGO, PED_D_DATA, PED_N_VALOR
       FROM CLI_CLIENTE
              LEFT JOIN PED_PEDIDO
                    ON CLI_N_CODIGO = PED_CLI_N_CODIGO

CLI_N_CODIGO
CLI_C_RAZAO
PED_C_CODIGO
PED_D_DATA
PED_N_VALOR
1
Acne Ltda
100/2019
2019-05-01
300,00
1
Acne Ltda
101/2019
2019-09-12
550,00
2
Limofer Industria
NULL
NULL
NULL
4
Kimber Partner S/A
102/2019
2019-09-24
1000,00

SELECT CLI_N_CODIGO, CLI_C_RAZAO, PED_C_CODIGO, PED_D_DATA, PED_N_VALOR
       FROM CLI_CLIENTE
              RIGHT JOIN PED_PEDIDO
                    ON CLI_N_CODIGO = PED_CLI_N_CODIGO

CLI_N_CODIGO
CLI_C_RAZAO
PED_C_CODIGO
PED_D_DATA
PED_N_VALOR
1
Acne Ltda
100/2019
2019-05-01
300,00
1
Acne Ltda
101/2019
2019-09-12
550,00
NULL
NULL
100/2020
2020-01-01
600,00
4
Kimber Partner S/A
102/2019
2019-09-24
1000,00

FULL OUTER JOIN

Retorna todo o conjunto relacionando os dados que existem  entre a ligação (ON) e para os casos que não haja ligação carregados os dados nullos.

 SELECT CLI_N_CODIGO, CLI_C_RAZAO, PED_C_CODIGO, PED_D_DATA, PED_N_VALOR
       FROM CLI_CLIENTE
              FULL OUTER JOIN PED_PEDIDO
                    ON CLI_N_CODIGO = PED_CLI_N_CODIGO

CLI_N_CODIGO
CLI_C_RAZAO
PED_C_CODIGO
PED_D_DATA
PED_N_VALOR
1
Acne Ltda
100/2019
2019-05-01
300,00
1
Acne Ltda
101/2019
2019-09-12
550,00
2
Limofer Industria
NULL
NULL
NULL
4
Kimber Partner S/A
102/2019
2019-09-24
1000,00
NULL
NULL
100/2020
2020-01-01
600,00

Segue um infográfico que ajuda no entendimento de cada tipo de ligação.


Marcelo Goberto de Azevedo
Arquiteto na GFT Brasil
https://marcelogoberto.blogspot.com/

quarta-feira, 15 de janeiro de 2020

Piores Coisas para Encontrar em Código Fonte


Todo desenvolvedor irá se deparar com sustentação de sistemas em vários momentos de sua carreira, logo será inevitável ter que efetuar manutenção em código alheio e existem coisas que são feitas no código fonte que até tiram do sério até o mais puro desenvolvedor samaritano, vamos a elas:

Comentarista de Código

Todos sabemos a importância de comentar código fonte para que esse conteúdo possa auxiliar num futuro próximo a manutentabilidade. Entretanto para muitos desenvolvedores, simplesmente recebem o espírito de comentarista esportivo ou comediante e os comentários acabam por narrar tudo que está sendo feito ou declarar situação engraçadas, vejo o modelo abaixo:

public IHttpActionResult Get()
        {
            // Criar lista de retorno
            List<LogModel> lLogs = new List<LogModel>();
            try
            {
                // Efetuando conexão com o banco de dados
                using (SqlConnection con = new SqlConnection(WebConfigurationManager.ConnectionStrings["DbLog"].ConnectionString))
                {
                    // Definindo o nome da Stored Procedure
                    using (var com = new SqlCommand("ListLog", con))
                    {
                        // Abrindo conexão
                        con.Open();

                        // Recuperando os dados
                        var dReader = com.ExecuteReader();

                        //Percorrendo os dados
                        // Não MEXER, funciona como se DEVE
                        while (dReader.Read())
                        {
                            // Instância um novo objeto na lista
                            lLogs.Add(new LogModel
                            {
                                // Preenchedo as propriedades do objeto
                                Event = Convert.ToDateTime(dReader["DtEvent"]),
                                Actor = dReader["DsActor"].ToString(),
                                Category = dReader["DsCategory"].ToString(),
                                Content = dReader["DsContent"].ToString()
                            });
                        }

                        //Fechando a conexão
                        con.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                // Retornando erro (caso aconteceça)
                return Content(HttpStatusCode.BadRequest, ex.Message);
            }

            // Retorna com sucesso a lista recuperada
            return Ok(lLogs);
        }


DICA: Faça comentários que agreguem a explicação das regras e não simplesmente explicar os comandos que a linguagem executa, imagine que outros desenvolvedores também sabem como utilizar os comandos.

Manipular as exceções

Quando uma linguagem é criada, os arquitetos têm que a preocupação de criar mecanismos para retornar os erros quando acontecem e formas de capturar essas exceções para que possam ser analisadas e tratadas. Porém existem os “arquitetos” das aplicações que acreditam que podem criar exceções melhores, simplesmente manipulando ou substituindo os conteúdos, gerando resultado muitas vezes com pouca ou nenhuma informação pertinente.

static void Main()
            {
                double a = 98, b = 0;
                double result = 0;

                try
                {
                    result = a / b;
                    Console.WriteLine("{0} dividido por {1} = {2}", a, b, result);
                }
                catch (Exception e)
                {
                    Throw New Exception("Erro na divisão.");
                }
            }

DICA: Procure manter o estado original das exceções, efetuando no máximo acréscimo, porque dessa forma em outras camadas do sistema, será possível acessar informações mais precisas e completas. 

Artista de Codificação

Manter um código bem indentado e organizado ajuda muito para o processo de leitura e entendimento, entretanto alguns desenvolvedores vão além desse conceito e se tornam verdadeiros artistas e criando belíssima obras de artes, que muitas vezes impossibilitam a alteração por medo de estragar a obra de arte (entenda-se mexer em algo que não dá para entender e estragar o conjunto da obra)

public Indentation()
    {   while (n > 0) { System.out.println(); n++; }
        if (Cond1 == val1) { System.out.println("Cond1 is val1"); } else if (Cond1 == val2) { System.out.println("Cond2 is val2"); } else { System.out.println("No condition is satisfied"); }
        switch (Val1) {
            case 1: System.out.println("This is Java"); break; // Here is Java
            case 2: System.out.println("This is C#"); break; // Here is .NET
            case 3: System.out.println("This is Oracle"); break; // Here is Oracle
            default: System.out.println("This can be anything"); break; } 
    }


DICA: Quando mais claro e estruturado o código fonte, mais fácil ficará a visualização e o entendimento da cadência do código, evite a sobrecarga de comando em uma linha.

Uso de Números Mágicos

Muitos desenvolvedores acabam criando conhecimento ocultos que acabam sendo transpassados para seus códigos fontes, uma dessas técnicas é a utilização de números cabalísticos que alteram a lógica da programação pela sua simples existência.

        public decimal ApplyDiscount(decimal price, AccountStatus accountStatus, int timeOfHavingAccountInYears)
        {
            decimal priceAfterDiscount = 0;
            decimal discountForLoyaltyInPercentage = (timeOfHavingAccountInYears > 5) ? (decimal)5 / 100 : (decimal)timeOfHavingAccountInYears / 100;
            if (accountStatus == 1)
            {
                priceAfterDiscount = price;
            }
            else if (accountStatus == 2)
            {
                priceAfterDiscount = (price - (0.1m * price)) - (discountForLoyaltyInPercentage * (price - (0.1m * price)));
            }
            else if (accountStatus == 3)
            {
                priceAfterDiscount = (0.7m * price) - (discountForLoyaltyInPercentage * (0.7m * price));
            }
            return priceAfterDiscount;
        }

DICA: Nunca utilize valores “fixos” no código sem suas devidas referências, por exemplo, procure criar constantes ou ainda enumeradores para utilizá-los, além de centralizar seus valores referenciais, você ainda poderá declarar melhor seu proposito através de seus nomes.