terça-feira, 11 de maio de 2021

Erro ao Criar Runner Gitlab no Docker Toolbox - Error response from daemon: invalid mode: \MinGW\msys\1.0\etc\gitlab-runner.

      Nesse post eu mostro como resolver um problema de criar um Runner do Gitlab para quem usa o Docker Toolbox. Sabe o que é o Docker Toolbox? Um projeto (que até foi descontinuado, porém eu uso devido a problemas que tive com o Docker rodando direto na minha máquia e outras coisas que uso) que instala as ferramentas Docker (Docker Engine, Docker Machine, etc)  dentro de uma "caixa" que abstrai as características da sua máquina e roda o Docker independentemente delas. Como tudo no mundo, isso tem vantagens e desvantagens. Como o Docker Toolbox roda dentro dessa "caixa" algumas coisas funcionam um pouco diferentes. Os volumes são uma delas.

     Após baixar a imagem do Runner com o comando:


$ docker pull gitlab/gitlab-runner:latest


     Quando vamos executar o comando que sobe  o Runner criando os volumes:


$   docker run -d --name gitlab-runner --restart always -v /Users/Shared/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest


     Recebemos o seguinte erro:


c:\Program Files\Docker Toolbox\docker.exe: Error response from daemon: invalid mode: \MinGW\msys\1.0\etc\gitlab-runner. 

See 'c:\Program Files\Docker Toolbox\docker.exe run --help'.


     E procurando a solução, encontrei e foi bem simples, basta adicionar uma barra "/" a mais no início dos caminhos do volume, ficando assim:


$ docker run -d --name gitlab-runner --restart always -v //Users/Shared/gitlab-runner/config://etc/gitlab-runner -v //var/run/docker.sock://var/run/docker.sock gitlab/gitlab-runner:latest 


     Pronto. Agora funciona tranquilo.


https://stackoverflow.com/questions/50540721/docker-toolbox-error-response-from-daemon-invalid-mode-root-docker

sexta-feira, 7 de maio de 2021

Exemplo de teste com JUnit e Mockito

       Nesse post eu trago um exemplo de testes usando Mockito para simular o comportamento de uma classe DAO, substituindo seu acesso ao banco por dados criados específicamente para os testes, de maneira que possamos testar apenas o comportamento desejado e não a integração com banco de dados, etc. Esse exemplo é do curso que fiz da Alura sobre testes com Mockito.


/**

 * Resumo:

 * 1 - Cria as propriedades SERVICE(s) e DAO(s)

 * 2 - No metodo inicializar:

 *      1 - mocka o(s) DAO(s)

 *      2 - inicia o(s) SERVICE(s) com os respectivos DAO(s) mockados

 * 3 - Cria os métodos de teste

 */

class FinalizarLeilaoServiceTest {

 

    private FinalizarLeilaoService finalizarLeilaoService;

 

    private LeilaoDao leilaoDao;

 

    @BeforeEach

    void inicializar() {

        // inicializa o mock e passa pro service

        leilaoDao = Mockito.mock( LeilaoDao.class );

        finalizarLeilaoService = new FinalizarLeilaoService( leilaoDao );

    }

 

    @Test

    void deveriaFinalizarLeilao() {

        List<Leilao> leiloes = leiloes();

 

        // defino o retorno de metodos do DAO mockado

        Mockito.when( leilaoDao.buscarLeiloesExpirados() ).thenReturn( leiloes );

 

        // metodo testado

        finalizarLeilaoService.finalizarLeiloesExpirados();

 

        // resultados esperados

        Leilao leilao = leiloes.get( 0 );

        Assert.assertTrue( leilao.isFechado() );

        Assert.assertEquals( new BigDecimal( "900" ), leilao.getLanceVencedor().getValor() );

        // Testa se determinado método do DAO foi chamado

        Mockito.verify( leilaoDao ).salvar( leilao );

    }

 

    //método com dados hardcode para teste

    private List<Leilao> leiloes() {

        List<Leilao> leiloes = new ArrayList<>();

 

        Leilao leilao = new Leilao( "Celular", new BigDecimal( "500" ), new Usuario( "Alguém" ) );

 

        Lance primeiro = new Lance( new Usuario( "Outro Alguém" ), new BigDecimal( "600" ) );

        Lance segundo = new Lance( new Usuario( "Mais Alguém" ), new BigDecimal( "900" ) );

        Lance terceiro = new Lance( new Usuario( "Um Alguém" ), new BigDecimal( "500" ) );

 

        leilao.propoe( primeiro );

        leilao.propoe( segundo );

        leilao.propoe( terceiro );

        leiloes.add( leilao );

        return leiloes;

    }

}



terça-feira, 20 de abril de 2021

Exemplo de função SQL para atualizar vários registros com uma sequence

       Nesse artigo trago um exemplo de uma função para atualização de vários registros com dados de uma sequence. Caso não seja criada uma função o que acontece é que apesar de chamar-mos a sequence, todos os os registros receberiam o mesmo valor. Por isso se faz necessário o uso de uma função.


CREATE OR REPLACE FUNCTION cria_num_boletim_pacientes_em_atendimento()

 RETURNS void

 LANGUAGE plpgsql

AS $function$

declare

internacao record;

        begin

for internacao in

(select il.id_internacao from t_internacao_leito il

inner join t_internacao it on il.id_internacao = it.id_internacao

where it.id_tipo_atendimento = 2 and il.data_alta is null

group by il.id_internacao)

loop

update t_internacao set num_boletim = (select nextval('s_numero_boletim'))  where id_internacao = internacao.id_internacao;

end loop;

         end;

$function$;

sexta-feira, 16 de abril de 2021

Usando JUnit para testar acesso a webservice

 Essa postagem traz um código simples de testes para um acesso a webservice:


import javax.ws.rs.client.Client;

import javax.ws.rs.client.ClientBuilder;

import javax.ws.rs.client.WebTarget;


import org.junit.Assert;

import org.junit.Test;


public class teste {


    @Test

    public void testaQueAConexaoComOServidorFunciona() {

        Client client = ClientBuilder.newClient();

        WebTarget target = client.target( "http://www.mocky.io" );

        String conteudo = target.path( "/v2/52aaf5deee7ba8c70329fb7d" ).request().get( String.class );

        System.out.println( conteudo );

        Assert.assertTrue( conteudo.contains( "Rua Vergueiro 3185" ) );

    }

}

sábado, 6 de março de 2021

Mudando Domínio no Wordpress

       Nesse post eu vou deixar os comandos para substituir Domínios no WordPress.


UPDATE wp_options SET option_value = replace(option_value, 'Existing URL', 'New URL') WHERE option_name = 'home' OR option_name = 'siteurl';

UPDATE wp_posts SET post_content = replace(post_content, 'Existing URL', 'New URL');

UPDATE wp_postmeta SET meta_value = replace(meta_value,'Existing URL','New URL');

UPDATE wp_usermeta SET meta_value = replace(meta_value, 'Existing URL','New URL');

UPDATE wp_links SET link_url = replace(link_url, 'Existing URL','New URL');

UPDATE wp_comments SET comment_content = replace(comment_content , 'Existing URL','New URL');


     Fonte:

     https://betterstudio.com/blog/search-and-replace-phpmyadmin/

sexta-feira, 11 de dezembro de 2020

Lendo conteúdo de uma URL no Java

       Nesse artigo vou mostrar como ler um conteúdo de uma URL via Java. Isso é útil para ler um XML ou JSON disponibilizado por um site um sistema externo por exemplo.


public void lerConteudoURL() {
       
        String noticia;
        try {
            URL url = new URL("endereço_web");

            HttpURLConnection.setFollowRedirects(true);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(3000);
            connection.setRequestProperty("Accept-Charset", "text/xml; charset=UTF-8");
            int codeMessage = connection.getResponseCode();


            if(HttpURLConnection.HTTP_OK == codeMessage) {
                InputStream buffer = new BufferedInputStream(connection.getInputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(buffer, "UTF-8"));
                String line = reader.readLine();
               
                while (line !=null) {
                   
                    //conteúdo da linha
                    System.out.println(line);
                   
                    //pega a próxima linha
                    line = reader.readLine();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

}

segunda-feira, 30 de novembro de 2020

Acessando Tabela Externa dentro do seu Banco de Dados

As vezes precisamos fazer a leitura de dados de um banco que não é o da nossa aplicação, seja um acesso permanente como uma integração ou uma leitura pontual para importação de dados, e é isso que vou mostrar aqui. Esse acesso pode ser feito inclusive para Bancos de Dados diferentes. 

 

Os passos são os seguintes: 

 

  1. 1 - Instalar uma extensão usando CREATE EXTENSION. 

  1. 2 - Criar um servidor externo, usando CREATE SERVER, para representar cada banco de dados remoto ao qual deseja se conectar. 

  1. 3 - Criar um mapeamento de usuário, usando CREATE USER MAPPING, para cada usuário do banco de dados que você deseja permitir o acesso para cada servidor externo. 

  1. 4 - Criar as tabelas externas, usando CREATE FOREIGN TABLE  

 

Para acessar outros bancos dentro do nosso, é preciso de plugins para isso. Os plugins já estão no Postgre e precisam ser “ativados”. Neste exemplo vou mostrar um banco PostgreSQL acessar outro banco PostgreSQL. 

 

Os comandos abaixo exibem os plugins (extensões) disponíveis (o segundo traz um breve comentário sobre o plugin): 

 

SELECT * FROM pg_available_extensions; 

Ou 

SELECT * FROM pg_available_extension_versions 

 

O plugin que vamos usar é o postgres_fdw. Esse comando a seguir vai ativar o plugin e deixá-lo disponível para uso: 

 

CREATE EXTENSION postgres_fdw 

    SCHEMA "public" 

    VERSION "1.0"; 

 

Como essa extensão trata de acesso a um banco de dados, precisamos de um passo a mais que é o de criar o wrapper que vai ficar fazendo a tradução da linguagem de um banco para o outro. 

 

CREATE FOREIGN DATA WRAPPER postgres_fdw 

    HANDLER postgres_fdw_handler 

    VALIDATOR postgres_fdw_validator 

    OPTIONS (); 

 

Caso o wrapper já tenha sido criado, precisamos ver se o handler e o validator foram especificados, caso não, precisamos atualizar. 

 

ALTER FOREIGN DATA WRAPPER postgres_fdw 

    HANDLER public.postgres_fdw_handler 

    VALIDATOR public.postgres_fdw_validator; 

 

Para criar o servidor, vamos precisar do nome do banco, endereço e porta. Para o servidor vamos fazer: 

 

CREATE SERVER nome_servidor 

    FOREIGN DATA WRAPPER postgres_fdw 

  OPTIONS (dbname 'nome_banco', host 'ip_banco', port 'porta'); 

 

Para o(s) usuário(s) 

 

CREATE USER MAPPING 

    FOR postgres 

    SERVER nome_servidor 

    OPTIONS (password 'senha', user 'usuario'); 

 

Agora basta criar as tabelas. Aconselho criar um schema separado para suas tabelas de servidores externos para não misturar com as tabelas internas. Se o usuário tiver permissão de escrita, os comandos de UPDATE, INSERT, e DELETE vão funcionar normalmente. 

 

CREATE FOREIGN TABLE seu_schema.sua_tabela ( 

    id bigserial, 

    nome varchar(70) NOT NULL, 

    dt_nascimento date 

) 

SERVER nome_servidor 

OPTIONS (schema_name 'nome_schema_externo', table_name 'nome_tabela_externa'); 

 

Pode ser necessário dar permissão de acesso no banco externo caso ele esteja restringindo por IP o acesso. Você verá o erro: no pg_hba.conf entry for host "ip_seu_banco", user "usuario_que vc definiu", database "nome_banco_que_quer_acessar". 

 

Pronto, basta usar as tabelas como se estivessem localmente. 

 

Links: