How to simulate a MQ server ?

The problem

Our application is retrieving information from a distant server using IBM Websphere Mq messaging system. In production we need to install two MQ servers , one on machine A and another one on machine B:

Creation Fil MQ

We want to avoid installing MQ Server on two machines for the qualification platform. How to simulate machine B ‘s MQ Server ?

The solution

This article will explain several steps taken to simulate the communication between two MQ servers. These are the steps explained :

  • Create a MQ server on machine A
  • Run a Java application on machine B within tomcat which listens to inqueue QueueManager and send back information to Outqueue MQ queue manager
  • Create a MQ server on machine A

    A IBM MQ server is composed of a queue manager, local queues, channels. Channels allow the queues to communicate between each other. Aliases can also be used to give an alias to queues.

    https://wordpress.com/post/julienprog.wordpress.com/1235

    Simulate a MQ server on machine B

    First of all install tomcat on the machine B. The solution is using Java to catch JMS information from our MQ Server on machine A. To simulate the MQ Server these are the steps :

  • Add a listener in web.xml
  • The Java class listener will be launched at tomcat startup.
  • At statup , the listener starts one Thread or multiple ones to listen one or multiples queue managers
  • Let’s assume we have one thread listening to one Queue manager
  • When a Thread is cathing a JMS message, from receiver/in queue of machine A, it will parse the message
  • Based on the parsed message we check a database or filesystem for a DataSet response
  • Finally we send the dataset response to the Out/sender queue of machine A
  • The application in machine A reads the out/sender queue and process it like normal not knowing it is consuming messages from the simulator
  • That’s it : the machine B simulated a MQ Server
  • Add a listener to tomcat web.xml

    <web-app>
    	<display-name>MQ-Sim</display-name>
    
    	<listener>
    		<listener-class>my.com.MQListener</listener-class>
    	</listener>
    
    

    At startup of tomcat the MQlistener will be launched. The thread is started within the listener like this :

    final MqThread mq= new MqThread (mqinfo);
    MqThread .start();
    

    Read MQ configuration detailed from a file

    We need to know to which receiver/in queue we will listen to and which sender/out queue we will send message to.

    Example of properties file containing these information :

    hostname	  = myserver
    port		  = 9999
    queueManager = MYQUEUEMANAGER
    queue.in	  = QUEUE.OUT
    queue.out	  = QUEUE.IN
    

    “queue.in” represents the queue we are lestening to. “queue.out” is the queue we are going to send message to.

    Start a thread listening to a receiver queue

    The MqThread extends Thread class. It contains a run() method which will be executed when the thread is started.

    The MqThread constructor prepares an active connection with the queue manager and the queue receiver and sender in order to communicate with the MQ server .

    
    import javax.jms.QueueConnection;
    ...
    public MqThread (MqInfo mqInfo) throws JMSException {
           
    final MQQueueConnectionFactory queueConnectionFactory = new MQQueueConnectionFactory();
    			queueConnectionFactory.setTransportType(JMSC.MQJMS_TP_CLIENT_MQ_TCPIP);
    			queueConnectionFactory.setQueueManager(mqInfo.getQueueManager());
    			queueConnectionFactory.setHostName(mqInfo.getHostname());
    			queueConnectionFactory.setPort(mqInfo.getPort());
    
          queueConnection = queueConnectionFactory.createQueueConnection(mqInfo.user, mqInfo.password);
          queueConnection.start();
          // A QueueConnection object is
          // an active connection to a point-to-point JMS provider.
    
          this.queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
          // A QueueConnection can be used 
          // to create a QueueSession, 
          // from which specialized 
          // queue-related objects can be created
          this.receiver = session.createReceiver(mqInfo.receiverQueue);
          // Creates a QueueReceiver object to receive 
          // messages from the specified queue.
          this.sender = session.createSender(mqInfo.senderQueue);
          // Creates a QueueSender object to send 
          // messages to the specified queue.
    }
    

    More information about QueueConnection
    http://docs.oracle.com/javaee/6/api/javax/jms/QueueConnection.html

    The thread will be listening to MQ receiver queue. When a JMS message is sent to that queue the thread will consume and parse the message.

    public run() {
    
    		this.queueManager = queueManager;
                    while (isThreadTerminated) {
    		    final Message message = receiver.receive(1000);
    		    proccessMessage(message );
                     } 
    }
    

    The run() method is listening to queue receiver to handle messages from this queue.

    Receives the next message that arrives within the specified timeout interval.

    http://docs.oracle.com/javaee/6/api/javax/jms/MessageConsumer.html#receive(long)

    Based on the parsed message we check a database or filesystem for a DataSet response

    Once the message is parsed we can retrieve a DataSet response from a file system. This example is not complet but give an idea what to do :

    
    	private String getDataSetResponse(String inputMessage) {
    
    		final String filename = getFileNameDataSet(inputMessage);
    		return getFile(filename );
    	}
    

    Finally we send the dataset to the Out/sender queue of machine A

    private void sendMessage(String message, String messageId) throws JMSException {
           final TextMessage dataSetMessage = session.createTextMessage(message);
           dataSetMessage.setJMSCorrelationID(messageId);
           dataSetMessage.setJMSMessageID(messageId);
           sender.send(dataSetMessage );
    }
    

    That ‘s it

    Advertisements

    How to apply CSS specific on several tables ?

    Problem

    Our website did not look nice because of a CSS problem.
    Indeed some data on one row of a table was scrollable.
    The data of one row would overflow.

    How to stop this data to be scrollable on one line ?
    The goal was to present the information in several lines instead of one line. The solution to this first problem was to modify the table-layout for the CSS element table to “fixed” property.

    
    table {
        border-collapse: collapse;
        clear: both;
        margin-left: auto;
        margin-right: auto;
        width: 98%;
    
        table-layout: fixed;
    }
    
    

    Unfortunalely because of this global modification of CSS another problem popped up in a diffrent webpage :

    display_problem

    The solution for this second problem was to make the CSS table tag to this configuration :

    table-layout: auto
    

    Auto layout is the default property for most of the tables of my website in CSS.The auto property adapts the table layout to all different browers which is practical. But how can we apply specific CSS properties to specific tables ?

    This link help me to apply specific CSS to one specific table using id :
    https://www.w3schools.com/html/tryit.asp?filename=tryhtml_table_id1

    Solution

    This is the html page where we had a scrollable/overflow initial problem :

    <table id="my_tableA_X" class="result ">
    <table id="my_tableA_Y" class="result ">
    <table id="my_tableA_Z" class="result ">
    

    my_tableA_Y is having the scrollable/overflow problem. But I want also all other tables (starting with my_tableA) to have a similar look. Therefore i  will  apply the same CSS properties to all tables with id starting  by “my_tableA”. Regex is used to achieve this inside CSS file :

    https://stackoverflow.com/questions/11496645/how-to-get-css-to-select-id-that-begins-with-a-string-not-in-javascript

    The solution to the two problems :

    table[id^=my_tableA]{
        border-collapse: collapse;
        clear: both;
        margin-left: auto;
        margin-right: auto;
        margin-bottom: 5px;
        margin-top: 5px;
        width: 98%;    
    
        table-layout: fixed;
    }
    
    table {
        border-collapse: collapse;
        clear: both;
        margin-left: auto;
        margin-right: auto;
        width: 98%;
    
        table-layout: auto;
    }
    

    Now all table which start with an id my_tableA have the same layout and columns have same size , width, etc… This solution fixed the problem. The second table CSS tag indicates that other tables will have auto layout.

     

    How to bind apache server non localhost to tomcat server?

    Goal

    We would like to make sur tomcat only listen to apache server which was not on localhost adress. It is a security measure to protect the tomcat port.

    In order to do that we need to add the attribute “address” to the connector of the tomcat port.
    Few words about the connector :

    The HTTP Connector element represents a Connector component that supports the HTTP/1.1 protocol. It enables Catalina to function as a stand-alone web server, in addition to its ability to execute servlets and JSP pages.

    http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

     
    <Connector port="8111"                
                   acceptCount="100"     
                address="127.0.0.1" 
                   connectionTimeout="5000"               
                   keepAliveTimeout="10000"               
                   maxKeepAliveRequests="1"               
                   maxConnections="10000"               
                   protocol="HTTP/1.1"
                   />
    

    Few words about the attribute address :

    For servers with more than one IP address, this attribute specifies which address will be used for listening on the specified port. By default, this port will be used on all IP addresses associated with the server.

    NOTE : this solution uses HTTP protocol connector to connect to apache instead of AJP protocol. The connector AJP should be used between apache and tomcat for performance reason.
    https://www.mulesoft.com/tcat/tomcat-connectors

    Problem

    At first I used the localhost address(127.0.0.1) to make tomcat listening to this address. I wrongly assume the apache server was at the local address server.

    Apache and tomcat would start with no errors. However the application would not start. There was no errors meaningful in the application logs, tomcat logs. At last i found some error in apache server error.log :

    [Thu Jun 15 17:56:15 2017] [error] (111)Connection refused: proxy: HTTP: attempt to connect to 191.14.12.14:8111 (machine_adress) failed
    [Thu Jun 15 17:56:15 2017] [error] ap_proxy_connect_backend disabling worker for (machine_adress)

    This error helped to find a solution to this problem.
    I checked the IP address 191.14.12.14 and I found out in /etc/hosts that the adress 191.14.12.14 was link to a server called apache_instance1

    Solution :

    I check in apache configuration “httpd.conf” and I found out that the name of the server is :

    ServerName apache_instance1
    

    Therefore to bind tomcat port to listen only to apache server, I had to do modify the attribute adress like this :

     

     
    <Connector port="8111"                
                   acceptCount="100"     
                address="apache_instance1" 
                   connectionTimeout="5000"               
                   keepAliveTimeout="10000"               
                   maxKeepAliveRequests="1"               
                   maxConnections="10000"               
                   protocol="HTTP/1.1"
                   />
    

    It fixes my problem.

    Set up apache reverse proxy with tomcat

    This article will overview the relation between Apache HTTP Server and tomcat and also the reverse proxy.

    For a long time tomcat/apache was a black-box for me because I did not have to manage it. But few years ago I had the opportunity to gain more knowledge on this subject. The aim of this article is to focus on the big picture of apache/tomcat and present the mod reverse proxy for Apache HTTP server.

    What is tomcat ?

    Tomcat executes Java servlets and renders Webpages JSP ( Java server page). This guide can help you to understand and run tomcat https://tomcat.apache.org/tomcat-3.2-doc/uguide/tomcat_ug.html

    Tomcat is a web server used in the Java world most of the time. It is also easy to use in dev environment with Eclipse for quick testing of JSP/Javascript/HTML/CSS pages.

    Install tomcat on linux :
    http://www.vogella.com/tutorials/ApacheTomcat/article.html

    Why use Apache if tomcat is a web server ?

    Apache is more robust for HTML/images static content. For production environment it is necessary to have Apache HTTP web server combined with tomcat for dynamic content(JSP).

    https://tomcat.apache.org/tomcat-3.2-doc/tomcat-apache-howto.html

    How apache and tomcat communicate together ?

    I am not going into details since there is a documentation about it in user’s guide and also here https://tomcat.apache.org/tomcat-3.2-doc/tomcat-apache-howto.html

    I am just going through the most important steps briefly and give real world example along the way. For information the example i am giving is in with tomcat version 8.0.23 and apache version Apache/2.2.15 (Unix).

    What’s required to pull this off?
    Answers to the above three questions!
    1. Configure Tomcat
    2. Install a web server adapter.
    3. Modify Apache’s httpd.conf file.

    1.Configure Tomcat

    1.1 Modify Tomcat’s server.xml file.
    -> Create connectors (HTTP/HTTPS/AJP). A “Connector” represents an endpoint by which requests are received and responses are returned.
    ->The AJP connector is mechanism by which Tomcat will communicate with Apache.

    1.2 Defining a context.
    ->It is NOT recommended to place elements directly in the server.xml file. Defined in context.xml instead.https://tomcat.apache.org/tomcat-7.0-doc/config/context.html
    -> We can also defined here the jdbc configuration used to access the database. Jdbc Example under the context :

    The Resources element represents all the resources available to the web application. https://tomcat.apache.org/tomcat-8.0-doc/config/resources.html . Example of resource within the context to mount the web app :

    2.Install a web server adapter.

    This adapter is not located in apache or tomcat configuration. It answers the question : “How will Apache forward these requests to Tomcat?”.
    http://tomcat.apache.org/connectors-doc/webserver_howto/apache.html

    mod_jk requires two entities:
    mod_jk.xxx – The Apache HTTP Server module, depending on your operating system, it will be mod_jk.so, mod_jk.nlm or MOD_JK.SRVPGM (see the build section).For example in our linux machine.
    find / -iname ‘*MOD_JK*’ -print 2>/dev/null
    /usr/lib64/httpd/modules/mod_jk-1.2.31-httpd-2.2.x.so
    workers.properties – A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory in the source download.
    Also as with other Apache modules, mod_jk should be first installed on the modules directory of your Apache HTTP Server, ie: /usr/lib/apache and you should update your httpd.conf file.
    Mod_jk.conf – It is not necessarily needed to make custom changes of this file. There are situation where we need to make changes.

    For information workers.properties and Mod_jk.conf are located under our module apache/conf.d

    3.Modify Apache’s httpd.conf file.

    We need to tell Apache how to load and initialize our adapter, and that certain requests should be handled by this adapter and forwarded onto Tomcat.Tomcat does most of the work for you.

    Each time you start Tomcat, after it loads Contexts (both from the server.xml and automatically from $TOMCAT_HOME/webapps), it automagically generates a number of files for you. The two that we’re concerned with are:
    tomcat-apache.conf (should really be named mod_jserv.conf-auto)
    mod_jk.conf-auto

    For example on my latest project our httpd.file we have simply a line to include all configuration files for apache including mod_jk.conf. :

    Include conf.d/*.conf

    NOTE : For this application we do not use mod_jk.conf-auto but our own custom configuration file mod_jk.conf.

    More information at chapter “httpd.conf – Apache’s main configuration file” https://tomcat.apache.org/tomcat-3.2-doc/tomcat-apache-howto.html#httpd

    Reverse Proxy in Apache

    A reverse proxy (or gateway), appears to the client just like an ordinary web server. No special configuration on the client is necessary. The client makes ordinary requests for content in the namespace of the reverse proxy. The reverse proxy then decides where to send those requests and returns the content as if it were itself the origin.

    https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html#access

    We wanted to set up a reverse proxy in order to access to a remote web server running on different machine but on the same network. The idea was to access a servlet running on different application. It would save us duplicating the servlet and a database for our application. Instead of creating something existing we could just reuse an existing web server.

    As you have seen previously we have loaded all .conf files in conf.d directory including our reverse_proxy.conf file.

    Our configuration file for the reverse proxy is the following :

    # Load the proxy module
    LoadModule proxy_http_module modules/mod_proxy_http.so

    # HTTP
    ProxyPass /foo/loadsomeinfo http://192.168.10.1.8080/loadapp
    ProxyPassReverse /foo/loadsomeinfo http://192.168.10.1.8080/loadapp

    ProxyPass / http://machinea:9000/
    ProxyPassReverse / http://machinea:9000/

    Apache module mod_proxy :
    https://httpd.apache.org/docs/2.4/en/mod/mod_proxy.html#access

    Basics knowledge of Apache HTTP Server

    I created this article as a reminder about some basics of Apache HTTP Server with real examples. I will present how to start apache,look for logs, and give information about the configuration.

    The HTTP server handles request and does the mapping from URL to Filesystem locations. More information at https://httpd.apache.org/docs/2.4/en/urlmapping.html

    How do we start Apache ?

    On Unix, the httpd program is run as a daemon that executes continuously in the background to handle requests.
    https://httpd.apache.org/docs/2.4/en/invoking.html

    According to the documentation, httpd should be invoked by a script called apachectl.
    https://httpd.apache.org/docs/2.4/en/programs/httpd.html

    Let’s see with an example a running apache daemon. It happens I have an apache server on a test machine .

    ps -edf | grep httpd
    root     23154     1  0 10:44 ?        00:00:00 /usr/sbin/httpd.worker -f /var/apache/conf/httpd.conf -f /var/apache/conf/httpd.conf -k start
    

    This command ps – edf tells us where is located the configuration file used for this apache running. On our machine exists many old install of apache. Therefore this command helps to find the right configuration file used by the current apache server.

    One would wonder why httpd.worker is being run and not httpd? What is httpd.worker?
    The answer to this question is here :

    http://serverfault.com/questions/213956/what-is-the-difference-between-apachectl-and-httpd-worker

    Basically at the installation of our product we install a new Apache/tomcat and deploy the application automatically. More information about how it is installed with shell scripts and deployed from Jenkins at
    https://julienprog.wordpress.com/2015/08/05/automate-the-installation-of-a-product-with-bash-scripts/

    Here are the commands executed by the shell script to launch our Apache server when installing on our machine :

    #----------------------------------------------------------------------------------------------------
    # Start the Apache http daemon
    #----------------------------------------------------------------------------------------------------
    start_httpd()
    {
        write_log "Starting Apache..."
                export OPTIONS="-f ${ApacheDir}/conf/httpd.conf"
    /usr/sbin/apachectl $OPTIONS -k start
    ReturnCode=$?
    #more code to handle the response
    }
    

    Where are the logs?

    To my mind it is an important question if we want to troubleshoot problems on the server.
    More about logging and how to understand the format of the logs :
    http://httpd.apache.org/docs/2.4/en/logs.html

    Previously we find out where is the configuration for the httpd running at /var/apache/conf/httpd.conf. If I look into this file i can find where are located the log :

    ErrorLog logs/error_log
    

    Thus , on my server, the error log is located at /var/apache/logs/error_log

    NOTE : If you have several Virtualhosts you will have one log for each of them.
    It happens that on the directory /var/apache/logs there are more logs than just error_log. It is because we have defined some other configuration in /var/apache/conf.d.

    For example if i want to find which module generate ssl_error_log, i will execute on the linux machine :

     grep -rnw '/var/apache' -e "ssl_error_log"
    /var/apache/conf.d/mod_jk.conf:57:ErrorLog logs/ssl_error_log
    

    Understand Apache Configuration

    The following considerations are about about the HTTP Server configuration : “httpd.conf”, and other custom made configuration files.

    What is the purpose of DocumentRoot ?

    Extract from httpd.conf :

    #
    # DocumentRoot: The directory out of which you will serve your
    # documents. By default, all requests are taken from this directory, but
    # symbolic links and aliases may be used to point to other locations.
    #
    DocumentRoot "/var/apache/www/html"
    

    Files and directories underneath the DocumentRoot make up the basic document tree which will be visible from the web.

    Therefore what you see on a website is the tree structure under DocumentRoot :
    Then a request for http://www.example.com/fish/ will cause httpd to attempt to serve the file /var/www/html/fish/index.html.

    What does IfModule tag in configuration files ?

    Did you notice

    <IfModule>

    tag in configuration files of apache server and wondered what is it exactly ?

    In the following example, the MimeMagicFile directive will be applied only if mod_mime_magic is available.

    <IfModule mod_mime_magic.c>
        MimeMagicFile "conf/magic"
    </IfModule>
    

    https://httpd.apache.org/docs/2.4/en/sections.html

    Therefore this tag will apply directives from module.

    What is ServerName ?

    Extract from httpd.conf :

    #
    # ServerName gives the name and port that the server uses to identify itself.
    # This can often be determined automatically, but we recommend you specify
    # it explicitly to prevent problems during startup.
    #
    # If this is not set to valid DNS name for your host, server-generated
    # redirections will not work.  See also the UseCanonicalName directive.
    #
    # If your host doesn't have a registered DNS name, enter its IP address here.
    # You will have to access it by its address anyway, and this will make
    # redirections work in a sensible way.
    #
    ServerName apache-myinstance:8080
    

    Do the following command in a shell terminal to have more information about the IP address of the server name:

    cat \etc\hosts
    

    What is doing the directive Listen ?

    The Listen directive tells the server to accept incoming requests only on the specified port(s) or address-and-port combinations.
    https://httpd.apache.org/docs/2.4/en/bind.html

    For example we have on our server used two times the directive for

    # Virtual HOST HTTP **
    Listen apache-myinstance:8080
    # Virtual HOST HTTPS **
    Listen apache-myinstance:447
    

    What is a Virtual Host ?

    httpd is also capable of Virtual Hosting, where the server receives requests for more than one host. For example on the same server you would have http://www.mywebsite.com and http://www.myotherwebsite.com,etc.. running.

    <VirtualHost apache-myinstance:447>
    
          JkMount /* myworker
    
    ErrorLog logs/ssl_error_log
    CustomLog logs/ssl_access.log java_format
    LogLevel warn
    
    SSLEngine on
    SSLProtocol all -SSLv2
    SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
    SSLCertificateFile /etc/certs/localhost.crt
    SSLCertificateKeyFile /etc/certs/localhost.key
    
    <Files ~ "\.(cgi|shtml|phtml|php3?)$">
        SSLOptions +StdEnvVars
    </Files>
    <Directory "/var/www/cgi-bin">
        SSLOptions +StdEnvVars
    </Directory>
    
    SetEnvIf User-Agent ".*MSIE.*"          nokeepalive ssl-unclean-shutdown          downgrade-1.0 force-response-1.0
    
    </VirtualHost>
    

    How to modify your git credentials when cloning from Git Extensions ?

    Problem

    I installed recently git extensions on Windows https://gitextensions.github.io/ . I had to clone a repository located on a distant server.

    clone_repo

    But I used a wrong login (mywronglogin). Here is the error :

    "C:\Program Files (x86)\Git\bin\git.exe" clone -v --recurse-submodules --progress --branch develop "https://www.example.com/git/myproject.git" "D:/my_repo_git"
    Cloning into 'D:/my_repo_git/myproject'...
    fatal: remote error: FATAL: R any myproject mywronglogin DENIED by fallthru
    (or you mis-spelled the reponame)

    Unfortunately from the user interface of git extensions it is not possible to modify the credentials !

    I have done the following without success

    • Modifying login in git extensions UI
    • Looking for the configuration with my wronglogin in C:/Users/mylogin, the directory of git and git extensions
    • Modifying regedit
    • I tried to uninstall git exensions but after reinstall : i got the same issue !
    • Finally I found out about the credential helper for Windows which can cache git credentials.

    Solution

    I had to unset the cache credential in order to modify this login. Indeed the credentials are stored in the “credentials.helper” to avoid typing them every time. It is a nice feature except when you want you to modify the credentials for some reason.

    I had to unset credentials like this :

    git config --system --unset credential.helper
    

    http://stackoverflow.com/questions/15381198/remove-credentials-from-git

    Now when you will clone the repo you will be asked for the login/password !
    If you were not aware of this feature you can spend quite some time on this problem.

    How to call asynchronously web servers with Javascript ?

    Problem :

    We wanted to display or hide information from more than five web servers when loading a homepage. Instead of waiting until all the servers reply to us ( synchronous method) the customer wanted to see the information as soon as the server would reply. This solution presents a better user experience because the webpage is more responsive.

    Solution

    I will decompose the solution in several parts and explain each steps

    • A HTML/W3.CSS webpage with a button calling the javascript method
    • The Javascript code calling multiple web servers
    • The Javascript class that call a web server
    • The callback method which handle the response of the web server
    • The Javascript function which updates the webpage after obtaining a response from the server.

    HTML web page

    The html webpage contains a button and a text input. The text input is sent to the web servers when we click the button.

    main_webpage
    This is a simple example of webpage

    The link to my javascript file :

    <script type="text/javascript" src="./webserver.js">
    <script type="text/javascript" src="./request.js">

    When we click on the button we call a javascript function which will use the text content of the input “myinput”.

     <input name="myinput" id="myinput" class="w3-input w3-border w3-light-grey" type="text">
    <button class="w3-btn w3-blue-grey" onclick="callWeb()">Load Web Servers</button>

    callWeb() is a Javascript function which will retrieve the input value and call web servers.

    function callWeb() {
        var input = document.getElementById('myinput'),
           myinput = input.value;
        if (myinput) {
           loadWebServers(input);
        } else {
           alert('Please enter an input!');
           input.focus();
        }
    }
    

    To avoid the error “The character encoding of the HTML document was not declared” : I have added these lines in the HTML :

    <meta content="text/html;charset=utf-8" http-equiv="Content-Type">
    <meta content="utf-8" http-equiv="encoding">
    

    For information in this example I use W3.CSS for the style. It is a modern CSS framework with built-in responsiveness. It is an equivalent of Bootstrap. More information at https://www.w3schools.com/w3css/.

    Javascript : Calling multiple web servers

    I will present the javascript function which send the request and the callback function which handle the response .

    function loadWebServers(input)
    {
        var value1 = input
        var value2 = ''
        var value3 = ''
        loadWebABC(value1);
        loadWebX(value1);
    }
    

    In this example we call only two web servers. loadWebABC call a web service with XML request. loadWebX call another web service with a JSON request.

    function loadWebABC(value1)
    {
     updateLoading();
    MyClassRequest.sendXmlRequest("http://example.com/service", "myinput=”+ value1, "callbackWebABC");
    }
    

    When the server replies, the callback will handle the response :

    function callbackWebABC(xml)
    {
        updateLoading();
        var rootInfo = xml.getElementsByTagName("root-info");
        //parse more information
       infoextracted=…..
        showOrDisplayInfo(infoextracted);
    }
    

    Javascript : Detail of the class that call the web server

    XmlHttpRequest is the class used to call distant web servers.
    https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

    If you use XMLHttpRequest from an extension, you should use it asynchronously. In this case, you receive a callback when the data has been received, which lets the browser continue to work as normal while your request is being handled.

    https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests

    MyClassRequest is the equivalent of a class in Javascript world. It is defined in a file called request.js :

    var MyClassRequest = {
    	loading : false,
    
    updaters : new Array(),
    
    	Updater : function(request, backFunction, param, isXml, isJson) {
    		this.request = request;
    		this.backFunction = backFunction;
    		this.param = param;
    		this.isXml = isXml;
    		this.cancelled = false;
    		this.isJson = isJson;
    	},
    
    	createRequest : function() {
    		var request = false;
    		try {
    			request = new XMLHttpRequest();
    		} catch (trymicrosoft) {
    			try {
    				request = new ActiveXObject("Msxml2.XMLHTTP");
    			} catch (othermicrosoft) {
    				try {
    					request = new ActiveXObject("Microsoft.XMLHTTP");
    				} catch (failed) {
    					request = false;
    				}
    			}
    		}
    		return request;
    	},
    
    	sendXmlRequest : function(url, urlParam, backFunction, param) {
    		return this
    				.sendRequest(url, urlParam, backFunction, param, true, false);
    	},
    
    	sendRequest : function(url, urlParam, backFunction, param, isXml, isJson, timeout) {
    		 if (typeof(timeout)==='undefined') {
    			 timeout = 0;
    		 }
    		var request = this.createRequest();
    
    		if (!request) {
    			alert("Request not supported");
    			return -1;
    		} else {
    			var index = this.updaters.length;
    			this.updaters[index] = new MyClassRequest.Updater(request,
    					backFunction, param, isXml, isJson);
    
    			request.open("POST", url, true);
    			request.onreadystatechange = MyClassRequest.receiveRequest;
    			if (timeout != null && timeout > 0) {
    				request.timeout = timeout;
    				request.ontimeout = MyClassRequest.timeoutRequest;
    			}
    			request.setRequestHeader("Content-Type",
    					"application/x-www-form-urlencoded; charset=UTF-8");
    			request.send(urlParam);
    
    			this.setLoading("true");
    			return index;
    		}
    	},
    

    As you can see the function sendXmlRequest is a sub function of sendRequest. sendRequest will use the object XMLHttpRequest or an equivalent for microsoft supported browser. This important part in this function is :

    request.onreadystatechange = MyClassRequest.receiveRequest;
    

    It is receiveRequest function which will trigger the callback function defined previously.

    receiveRequest : function() {
    		var stillLoading = false;
    		for ( var i = MyClassRequest.updaters.length - 1; i >= 0; i--) {
    			var updater = MyClassRequest.updaters[i];
    			if (updater != null) {
    				if (updater.request.readyState == 4) {
    					MyClassRequest.updaters[i] = null;
    					if (updater.cancelled == false) {
    						if (!updater.request.status == 200) {
    							alert("No response from server");
    						} else {
                                                            if (updater.backFunction) {
    							callbackFunction(updater);
                                                            }
    						}
    					}
    				} else {
    					stillLoading = true;
    				}
    			}
    			MyClassRequest.setLoading(stillLoading);
    		}
    	},

    callbackFunction is the function which will actually call our callback function when we receive correctly a response form the distant web server.

    function callbackFunction(updater)
    {
    
    var func = new Function("response", "param",
    			updater.backFunction
    					+ "(response, param)");
    	if (updater.isXml) {
    		var xml = updater.request.responseXML;
    		if (MyClassRequest.checkErrors(xml)) {
    			func(false, updater.param);
    		} else {
    			func(xml, updater.param);
    		}
    	} else {
    		func(updater.request.responseText,
    				updater.param);
    	}
    
    }
    

    Javascript : update the webpage

    In the previous callback method we use a function showOrDisplayInfo(). This function will display or hide element in the web page. This is a simplified version of the function but as you can see it modifies an HTML element to show or hide this element.

    function showOrDisplayInfo(infoextracted) {
    for (var infoin infoextracted)
        {
          var idElementToShow ="elementX"+ infoin;
             show( idElementToShow );
        }
    }
    
    function show(element)
    {
      if (element)
      {
        element.style.display="";
      }
    }
    
    function hide(element)
    {
      if (element)
      {
        element.style.display="none";
      }
    }