SwiftMQ Client

Filetransfer Client

Introduction

The SwiftMQ Filetransfer client is an easy-to-use client to transfer files of unlimited size between JMS clients and a SwiftMQ Router. It uses an existing JMS connection and can be easily integrated with any JMS application.

The client API consists of only 3 classes:

Class

Package

Description

Filetransfer

com.swiftmq.filetransfer

Provides the Filetransfer client.

FiletransferException

com.swiftmq.filetransfer

A filetransfer exception class.

ProgressListener

com.swiftmq.filetransfer

Provides information about the progress of a file transfer.

Samples

There are several example programs provided under the SwiftMQ distribution's directory "samples/filetransfer". Please have a look!

Protecting Files

A file can be protected by a password that needs to be specified during receive. A file can also be declared as private. Links to private files are not returned from a query, rather the link needs to be known.

File Expiration

Similar to JMS messages, a file can have an expiration which is specified in milliseconds. The file is automatically deleted after it has expired.

Maximum Downloads

The maximum number of downloads can be specified for a file. The file is automatically deleted after this number has been reached.

Message Properties and Selectors

The following message properties are automatically set during send:

Property

Type

Value

JMS_SWIFTMQ_FT_USERNAME

String

The JMS user who sent the file.

JMS_SWIFTMQ_FT_FILENAME

String

The original filename

JMS_SWIFTMQ_FT_SIZE

long

File size in bytes

JMS_SWIFTMQ_FT_EXPIRATION

long

The absolute expiration time in ms (since 01/01/1970)

JMS_SWIFTMQ_FT_DIGESTTYPE

String

The digest type, e.g. "SHA1".

JMS_SWIFTMQ_FT_STORETIME

long

The absolute store time in ms (since 01/01/1970)

JMS_SWIFTMQ_FT_DELAFTDL

int

The number of downloads after which the file will be deleted.

JMS_SWIFTMQ_FT_DOWNLOADCOUNT

String

The current number of downloads.

The sender can add arbitrary custom JMS message properties to a file, e.g. by setting an "orderid" property to mark a file containing a purchase order.

In addition to the Filetransfer properties listed above, all custom properties can be used in a message selector, too. For example, if custom property "orderid" was set as a custom property and one wants to get all PDF files for a particular order id, a query might look like this:

SQL
  orderid = 12345 and JMS_SWIFTMQ_FT_FILENAME like '%.pdf'

To select all zip-files of a particular customerId range which are bigger than 1 MB, use this selector:

SQL
  JMS_SWIFTMQ_FT_FILENAME like '%.zip'
    and customerid between 10000 and 11500
      and JMS_SWIFTMQ_FT_SIZE > 1024 * 1024

Sending Files

The most basic usage of a Filetransfer object to send files is to create it, set the file to send, send and close it:

Java
         Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
         String link = filetransfer.withFile(file).send();
         filetransfer.close();

A Filetransfer object can be used to send multiple files sequentially but can not be used by multiple threads (use a dedicated Filetransfer object per thread, see Filetransfer samples):

Java
         Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
         for (int i=0; i < files.length; i++)
           filetransfer.withFile(file[i]).send();
         filetransfer.close();

Various other settings can be applied in a builder style fashion:

Java
         Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
         String link = filetransfer.withDigestType("SHA1")
                                   .withFileIsPrivate(isPrivate)
                                   .withPassword("Cheers")
                                   .withFile(file)
                                   .send();
         filetransfer.close();

In addition to a bunch of message properties that are automatically set from the Filetransfer, custom message properties can be added to each file that can be used to select them through a message selector:

Java
         Map props = new HashMap();
         props.put("orderid", orderId);
         props.put("customerid", customerId);
         props.put("documenttype", docType);
         Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
         String link = filetransfer.withDigestType("SHA1")
                                   .withFileIsPrivate(isPrivate)
                                   .withPassword("Cheers")
                                   .withProperties(props)
                                   .withFile(file)
                                   .send();
         filetransfer.close();

A ProgressListener can be used too:

Java
         Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
         String link = filetransfer.withFile(file).send(new ProgressListener()
         {
           public void progress(String filename, int chunksTransferred,
                                long fileSize, long bytesTransferred,
                                int transferredPercent)
           {
             System.out.println("  " + filename + ": " + chunksTransferred +
                                " chunks, "+ bytesTransferred + " of " + fileSize +
                                " transferred (" + transferredPercent + "%)");
           }
         });
         filetransfer.close();

Receiving Files

The most basic usage of a Filetransfer object to receiving a file is to create it with a link, set the output file, receive and close it:

Java
         Filetransfer.create(connection, link)
                     .withFile(file)
                     .receive()
                     .close();

To delete the file at the file cache after receive, call:

Java
         Filetransfer.create(connection, link)
                     .withFile(file)
                     .receive()
                     .delete()
                     .close();

One can also use the original filename. In that case the output directory needs to be specified:

Java
         Filetransfer.create(connection, link)
                     .withOutputDirectory(outDir)
                     .withOriginalFilename(true)
                     .receive()
                     .delete()
                     .close();

The password needs to be specified if file is protected:

Java
         Filetransfer.create(connection, link)
                     .withOutputDirectory(outDir)
                     .withOriginalFilename(true)
                     .withPassword("Cheers")
                     .receive()
                     .delete()
                     .close();

A ProgressListener can be used too:

Java
         Filetransfer.create(connection, link)
                     .withOutputDirectory(outDir)
                     .withOriginalFilename(true)
                     .receive(new ProgressListener()
         {
            public void progress(String filename, int chunksTransferred,
                                 long fileSize, long bytesTransferred,
                                 int transferredPercent)
            {
              System.out.println("  " + filename + ": " + chunksTransferred +
                                 " chunks, "+ bytesTransferred + " of " + fileSize +
                                 " transferred (" + transferredPercent + "%)");
            }
         }).delete().close();

There are 2 ways to get a link to a file:

  • The sending client sends it to the receiving client by using JMS (e.g. sends a JMS TextMessage). This is required for private files.

  • The receiving client queries the file cache.

To query a file cache, any existing or a new Filetransfer object can be used:

Java
        Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
        List<String> result = filetransfer.query();
        filetransfer.close();
        final CountDownLatch countDownLatch = null;
        if (result != null && result.size() > 0)
        {
          countDownLatch = new CountDownLatch(result.size());
          for (int i = 0; i < result.size(); i++)
          {
            final String link = result.get(i);
            executorService.execute(new Runnable()
            {
              public void run()
              {
                transfer(link); // Uses a dedicated Filetransfer object to receive a file
                countDownLatch.countDown();
              }
            });
          }
        }
        if (countDownLatch != null)
          countDownLatch.await();

A JMS message selector can be used to select specific files:

Java
        Filetransfer filetransfer = Filetransfer.create(connection, routerName, cacheName);
        List<String> result = filetransfer.withSelector(selector).query();
        filetransfer.close();
        // ....

Querying Properties

This functionality has been removed in SwiftMQ 13.2.0 due to XStream dependency.