martes, 2 de julio de 2019

Cómo agregar espacio a vmdk de VirtualBox en Mac OS

Cómo agregar espacio a máquina virtual Linux en VirtualBox desde Mac


Hola.

Estuve trabajando en una instalación de software con mi máquina virtual Linux en VirtualBox desde mi Mac.

Me encontré con un error de espacio insuficiente al intentar hacer mi instalación: insufficient disk space available for selected location.

Al checar el espacio obtengo un 98% de espacio usado de 29G en /dev/mapper/vg_edqtrn-lv_root

[oracle@edqtrn ~]$ df -H
Filesystem                                        Size  Used Avail Use% Mounted on
/dev/mapper/vg_edqtrn-lv_root   29G   27G  656M  98% /                    
tmpfs                                                2.1G  748M  1.4G  37% /dev/shm
/dev/sda1                                          500M  211M  259M  45% /boot
/dev/sdb1                                          107G   18G   84G  18% /apps
Downloads                                       501G  389G  112G  78% /media/sf_Downloads
share                                                 501G  389G  112G  78% /media/sf_share

Buscando un poco me di cuenta que no hay manera de agregar espacio a la máquina virtual desde VirtualBox de manera fácil. Estaba buscando algo como sólo aumentar el número de GB desde VirtualBox y encender la máquina pero el proceso es un poco más complicado.

Les pongo aquí los pasos que utilice para agregar más espacio a la maquina virtual desde Mac.


Si no está apagada su maquina virtual, apáguenla primero.

1. Abrir una terminal de Mac e ir a la ubicación donde se encuentra los archivos de la máquina virtual y ejecutar los siguientes comandos:

#lo pasamos a formato vdi
VBoxManage clonehd "midisco.vmdk" "nuevo-midisco.vdi" --format vdi 
#redimensionamos el espacio a 60GB
VBoxManage modifyhd "nuevo-midisco.vdi" --resize 60000
#regresamos a formato vmdk
VBoxManage clonehd "nuevo-midisco.vdi" "resized-midisco.vmdk" --format vmdk

2. Desde VirtualBox remuevan el disco que clonaron "midisco.vmdk" y agreguen el nuevo redimensionado "resized-midisco.vmdk"

VirtuaBox-Settings-Storage-Controller-SATA

Para poder usar el nuevo espacio, se debe extender el espacio usando gparted.

3. Descarguen GParted de aquí http://gparted.org/download.php 

4. Agregar un disco (Add optical drive) apuntando al archivo iso descargado en: VirtualBox > Settings > Storage > Controller IDE.

VirtuaBox-Settings-Storage-Controller-IDE-Controller

5. Iniciar la máquina virtual y aceptar las opciones default hasta llegar a la pantalla principal de GParted. Ahí deben extender con el mouse para ocupar todo el espacio unallocated del disco. Chequen las imágenes de abajo.


GParted-Unallocated


GParted-Allocated

Click en la palomita verde de arriba para aplicar los cambios y reinicien la máquina.

Hasta aquí el espacio ya está disponible para usar dentro de la maquina virtual pero aun falta algo!

6. Ejecutar la siguiente instrucción lvextend para extender el espacio en el file system especificado.

[oracle@edqtrn ~]$ sudo lvextend --size +20G --resizefs /dev/mapper/vg_edqtrn/lv_root
Size of logical volume vg_edqtrn/lv_root changed from 36.98 GiB (9468 extents) to 46.98 GiB (12028 extents).
Logical volume lv_root successfully resized.
resize2fs 1.43-WIP (20-Jun-2013)
Filesystem at /dev/mapper/vg_edqtrn-lv_root is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 3
The filesystem on /dev/mapper/vg_edqtrn-lv_root is now 12316672 blocks long.

Validando el espacio disponible con df -H ya veo el nuevo espacio disponible. Tenía 30, le agregué 20 y me quedan 10 disponibles que no asigno por el momento.

[oracle@edqtrn ~]$ df -H
Filesystem                                       Size  Used Avail Use% Mounted on
/dev/mapper/vg_edqtrn-lv_root   50G   27G   21G  56% /
tmpfs                                               2.1G  748M  1.4G  37% /dev/shm
/dev/sda1                                         500M  211M  259M  45% /boot
/dev/sdb1                                         107G   18G   84G  18% /apps
Downloads                                      501G  389G  112G  78% /media/sf_Downloads
share                                                501G  389G  112G  78% /media/sf_share


Después de todo este show, ya me fue posible realizar la instalación del software en la máquina virtual.

Hubiera preferido algún método más sencillo que no me quitara todo el día pero esto fue lo mejor que encontré.


Espero les sirva.





Cómo ordenar aleatorio un query en Oracle

Cómo ordenar aleatorio un query en Oracle


Hola.

Requiero hacer un listado de base de datos Oracle que muestre los elementos con un orden aleatorio o random.

Un poco extraño el requerimiento pero se necesita que los registros no tengan orden debido a cuestiones comerciales de no dar preferencia a ningún resultado de la consulta.

Así que investigando cómo ordenar aleatorio me encontré con la instrucción dbms_random.value
Estoy usando Oracle 11g y la instrucción funciona a la perfección trayendo resultados random cada vez que lo ejecuto.

Solución.

Así deben hacer el ORDER BY:

SELECT campo, campo2 FROM MiTabla ORDER BY dbms_random.value;

Con esto ya tienen el ordenamiento aleatorio.


Espero les sirva.










jueves, 27 de junio de 2019

Cómo ofuscar atributos de un XML con namespace usando XSLT

Cómo ofuscar atributos de un XML con namespace usando XSLT


Hola.

Estoy intentando ocultar los valores de algunos atributos XML usando XSLT.

Para quien no ha usado este método, es muy útil para cuando necesitas ocultar cierta información sensitiva en tus aplicaciones. Generalmente en los logs que generan las aplicaciones. Estos datos pueden ser datos personales como: nombre, teléfono, email, tarjeta de crédito, etc.

El problema que tengo es que los elementos que quiero ofuscar tienen como prefijo un namespace. No tuve ningún problema para ofuscar cuando los elementos no tienen namespace.

Después de investigar un poco, la solución pareciera bastante obvia. Se tiene que definir el mismo namespace que usa el XML en el archivo XSLT.

En mi caso el namespace es xmlns:ns1="http://www.sample.com/CustomerOrder/2.0"

Abajo les dejo mi XML y mi XSLT

Mi XML se ve así:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Envelope xmlns:ns0="http://www.sample.com/icc/wrapper/1.0">
    <ns0:Header>       
    </ns0:Header>
    <ns0:Body>
        <Payload>
            <ns1:CustomerOrder xmlns:ns1="http://www.sample.com/CustomerOrder/2.0">
                <ns1:CustomerOrderAddresses>
                    <ns1:CustomerOrderAddress AddressLine1="aaaaaaaaaa" City="dddddd" Country="eee" EmailAddress="nada@nada.com" FirstName="nombre" LastName="apellido" />
                     </ns1:CustomerOrderAddresses>
            </ns1:CustomerOrder>
        </Payload>
    </ns0:Body>
</ns0:Envelope>


Como pueden ver abajo en negritas, mi XSLT tiene definido el namespace ns1 que está definido en el XML de arriba también en negritas.

En mi elemento template defino el parent de los atributos usando como prefijo el namespace parent::ns1:CustomerOrderAddress

Mi XSLT se ve así.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="http://www.sample.com/CustomerOrder/2.0">

<xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
</xsl:template>

<xsl:template match="@AddressLine1[parent::ns1:CustomerOrderAddress]">
<xsl:attribute name="AddressLine1">
<xsl:if test="string-length(.)>'0'">
<xsl:value-of select="concat(substring(., 1 ,string-length(.)-16),'XXXXXXXXXXXXXXXX')"/>
</xsl:if>
<xsl:if test="string-length(.)&lt;'1' "></xsl:if>
</xsl:attribute>
</xsl:template>
<xsl:template match="@EmailAddress[parent::ns1:CustomerOrderAddress]">
<xsl:attribute name="EmailAddress">
<xsl:if test="string-length(.)>'0'">
<xsl:value-of select="concat(substring(., 1 ,string-length(.)-16),'XXXXXXXXXXXXXXXX')"/>
</xsl:if>
<xsl:if test="string-length(.)&lt;'1' "></xsl:if>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>


El resultado se ve así:


<ns0:Envelope xmlns:ns0="http://www.sample.com/icc/wrapper/1.0">
    <ns0:Header>       
    </ns0:Header>
    <ns0:Body>
        <Payload>
            <ns1:CustomerOrder xmlns:ns1="http://www.sample.com/CustomerOrder/2.0">
                <ns1:CustomerOrderAddresses>
                    <ns1:CustomerOrderAddress AddressLine1="XXXXXXXXXXXXXXXX"
                                         City="dddddd"
                                         Country="eee"
                                         EmailAddress="XXXXXXXXXXXXXXXX"
                                         FirstName="nombre"
                                         LastName="apellido"/>
                     </ns1:CustomerOrderAddresses>
            </ns1:CustomerOrder>
        </Payload>
    </ns0:Body>
</ns0:Envelope>


Pueden probar esto en la siguiente página: https://www.freeformatter.com/xsl-transformer.html



Espero les sirva.








lunes, 24 de junio de 2019

TIBCO EMS Cómo saber el host de los consumers de una queue

TIBCO EMS Cómo saber el host de los consumers de una queue


Hola.

Por increíble que parezca, el consumidor de una queue  me acaba de pedir que si puedo eliminar los consumers de una queue porque no sabe en dónde está su aplicación!

Bueno estas cosas pasan y como siempre es bueno saber quién es el consumidor de una queue en particular.

Investigué un poco y di con este método fácil.

Lo que hago es primero listar los consumers de la queue para ver las conexiones de cada consumer. Con esto obtengo el id de todas las conexiones.

show consumers queue=miqueue

El resultado será algo así

tcp://server:7222> show consumers queue=miqueue
                                                           Msgs Sent
       Id      Conn User     T Queue                   SASB Sent Size   Uptime
251172286 121196809 miusuario Q miqueue +T--    0    0 1298:14:13
251172288 121196809 miusuario Q miqueue +T--    0    0 1298:14:13
251172290 121196809 miusuario Q miqueue +T--    0    0 1298:14:13

Con esta información obtienen el id de la conexión y el nombre del usuario EMS que se usa para crear el consumidor.

Ahora ejecutamos la instrucción para ver todas las conexiones de ese usuario

show connections user=miusuario

El resultado se verá así

tcp://server:7222> show connections user=miusuario
L  ID        FSXT  S  Host                     User     ClientID                  Sess     Uptime Processor
J  119448740 +--Q  +  hostname1                miusuario                              8 1130:16:58         8
J  121196809 +--Q  +  hostname2                miusuario                              3 1130:16:58         6

Con esta información se puede determinar que los consumers se conectan desde hostname2 relacionando ambos resultados a través de la conexión id. Osea hagan el join de las tablas de resultados con los campos conn y ID


Espero les sirva.






lunes, 3 de junio de 2019

TIBCO EMS ejemplos de comandos

Ejemplos de comandos de TIBCO EMS


Hola.

Si están aquí es porque, al igual que yo, en algún momento han necesitado conocer la sintaxis básica de alguna instrucción de TIBCO EMS. Ya sea para conectar, crear objetos, eliminarlos, asignar permisos, etc.

Les pongo aquí las instrucciones de TIBCO EMS que más he utilizado.

Cómo conectar a TIBCO EMS server


connect tcp://localhost:7222

Comandos de queues


Mostrar la lista de queues

show queues

Crear una queue

create queue miqueue

Detalles de una queue

show queue miqueue

Limpiar una queue

purge queue miqueue

Eliminar una queue

delete queue miqueue

Ver permisos de una queue

showacl queue miqueue

Limitar el número de mensajes en una queue

addprop queue miqueue maxMsgs=1000,overflowPolicy=discardOld

Comandos de topics


Mostrar la lista de topics

show topics

Crear un topic

create topic mitopic

Detalles de un topic

show topic mitopic

Eliminar un topic

delete topic mitopic

Ver permisos de un topic

showacl topic mitopic

Comandos de bridges


Crear bridge de topic a queue

create bridge source=topic:mitopic target=queue:miqueue

Crear bridge de topic a queue con selector

create bridge source=topic:mitopic target=queue:miqueue selector="Header1 IS NULL"

create bridge source=topic:mitopic target=queue:miqueue selector="Header1<>'CA'"

create bridge source=topic:mitopic target=queue:miqueue selector="Header1 NOT IN ('CA')"

Borrar bridge de topic a queue

delete bridge source=topic:mitopic target=queue:miqueue

Comandos de usuarios


Crear usuario

create user user_name ["user_description"] [password=password] 

Cambiar password de usuario

set password <user-name> [<password>]

Guardar cambios


Para guardar los cambios realizados correctamente

commit

Estas son las que más utilizo en el día a día. Si necesitan saber alguna otra menciónenlas en los comentarios.

Espero les sirva.




viernes, 31 de mayo de 2019

JavaScript Google Maps mostrar Markers con click

Como mostrar Markers en un mapa de Google Maps on click.


Hola.

Estoy colocando un mapa de Google en una sección de mi aplicación web. Estoy usando la API de Google Maps para mostrar todas las ubicaciones al usuario en un solo mapa.

La idea es crear un arreglo en javascript con todas las ubicaciones en latitud y longitud y crear markers para visualizarlos en el mapa de google.

Google Maps ofrece la oportunidad de crear Markers con JavaScript.

Mi arreglo se ve así y se encuentra en un archivo externo con extension js:

var marcadores = [[1,'Descripcion del marcador 1',-16.494213, -68.136466,2629],
[2,'Descripcion del marcador 2',-16.653139, -68.301835,3354],
[3,'Descripcion del marcador 3',-19.036393, -65.255528,2630],
[4,'Descripcion del marcador 4',-21.427691, -64.754212,2631]]

El orden del arreglo es [id, descripción, latitud, longitud, zindex]

La inclusion del mapa se ve así con un div con id definido para después asociarle un objeto Mapa de Google Maps con la función initMap :

<div id="map" class="mapa-ubicacion"></div>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=xxx&callback=initMap"></script>  

Lo siguiente es definir los marcadores y relacionarlos con el mapa con Javascript. También defino la función que mueve el mapa cuando se hace click. Esto lo hago de la siguiente manera.

<script>
        var markers = [];
        function initMap() {            
            var mapDiv = document.getElementById('map');
            var map = new google.maps.Map(mapDiv, {
                zoom: 16,
                center: { lat: -16.497789, lng: -68.125839 }
            });
            setMarkers(map);

            infoWindow = new google.maps.InfoWindow;

            // Try HTML5 geolocation.
            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(function (position) {
                    var pos = {
                        lat: position.coords.latitude,
                        lng: position.coords.longitude
                    };

                    infoWindow.setPosition(pos);
                    infoWindow.setContent('Lugar encontrado.');
                    infoWindow.open(map);
                    map.setCenter(pos);
                }, function () {
                    handleLocationError(true, infoWindow, map.getCenter());
                });
            } else {
                // Browser doesn't support Geolocation
                handleLocationError(false, infoWindow, map.getCenter());
            }

        }

        function handleLocationError(browserHasGeolocation, infoWindow, pos) {
            infoWindow.setPosition(pos);
            infoWindow.setContent(browserHasGeolocation ?
                              'Error: Ha ocurrido un error con el servicio de geolocalizacion.' :
                              'Error: El navegador no soporta el servicio de geolocalizacion.');
            infoWindow.open(map);
        }

        function setMarkers(map) {
            // Adds markers to the map.
           
            for (var i = 0; i < marcadores.length; i++) {
                var marcador = marcadores[i];                
                var marker = new google.maps.Marker({
                    position: { lat: marcador[2], lng: marcador[3] },
                    map: map,                                        
                    title: marcador[1],
                    zIndex: marcador[4],
                    id:marcador[0]
                });

                marker.addListener('click', function () {
                    
                    map.panTo(this.getPosition());
                    infoWindow.setContent(this.title);
                    infoWindow.open(map, this);
                    map.setZoom(20);                 
                });

                markers[marker.id] = marker;                               

            }//end for
        }

        function verMarcador(markerID) {
             google.maps.event.trigger(markers[markerID], 'click');             
        }

    </script>


De este código deben llamar a la última función verMarcador desde una liga externa al mapa. Esto generalmente es el listado de ligas de marcadores que viene de la base de datos y que comparte el mismo id que los marcadores. A fin de cuentas, el listado y el arreglo, deben estar relacionados por algún dato que generalmente es el ID.

Las ligas que llaman a la función verMarcador y generan el cambio en el mapa se ven así:

<a href="javascript:verMarcador(2);">Mi marcador 2</a>
<a href="javascript:verMarcador(3);">Mi marcador 3</a>

Con esto ya deben poder hacer click sobre la liga fuera del mapa y provocar que el mapa muestre la ubicación seleccionada.

Tomé la referencia de aquí:
https://stackoverflow.com/questions/49347441/javascript-google-maps-and-marker-referencing-with-id


Espero les sirva.

jueves, 30 de mayo de 2019

Rango de años con jQuery Datepicker

Como poner un rango de años en jQuery Datepicker.


Hola.

Estuve armando un formulario de captura que incluye un campo de fecha, en realidad estoy dividiendo el campo de fecha en tres combos para año, mes y día.

Como el formulario es para capturar la fecha de nacimiento del usuario, necesito establecer un rango en el combo de años permitidos para evitar datos no reales.

Estoy usando jQuery Datepicker y necesito establecer un rango para el combo de años permitidos.

En mi caso quiero mostrar desde 70 años atrás hasta el año actual.

Deben user la propiedad yearRange de jQuery Datepicker. Hay dos maneras comunes de hacerlo:

1.- Para especificar el rango de años constante.

yearRange: '1950:2020'

2.- Para especificar el rango de años relativo al año actual.

yearRange: '-70:+0'

Así es como queda mi campo cuando establezco el DatePicker al input.

$("#FECHANAC.datepicker").datepicker({dateFormat:'dd/mm/yy',changeMonth:true,changeYear:true,yearRange:'-70:+0'});


Espero les sirva.