Wednesday, 10 January 2018

Apache Active MQ, Spring Integration Messaging sending SWIFT MT950 messages...

I need to send MT950 messages to a SWIFT message, I've done this before but I always forget how I did it. This version, however needs to be a little more comprehensive. Specifically, I want to develop this to send messages from a query, but be able to map the query results to the message fields

so first things first I'm going to need to tool up. I downloaded Apache Active MQ and installed it (basically just uncompresses)



/Users/christopherwebster/Dev/apache-activemq-5.8.0




./bin/activemq console




The above starts Active MQ. In a web browser, navigating to http://localhost:8161/admin/index.jsp
you should see the following




  















So now we've got something to send a message to we can code up a simple test.

here's my pom:

    4.0.0
    cwc
    SwiftMessagePublisher
    1.0.0.BUILD-SNAPSHOT
    jar
    SwiftMessagePublisher
    http://www.springsource.org/spring-integration
  
    
        2.2.1
    

    
        UTF-8
        2.2.4.RELEASE
        1.2.17
        4.11
    

    
        
        repo.springsource.org.milestone
        Spring Framework Maven Milestone Repository
        https://repo.springsource.org/milestone
        

        
        repository.jboss.org-public
        JBoss.org Maven repository
        https://repository.jboss.org/nexus/content/groups/public
        

    

    
        
            
                maven-eclipse-plugin
                2.9
                
                    
                        org.springframework.ide.eclipse.core.springnature
                        

                    
                        org.springframework.ide.eclipse.core.springbuilder
                    

                    true
                    true
                

            

            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.0
                
                    1.6
                    1.6
                    -Xlint:all
                    true
                    true
                

            

            
                org.codehaus.mojo
                exec-maven-plugin
                1.2.1
                
                    com.cwc.swiftmessagepublisher.Main
                

            

        

    

    
        
        
            junit
            junit
            ${junit.version}
            test
        

        
            javax.jms
            jms
            1.1
        

        
        
            org.springframework
            spring-jms
            3.1.2.RELEASE
            

        
            org.springframework.integration
            spring-integration-jms
            2.1.3.RELEASE
            

        
            org.apache.activemq
            activemq-core
            LATEST
            

        
            org.apache.activemq
            activemq-pool
            LATEST
            

        
            org.springframework.integration
            spring-integration-core
            ${spring.integration.version}
            

        
            org.springframework.integration
            spring-integration-file
            ${spring.integration.version}
            

        
        log4j
            log4j
            ${log4j.version}
        

        
        
            commons-io
            commons-io
            2.4
        

    


Create a project and add this in eclipse. Here's mine...


I've used STS here and created a Spring project. I added maven and modified the POM. You need a couple of alternative repos because some of the dependencies aren't covered by the defaults.

notice the spring integration context. STS adds this for a Sprint Integration project by default.















You'll notice the testSend() :void test. I added this just to get the go-no-go test proved with Active MQ. Here's the code, no spring in there yet. I just want to prove that I can successfully send a message to the Queue.



@Test

public void testSend(){

try {

            //created ConnectionFactory object for creating connection 

            ConnectionFactory factory = new ActiveMQConnectionFactory("admin", "admin", "tcp://localhost:61616");

            //Establish the connection
            Connection connection = factory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            Queue queue = session.createQueue("TEST-QUEUE");
            //Added as a producer
            javax.jms.MessageProducer producer = session.createProducer(queue);
            // Create and send the message
            TextMessage msg = session.createTextMessage();
            msg.setText("Hello World");
            producer.send(msg);
        } catch (Exception e) {
            // TODO: handle exception
        e.getMessage();
        }
}

So running the tests...
We're good, all compiles and runs.. but did we send a message?

Switch to the ActiveMQ Console and review Queues. Click the queue name and you'll see there's a message. Click the message to review the payload and we can see we've got a "Hello World" message.


















OK so to review, we've installed Apache Active MQ, retaining the defaults. Created a Spring Integration Project in STS (Spring Source Tool Suite) and added a test that sends a hello world message to Active MQ. We've tested the development harness and we're ready to start generating and testing SWIFT messages.

...not bad for a hour or so's work.

Concurrency Issues in Oracle

Avoiding duplicates in multi-user environments 

Avoiding concurrency issues in stored procedures can be tricky. I'm writing some functionality to add a document ID to a table in Oracle. The requirement is as follows:

The document ID must consist of a string identifying the entity a string identifying the month and a string identifying the year and an increment.

[entity]_[mm]_[yyyy]_[nnn] which might look like 9999_01_2017_1

At first glance this looks like it should be quite easy. query the data by entity, month, year. count and add one. Cast the numeric values to a varchar and Concatenate. This, however doesn't take into account the fact that two concurrent inserts might not see a unique count. In this case you'll end up with the, possibility disastrous, duplicate. This is the scenario that DBMS_LOCK was designed to resolve.

For me the solution was to employ the example here
This very good article clearly shows how to lock a portion of pl/sql while an update is carried out and then release the lock such that the process remains isolated and gets an unimpeded view of the data it's updating and can remain confident that the process will function without concurrency issues.

   v_doc_id varchar2(20);
   v_call_status INTEGER;
   v_lock_handle varchar2(128);

   BEGIN
      -- Calculate the document id
     DBMS_LOCK.allocate_unique( 'SET_APPROVAL_DOCUMENT_ID', v_lock_handle );
     v_call_status := DBMS_LOCK.REQUEST(v_lock_handle, DBMS_LOCK.X_MODE, 5, TRUE);
     IF v_call_status = 0 THEN
      Select ( select to_char(je.legal_entity_cd)||'_'||je.financial_period
                 from me_journal_entry je
                  where je.CFME_ID = p_cfme_id) ||'_'||
               ( select to_char(count(*)+1)
                   from V_ME_JOURNAL_APPROVAL_LOG al,
                        (select je.legal_entity_cd, je.financial_period
                           from me_journal_entry je
                          where je.CFME_ID = p_cfme_id) j
                  where al.is_approved = 'Y'
                    and j.legal_entity_cd = al.legal_entity_cd
                    and j.financial_period = al.financial_period)
        into v_doc_id
        from dual;
       
    -- Insert the approval row
   
    Insert into G79_CFM.ME_APPROVAL_LOG (IS_APPROVED, CFME_ID, APPROVAL_NOTES,USER_ID, APPROVAL_TYPE, CFME_DOCUMENT_ID, APPROVAL_DATE_TIME)
                                 Values (p_is_approved, p_cfme_id,  p_approval_notes, p_user_id, p_approval_type, v_doc_id, sysdate());
   
        COMMIT;
    ELSE



Saturday, 27 April 2013

Blogging at school

Today, My eldest daughter showed me her school blog. At eight she's learning how to blog. The school  has subscribed to a bolgging site for schools. In this day and age of the internet, shouldn't the school have it's own Wordpress site? Installation literally takes minutes. Keeping it internal would make it safer and give the school full control over the site.

I've set up a few Wordpress sites now and it's so easy. I installed Wordpress on a hosted Centos machine using this fantastic tutorial Wordpresss installation 

Wednesday, 4 May 2011

Google Analytics easy-peasy-lemon-squeezy

Clever chaps & chapesses at Google. I've just put a website live for an Accountancy Outsourcing Company www.henryjamesoutsourcing.co.uk and added Google Analytics to the site.

Google Analytics is one of a number of tools Google provide for web developers. Essentially it captures statistics for pages on your web site. You have to have a Google account to use it so you have to sign up there first. Then you add Analytics to your suit of Google tools (sign up for an email address whilst you're at it and you can receive your stats reports pushed via email to the google email address)

Once you've signed up you'll get a little text window with some Java script in that'll look a bit like this

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try{
var pageTracker = _gat._getTracker("UA-xxxxxx-x");
pageTracker._trackPageview();
} catch(err) {}
</script>

Copy this and paste it into your static web pages eg index.html … before the tag (keeps things tidy) and that's it hit your site a few times and check your Analytics pages a bit later (takes a while for the stats to filter through) I hit the verify

Now for some techie stuff: This is downloading some javascript code from google that actually does the monitoring. It uses cross site scripting to do this but adding the javascript dynamically

document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));

gets round the browser security issues (see my earlier posts on cross site scripting and Ajax) Activity is reported back to google in most cases. One thing to watch out for is that any activity from China won't be reported on in full because of Chinese Government security limitations on internet information. Not that that's a problem for Henry James Outsourcing, maybe for when we're a little nearer world domination.

Monday, 18 January 2010

SEO - The Dark Art

Search Engine Optimisation - a strange and dark world occupied by people with street cred. games consoles and skateboards. I was contacted recently by a company I did some work for because searching for their name and one of their customer's brought up all the usual sites in google and my CV (woops!)

The CV was a pdf, and listed companies I had done work for although there was no direct link in the wording my CV obviously listed my client but also their customer mentioning no link or relationship.

I took the CV down for the sake of a quiet life, but it got me thinking why didn't my company website show up in the same search? http://www.cwebster-consulting.co.uk/. This in turn started me thinking about SEO (Search Engine Optimisation), something I'd not done for a long time. It dawned on me that the last time I did anything along those lines was way back when, all you had to do was drop in the key words in the meta tag and send a cheque off to your favourite search provider!

Now though, it seems things have changed. I'm reliably informed there are “White Hat” strategies that can get you to the top of the list. There are “Black Hat” strategies that can also get you there but can also get you barred from search engines altogether. You're best going to an SEO specialist Dave Chung is one SEO Guru who can help you to get your site a more appropriate audience.

So what strategy did I use to get my CV up there in the rankings? Well, none what so ever. It was a pdf, so there was no code. There were no links (I'm not that great at creating pdf's) it was just a CV exported from Word to pdf format. It did for some reason though, satisfy whatever criteria Google use to rank web pages. I can only assume that this is simply what's in the text.

I did a little more digging and came up with Google’s rules on getting good page ranking. Some interesting things come up. For example, every web page has a reputation. Websites with a good reputation linking to other well behaved websites improve their page rankings. So don't link to iffy websites and do link to legit, nice websites and let them link to you. One of the “Black Hat” strategies is to set up a company and charge people for links to bump up their ranking. Be careful, though, if discovered this can get you banned from some sites including Google.

Nice sites that show meaningful error messages (401, 403, 404, 500 errors) instead of the default pages churned out from standard web servers rank higher. So customise your error messages and give links back to the main pages in your site from the error pages.

Only three things matter on websites, content, content, content. For your site to bump up its rankings you need to publish articles that are relevant to your business. Use Title text as though it were key word searchable. Google like to use titles as guides to what's on the site. So for example if you’re a plumber you should add an article every month on Plumbing, Plumbing techniques, Plumbing products, maybe review some equipment. This will aid the search engines indexing of your site for relevant key words in the search criteria.

Finally update regularly, most search engines throw relevance into the mix by returning sites that are regularly updated and maintained. This shows a site on the move and being kept up to date. All of which adds to relevance.

Wednesday, 16 December 2009

MySQL Communications Link Failure

I'm building a MySQL Driven web app using MySQL JPA Hibernate JConnector. I've hit an exception:

HTTP Status 500 - exception
javax.persistence.PersistenceException: org.hibernate.exception.JDBCConnectionException: could not load an entity: [net.bmo.model.BmoCalendar#2]

The root cause of this error is:

root cause:java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.

Basically this means that the DB connection times out and when the app. went back to the DB to retrieve some data the connection had been lost.

Solution? Add connection pooling. Something I'd been meaning to get round to but hadn't had a chance. So I added C3P0 Connection pooling. I'm using Hibernate so I added the following dependency to the pom.xml:

  <dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-c3p0</artifactId>
    <version>3.3.2.GA</version>
  </dependency>

This drops in the required jar(s) hibernate-core-3.3.8.GA.jar and c3p0-0.9.1.jar add them to the class path if you don't already have them.

Next I added the c3p0 properties to the persistence.xml file. The amendments are highlighted in blue.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
  <persistence-unit name="myPersistence"
      transaction-type="RESOURCE_LOCAL">
   <provider>org.hibernate.ejb.HibernatePersistence
   <properties>
     <property name = "hibernate.connection.driver_class"
          value = "com.mysql.jdbc.Driver"/>
     <property name = "hibernate.connection.url"
          value = "jdbc:mysql://localhost:3306/myDB"/>
     <property name = "hibernate.connection.username" value = "uid"/>
     <property name = "hibernate.connection.password" value = "pwd"/>
     <property name = "hibernate.hbm2ddl.auto" value = "validate"/>

     <property name="hibernate.connection.provider_class"
          value="org.hibernate.connection.C3P0ConnectionProvider" />
     <property name="hibernate.c3p0.max_size" value="100" />
     <property name="hibernate.c3p0.min_size" value="0" />
     <property name="hibernate.c3p0.acquire_increment" value="1" />
     <property name="hibernate.c3p0.idle_test_period" value="300" />
     <property name="hibernate.c3p0.max_statements" value="0" />
     <property name="hibernate.c3p0.timeout" value="100" />

   </properties>
  </persistence-unit>
</persistence>



The effect of the lines above is to force the test of the connections in the pool at regular intervals and refresh the connection if required. This prevented the above error for my deployment. I did this without making any changes in the MySQL Database configuration

Tuesday, 6 October 2009

...I know a bloke who does a bit of that....

I met a guy the other day who was having a bit of difficulty with his company's IT infrastructure. If I had a pound for every time I have this conversation.

"We've got xxx application running on a server in our office and it's broken/not doing what we want any more. Can you fix it?"

Well, yes, probably. But how do companies with no IT expertise end up with huge systems flogged to them by some bloke they knew then he left/went bust/went elsewhere and now we're high and dry with no IT resources.

Also, why does someone recommend MS Small Business Server and MS Exchange to an organisation that clearly don't have the resources to maintain it? At some point the underlying SQL Server will run out of space/run into problems emails will get inevitably get lost and the whole thing will fall apart. It happens at big companies (I've seen it!) and can cause all sorts of issues, but it can cripple a small organisation.

These are the same organisations that don't get a consultancy in to give them a realistic breakdown of the the options and costs. I'd want to see 3 or 4 different options and cost/benefits for each and make my mind up from there. There's no doubt that there are a lot of clever systems out there with lots of features but they all come at a price and maintenance is no small part of that price.

I'm not saying that consultancy is a solution in itself, far from it. In the UK Business Link can be a good source of advice as well as numerous other organisations. There's a range of issues to consider when buying an IT system. Hardware failure support, software training support, procurement, installation & deployment, maintenance & disposal. Having seen a few RFP's (Request For Proposal) usually issued by very large companies to invite bids from suppliers. This seems a good way for small businesses to think too. If nothing else it forces the purchaser to consider the requirements as a whole rather then just as buying a shiny sparkly new computer that looked great in the add. A little bit of light research will show up RFP examples and guidance

This company I spoke to could have achieved all they wanted (email, shared docs & calendars, holiday forms linked to storage and basic work flow) from Google Apps for example or any number of other systems and it wouldn't have cost him the best part of 6k GBP and he wouldn't be high and dry when it went wrong.

In this case SAAS(Software As A Service) services (or ASP - Application Service Provision - as it used to be known) could have a real benefit. YOU don't have to have a DBA and a Sys Admin on your books. There's plenty of time and scope to bring that in house as and when you're big enough. But please don't "get a bloke you know" to do it for you unless he's prepared to enter into an SLA(Service Level Agreement) and can provide you with a DR strategy for when he gets hit by a bus.