26 June 2014

Eclipse Luna bug in Preferences for XML Editor

Bambitroll @ 09:59

If you are using the first release version of Eclipse 4.4 Luna, there is a bug in Windows->Preferences->XML->XML Files->Editor.

You can not change the settings for indentation size when using spaces. It is impossible to write a new number in the field and the -/+ buttons are disabled. The default value is 1! :(

The work around I found is to edit the following file in your workspace:
.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.xml.core.prefs

And add the following line (if you want 4 char for your indentation):
indentationSize=4


17 June 2014

ActiveMQ: memory management for queues

Bambitroll @ 11:05
With JMS persistent messages, all the message are persisted to the storage device by default, but also kept in memory. When a queue can potentially contain many messages, it is then necessary to set a max memory allowed, like this:
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="/var/activemq/data">
    <destinationPolicy>
        <policyMap>
            <policyEntries>
                <policyEntry queue=">" producerFlowControl="false" memoryLimit="100mb" queuePrefetch=”1” maxPageSize=”10” lazyDispatch=”true” />
            </policyEntries>
        </policyMap>
    </destinationPolicy>
</broker>

02 May 2014

Fuse and expressions in properties files

Bambitroll @ 11:23
The problem:
When using properties files in Fuse/ServiceMix (which you deploy in $FUSE_HOME/etc), you can define a camel endpoint like this
my.file.endpoint=file:/var/tmp/in?move=/var/tmp/sent/${date:now:yyyyMMdd}-${file:name}

This will work fine if you define it as a properties in your camel context XML file, like this:
<cm:property-placeholder persistent-id="my.properties">
    <cm:default-properties>
        <cm:property name="my.file.endpoint" value="file:/var/tmp/in?move=/var/tmp/sent/${date:now:yyyyMMdd}-${file:name}"/>
    </cm:default-properties>
</cm:property-placeholder>

But if you use the same definition in your properties file, because you want a more environment specific value for each of your servers, you are out of luck.
All you will achieve is having your files moved to a folder called "-" under sent.
This is because everything within a ${} is interpreted as a variable and will be resolved (unsuccessfully) before being passed along.


The solution:
Use the simple language!

my.file.endpoint=file:/var/tmp/in?move=/var/tmp/sent/$simple{date:now:yyyyMMdd}-$simple{file:name}

25 April 2014

Create fake TCP server to test a port is up and running

Bambitroll @ 16:41
There might be a way easier way to do this but here is how I solved it.

What I needed was to have a mock TCP server running on a given port on a given server to check that the firewall between my machine and the remote machine was properly open for a given port.
So I got a little  program running on the remote machine listening on the given port.
I also found a little client program, but using telnet works as well.

Under linux, just run "gcc server.c -o server_test" to compile the program and then run it with "server_test "
Also run "gcc client.c -o client_test" to compile and then run the client with "client_test "

Here is server.c:
/* A simple server in the internet domain using TCP
   The port number is passed as an argument */
#include 
#include 
#include 
#include 
#include  
#include 
#include 

void error(const char *msg)
{
    perror(msg);
    exit(1);
}

int main(int argc, char *argv[])
{
     int sockfd, newsockfd, portno;
     socklen_t clilen;
     char buffer[256];
     struct sockaddr_in serv_addr, cli_addr;
     int n;
     if (argc < 2) {
         fprintf(stderr,"ERROR, no port provided\n");
         exit(1);
     }
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if (sockfd < 0) 
        error("ERROR opening socket");
     bzero((char *) &serv_addr, sizeof(serv_addr));
     portno = atoi(argv[1]);
     serv_addr.sin_family = AF_INET;
     serv_addr.sin_addr.s_addr = INADDR_ANY;
     serv_addr.sin_port = htons(portno);
     if (bind(sockfd, (struct sockaddr *) &serv_addr,
              sizeof(serv_addr)) < 0) 
              error("ERROR on binding");
     listen(sockfd,5);
     clilen = sizeof(cli_addr);
     newsockfd = accept(sockfd, 
                 (struct sockaddr *) &cli_addr, 
                 &clilen);
     if (newsockfd < 0) 
          error("ERROR on accept");
     bzero(buffer,256);
     n = read(newsockfd,buffer,255);
     if (n < 0) error("ERROR reading from socket");
     printf("Here is the message: %s\n",buffer);
     n = write(newsockfd,"I got your message",18);
     if (n < 0) error("ERROR writing to socket");
     close(newsockfd);
     close(sockfd);
     return 0; 
}

Here is client.c:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include  

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr, 
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
        error("ERROR connecting");
    printf("Please enter the message: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0) 
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0) 
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    close(sockfd);
    return 0;
}



Sources: Linux Howtos: C/C++ -> Sockets Tutorial

09 April 2014

Adding/Removing queue to/from ActiveMQ via command line

Bambitroll @ 10:09

There is a way to add/remove queues on ActiveMQ from the command line.
It uses the REST interface of Jolokia which comes with Hawtio on ActiveMQ 5.9.0.

The first 2 commands contain all you need to create and then to remove the queue called q_titi, using the user admin/admin:
curl -u admin:admin -d "{\"type\":\"exec\",\"mbean\":\"org.apache.activemq:type=Broker,brokerName=localhost\",\"operation\":\"addQueue(java.lang.String)\",\"arguments\":[\"q_titi\"]}" http://localhost:8161/hawtio/jolokia/

curl -u admin:admin -d "{\"type\":\"exec\",\"mbean\":\"org.apache.activemq:type=Broker,brokerName=localhost\",\"operation\":\"removeQueue(java.lang.String)\",\"arguments\":[\"q_titi\"]}" http://localhost:8161/hawtio/jolokia/


The next 2 command do the same for the queue q_OMG but use the attached files for the necessary JSON request (so no more need to escape the double quotes and way more readable!):

curl -u admin:admin -d "@/tmp/jmr/createQ_json.txt" http://localhost:8161/hawtio/jolokia/
curl -u admin:admin -d "@/tmp/jmr/removeQ_json.txt" http://localhost:8161/hawtio/jolokia/

createQ_json.txt looks like this:
{
 "type":"exec",
 "mbean":"org.apache.activemq:type=Broker,brokerName=localhost",
 "operation":"addQueue(java.lang.String)",
 "arguments":["q_OMG"]
}


removeQ_json.txt looks like this:
{
 "type":"exec",
 "mbean":"org.apache.activemq:type=Broker,brokerName=localhost",
 "operation":"removeQueue(java.lang.String)",
 "arguments":["q_OMG"]
}


More info here:
Monitoring ActiveMQ via HTTP http://www.jakubkorab.net/2013/11/monitoring-activemq-via-http.html

03 February 2014

Properties files, blueprint and Fuse

Bambitroll @ 16:38
According to the specs for Fuse, if one uses blueprint, it is possible to create several files called *.xml under OSGI-INF/blueprint and they will all be used in the bundle.
This is true but I just found out that the alphabetical order of the file names can have its importance.
Indeed, I have a separate file for my properties (where my cm:property-placeholder is located) and I found out that the properties I wanna use as parameters to bean or outside the camel context are not taken into account if the file is read after the other blueprint files.
So name you properties file aaa_properties and not just properties, especially if your blueprint file is called blueprint.xml :)