PortBanning: URL prohibida cuando tiene un puerto especial

25 marzo, 2014 Deja un comentario

Hoy tuve un problema bloqueante mientras tenía que hacer la prueba de una aplicación vía su URL interna. Cuando hablamos de una URL interna, nos referimos a aquella que la empresa que alberga el sitio utiliza para acceder en intranet. La URL externa es aquella que todo el mundo conoce. Por ejemplo http://jomaora-prod.miempresa.com:115 con respecto de http://www.miempresa.com.

portBanning

El problema que tuve se daba cuando accedía a la página. Tenía un mensaje que decía que la URL era prohibida. Probaba la externa y no había problema, pero imposible con la interna. La razón era que el puerto que de la URL interna. En mi caso era el puerto 115, normalmente usado para el sftp, pero por alguna bizarra razón se estaba usando aca para un servicio HTTP. (Seguramente un error de algun administrador de sistemas)

Leyendo, encontré que esos puertos son bloqueados por los navigadores, por la cual la URL es prohibida. Para solucionar el problema, hay que modificar la configuración por defecto del navigador.

En el caso de Firefox hay este link http://www-archive.mozilla.org/projects/netlib/PortBanning.html

Entonces lo que hice fue buscar dónde estaba instalado forefox en mi máquina.


joan@jomaora:~$ ll /usr/bin/firefox
lrwxrwxrwx 1 root root 25 mars 18 01:24 /usr/bin/firefox -> ../lib/firefox/firefox.sh*

Fui a ese directorio


joan@jomaora:~$ cd /usr/lib/firefox
joan@jomaora:firefox$ vi defaults/pref/
channel-prefs.js vendor-gre.js

Y modifiqué el archivo vendor-gre.js agregando al final


pref("network.security.ports.banned.override", "115");

Reinicié el navigador. Y listo 🙂

En Window se puede hacer lo mismo, simplement hay que ir a la carpeta ProgramFiles, buscar Mozilla Firefox y encontrar uno de los archivos js de la configuracion para agregar el valor.

Modificar path del déposito maven: -Dmaven.repo.local

16 diciembre, 2013 Deja un comentario

Cuando trabajamos con Maven, utilizamos algo que se llaman repositories o depósitos. Estos depósitos contienen los artifactos que un proyecto necesita para compilar y ejecutarse. Ellos corresponden a los jar de las dependencias del proyecto que definimos en el archivo pom.xml, del cual se hablo un poco aquí. Para mas información sobre lo qué es un depósito, ver acá.

El objetivo de estos depósitos es que cuando compilamos un proyecto, podamos recuperar los artifactos de nuestras dependecias y guardarlos en nuestra máquina de manera a reutilizarlos sin necesidad de descargarlos desde un depósito remoto como un Nexus en Jenkins. De esta manera, recuperamos artifactos de librerias comunes entre proyectos como commmons.io, commons.collections, etc. Esas dependecias son especificadas en el pom.xml del proyecto. Consideremos el siguiente ejemplo:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
_________xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
____<modelVersion>4.0.0</modelVersion>
____<groupId>com.jomaora.app</groupId>
____<artifactId>testMockito</artifactId>
____<packaging>jar</packaging>
____<version>1.5-SNAPSHOT</version>
____<name>testMockito</name>
____<build>
________<plugins>
____________<plugin>
________________<groupId>org.apache.maven.plugins</groupId>
________________<artifactId>maven-compiler-plugin</artifactId>
________________<version>2.3.2</version>
________________<configuration>
____________________<source>1.6</source>
____________________<target>1.6</target>
________________</configuration>
____________</plugin>
________</plugins>
____</build>
____<dependencies>
________<dependency>
____________<groupId>com.jomaora.app</groupId>
____________<artifactId>myproject</artifactId>
____________<version>${project.version}</version>
________</dependency>
________<dependency>
____________<groupId>com.google.guava</groupId>
____________<artifactId>guava</artifactId>
____________<version>${guava.version}</version>
________</dependency>
________<dependency>
____________<groupId>org.mockito</groupId>
____________<artifactId>mockito-core</artifactId>
____________<version>${mockito.version}</version>
________</dependency>
____</dependencies>
____<properties>
________<mockito.version>1.9.0</mockito.version>
________<guava.version>11.0.1</guava.version>
____</properties>
</project>

Cuando compilamos el proyecto (mvn clean install), las dependencias se alojan por defecto en el directorio oculto m2 de la HOME del usuario. Es fácil ubicarlas si uno lee el pom.xml. En el caso de mockito, el pom indica el groupId y el artifact que nos sirven para el path hacia el archivo, asi como la versión en la 1.9.0.

reposiroty

Ahora bien. Supongamos que tenemos dos equipos estan trabajando en evoluciones importantes sobre myproject. El equipo A trabaja en la rama (branch) dev-1.5 y el equipo B trabaja en la rama dev-1.5-big-improuvement. El equipo A tiene una fecha de entrega prevista antes que el equipo B, y tanto el equipo A como el equipo B trabajan sobre la misma máquina para hacer sus pruebas (he aquí el detalle importante del asunto).

El problema que esto presenta es que cada vez que myprojet será compilado por un equipo, el artifacto generado va a reemplazar al del otro equipo. Ejemplo:

  1. El equipo B compila el proyecto desde su rama (dev-1.5-big-impouvement) con mvn clean install, el jar de myproject se actualiza en el depósito. Luego el equipo B empaqueta la aplicación que utiliza myproject (mvn clean package) y entonces el artifacto se recupera desde el depósito.
  2. El equipo A compila el proyecto desde su branch (dev-1.5), y el jar de my project se actualiza en el depósito, reemplazando el generado por el equipo B. Problema, este nuevo artifacto no contiene los commits de la branch (dev-1.5-big-impouvement).
  3. Sin saberlo, el equipo B repite el empaquetado de la aplicación. Como el artifacto de myproject no es re compilado, la versión generada por el equipo A es recuperada y la aplicación no tendrá las modificaciones del equipo B.

Capture du 2013-11-22 18:00:00

Para evitar este problema, lo mejor es utilizar un depósito diferente para cada equipo, hasta que todas las ramas sean fusionadas (merge) en la rama a entregar. Para ello, el comando mvn de maven tiene un parámetro que permite indicar el directorio que nos servirá de depósito temporal: -Dmaven.repo.local. Ejemplo:

mvn clean install -Dmaven.repo.local=/usr/local/web/.m2/repository-equipoB 

Mock para HttpServletResponse: Test unitario para un StreamResolution

18 octubre, 2013 Deja un comentario

Stripes es un framework del que no he hablado en mis publicaciones, pero con el que trabajo todos los días. Para no entrar en detalles, Stripes es un framework utilisable en la capa de presentación que puede interfasarse fácilmente con una capa Spring de Lógica de negocio.  Uno de los principios de Stripes es que una interfaz de usuario está conectada con un ActionBean, clase que asocia cada campo de un formulario con sus atributos. Los métodos de un ActionBean pueden conectarse a los eventos del formulario y se les identifica por tener la anotación @DefaultEvent o @HandleEvent. Normalmente, estos métodos retornan un objeto de tipo Resolution, que, dando una definición ordinaria, permite la redirección de la página después del tratamiento.

Hay diferentes implementaciones de Resolution, pero la que hoy me interesa presentarles es StreamResolution. Este tipo de Resolution tiene como objetivo enviar datos al cliente más que reridigir a otra página. Uno de sus usos entonces es para presentar información en formato XML o JSON como si se tratara de un WebService. El otro día tuve que trabajar con método que efectuaba precisamente este trabajo, pero lo que me interesaba mas que la salida del flujo XML en la pantalla, era la creación de un test unitario para poder probar el código. Consideremos el siguiente método dentro de un ActionBean:

@DefaultEvent
public Resolution getResults() {
___final ResultDTO resultDTO = new ResultDTO();
___LinkedList<BookDTO> books = catalogueService.find(keyword);
___resultDTO.setBooks(books);
___XStream xStream = new XStream();
___return new StreamingResolution("text/xml", new StringReader(xStream.toXML(resultDTO)));
}

Podemos suponer que para llamar a este método pudimos haber pasado por una URL ligada al ActionBean y que el parametro keyword viene en el request. Con este valor recuperamos una lista de BookDTO que vamos luego a serializar en formato XML gracias a un objeto de la classe com.thoughtworks.xstream.XStream. Supogamos que éste tiene la siguiente estructura:

<ResultDTO>
___<books class="linked-list">
______<BookDTO>
_________<title>Maus</title>
_________<author>Art. Spiegelman</author>
______</BookDTO>
______<BookDTO>
_________<title>La Reina del Sur</title>
_________<author>Arturo Peréz Reverte</author>
______</BookDTO>
___</books>
</ResultDTO>

Ahora, lo que nos interesa es, a partir de la salida que hemos supuesto, testear el código del método. En el test unitario, además de llamar el método, debemos evaluar los valores dentro del objeto Resolution.

En debug es fácil acceder a resolution.contentType o al resolution.reader que contiene el flujo en xml. Sin embargo, esto no es posible en el test ya que estos atributos son privados. En tiempo de ejecución normal, es el objeto response que contiene también el flujo à mostrar. En este caso, podemos pasar por este objeto para recuperar esta informacion. Solo que estamos en un contexto de test Unitario, y no hay acceso a las implementaciones estandar de  es HttpServletResponse.

Para contornar este problema, existe una clase del API Spring nos permite mockear HttpServletResponse : MockHttpServletResponse. Para poder llenar las informaciones en el objeto response, debemos ademas de llamar el metodo del actionBean, invocar el método execute de la resolution, pasando precisamente como parametro el objeto response. Teniendo esto, podemos luego recuperar el ContentType y la sálida de texto. Con esto nuestro test sera:

@Test
public void verifiy_xml_conversion() throws Exception {
___when( catalogueService.find(( anyString() ) ).thenReturn(results);
___HttpServletRequest request = new MockHttpServletRequest();
___HttpServletResponse response = new MockHttpServletResponse();

___StreamingResolution resolution = (StreamingResolution) actionBean.getResults();
___resolution.execute(request, response);

___Assert.assertEquals(response.getContentType(), "text/xml");
___Assert.assertEquals( ((MockHttpServletResponse) response).getOutputString(), xmlOutPut);
}

donde xmlOutPut es un objeto String que contiene la sálida del XML que se mostró más arriba.

Identificar constraints que impiden delete en SQL. ORA-02292

9 octubre, 2013 1 comentario

Es muy común que cuando queremos hacer supresiones en una tabla de una base de datos nos veamos enfrentados con las constraint de la misma. Normalmente si la base de Datos ha sido creada con cuidado, estas constraints permiten evitar que la supresión de datos generen inconsistencias. En ese caso, ver mensajes que nos impiden suprimir los datos así como así es algo positivo.

delete from books where authorId = '9e51a7f758204f538d556049156f8f7b'

Error starting at line 1 in command:
delete from books where authorId = '9e51a7f758204f538d556049156f8f7b'
Error report:
SQL Error: ORA-02292: integrity constraint (MY_LIBRARY_SCHEMA.FK27B99837E9840F67) violated - child record found
02292. 00000 - "integrity constraint (%s.%s) violated - child record found"
*Cause: attempted to delete a parent key value that had a foreign
dependency.
*Action: delete dependencies first then parent or disable constraint.

Sin embargo, a veces estamos seguros que tenemos que eliminar ciertos datos y no necesariamente conocemos las dependencias entre las otras tablas de la base de datos y la tabla donde queremos eliminar datos. Si al momento de crear la tabla, la referencia no se hizo con ON DELETE CASCADE, la supresión no va a ser automática. Tenemos entonces que hacer un poco de retroingeniería para encontrar el order correcto de supresión. Para eso, el comando que sigue es muy práctico. Este permite encontrar el nombre de la tabla que nos impide suprimir. Para ejecutarla tenemos que estar conectados en modo administrador.

select owner, table_name from all_constraints where constraint_name = 'FK27B99837E9840F67'


OWNER                          TABLE_NAME
-----------------------------  ------------------------------
CMS4                          NODEVERSIONPUBLICATIONMETHOD


1 rows selected

Teniendo el nombre de la tabla, podemos ir a ella y ver cual es la columna que las une. Si solo hay esa constraint en la tabla, entonces suprimir en la tabla hija, bastará para poder ejecutar el delete inicial. Sino, debemos retener la constraint y seguir buscando las otras que lo impiden.

Categorías: Base de Datos Etiquetas:

Instalar jdk de Oracle en Ubuntu

8 octubre, 2013 Deja un comentario

He recibido una nueva máquina para desarrollar en el trabajo. Como cada vez que me entregan una nueva, ésta viene en Windows. Lo primero que hago es formatearla e instalar Ubuntu, esta vez, version 13.04. Luego me pongo en la tarea de instalar todos los programas, pero siempre tengo problemas para instalar el jdk. Como no quiero utilizar el openjdk que es propuesto por Ubuntu, acá mi TODO list para la próxima vez que lo quiera instalar.

  • Descargar del sitio de Oracle la versión del jdk que deseemos. En mi caso, la última versión de JDK 6 : jdk-6u45-linux-x64.bin. Es posible que sea necesario crear une cuenta Oracle para poder descargar el archivo.
  • El siguiente paso es copiar el archivo .bin en /usr/local/lib y ejecutarlo.

joan@jomaora:~$ sudo cp ~/Téléchargements/jdk-6u45-linux-x64.bin /usr/local/lib/
[sudo] password for joan:
joan@jomaora:~$ cd /usr/local/lib/

joan@jomaora:/usr/local/lib$ ./jdk-6u45-linux-x64.bin

  • Después de la ejecución, una carpeta con el jdk es creada:

joan@jomaora:/usr/local/lib$ ls
jdk1.6.0_45 jdk-6u45-linux-x64.bin python2.7 python3.3

  • Luego hay que definir las variables de entorno en el .bashrc.

export JAVA_HOME=/usr/local/lib/jdk1.6.0_45
export PATH=$PATH:$JAVA_HOME/bin

  • Con esto, desde el terminal se puede lanzar el comando java y javac y confirmar que java está correctamente instalado.

joan@jomaora:~$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)

joan@jomaora:~$ javac -version
javac 1.6.0_45

Categorías: Comandos Linux, Java Etiquetas: , ,
Savoirs d’Histoire

« Il faut savoir s'instruire dans la gaieté. Le savoir triste est un savoir mort. » (Voltaire)

Hype Driven Development

coz' geeks love new stuff !

My experiments with SCRUM

Site to discuss Agile (Scrum, XP, etc) concepts and ideas.

CommitStrip

Mi propia cheatsheet...

Chris Aniszczyk's (zx) diatribe

work. life. open source. diatribes.

GermanTrevi

repositorio de mi mente...