Alibaba Cloud offers a language translation service powered by machine learning. You can use this to easily present your e-commerce site in multiple languages, enable multi-lingual search and even translate support chats in real-time.
The service is currently made available as an SDK called “Machine Translation,” also known as Ali MT. Users are required to integrate the SDK into their application components that need to perform language translation. One approach would be implementing a client-server model with the SDK implemented in just the designated ‘server’ process(es) with the clients making translation requests to it. This offers some abstraction in your architecture by avoiding the need to have every process that wants to use the translation service be familiar with the full Machine Translation SDK.
For example, in a modern event-driven microservices architecture you can envision a set of elastically scaled microservices that offer the translation capability to all other microservices.
In many enterprises, JMS brokers are a very common way of connecting applications and services. As an easy to use messaging API, JMS is embedded in many integration products. If you have an enterprise service bus (ESB) in use today, a JMS provider is probably part of the stack.
Looking across your enterprise IT infrastructure, you may need to expose new cloud-based services like this to existing applications that are connected to an ESB, in addition to connecting them to new applications in a microservices architecture or functions-as-a-service (FaaS) deployment. You may also have some Internet of Things (IoT) devices that need to access them.
Wouldn’t it be great if you could deploy just one set of services and handle all these different client and protocol needs? With the help of an event broker like PubSub+, you can.
With JMS being an API specification only, and not tied to any particular product, it is possible to code an application against the API so that it works with any JMS-compliant JMS broker. The client libraries that contain vendor-specific detail can be resolved at runtime from the classpath. To eliminate the need for even this vendor specific library dependency in your application, the Advanced Message Queuing Protocol (AMQP) defines a standards-based connectivity protocol so an open source library can connect to brokers from multiple vendors without so much as a library change.
To support JMS connectivity to Alibaba MT, I have created a wrapper around the SDK and made it available here on Github. There are two demo JMS applications (as runnable JARs) in the repository that are implementing the request-reply pattern:
The Replier program is in the server role in the client-server pattern and is the only program needing to implement the Machine Translation SDK; the Requestor program is completely unaware of the SDK.
The repository by default builds with support for the AMQP JMS libraries from Apache Qpid, so it’s immediately ready to connect to a JMS broker such as Solace PubSub+ that supports AMQP.
To run the programs you need to update the contents of two files that are also in the checked out repository:
jndi.properties– This tells the programs how to connect to the JMS broker and what destination to use
alibaba-mt.properties– This tells the Replier program how to connect to the Alibaba Machine Translation service.
The easiest way to get started is to sign up for a free developer plan of PubSub+ Cloud. Once you have your service, jump down into the AMQP connectivity details from the “Connect” tab like so:
You can then modify the jndi.properties file to add the connection URI, username and password into the jndi.properties file like so in the “connectionfactory.ConnectionFactory” line:
connectionfactory.ConnectionFactory = amqp://your-service-here.messaging.solace.cloud:5672?jms.username=solace-cloud-client&jms.password=YourPasswordHere&jms.clientIDPrefix=NLPTranslationSample-&
For the purposes of this demo, also update the JMS destinations names like so:
topic.nlp-translation-requests-send = jms/nlp/translation/requests topic.nlp-translation-requests-receive = */nlp/translation/requests
Next, we need to provide the details of your Machine Translation service to the programs. You can get these details by following the instructions here.
In alibaba-mt.properties enter your service details like so:
service-region=cn-hangzhou access-key-id=IDGoesHere access-key-secret=SecretGoesHere
If you don’t have access to the service yet, you can also run the programs in offline/simulation mode. Just add the following line to the file instead:
Now you are ready to run the programs and access Machine Translation over JMS. Start the replier program first:
java -jar AlibabaNLPReplier.jar -j ./jndi.properties -a ./alibaba-mt.properties
Then start the requesting program:
java -jar AlibabaNLPRequestor.jar -j ./jndi.properties
The requesting program will collect keyboard input as you type and submit each new line as a request for translation.
For lightweight microservices running in a Functions-as-a-Service manner without a lot of library dependencies, communicating over HTTP is a popular mechanism. So let’s add HTTP support for the translation service next.
With the Java replier program running, we can actually have the same process respond to requests delivered over HTTP without deploying any further services or components. By selecting Solace PubSub+ as the JMS provider, its REST Microgateway provides access to the same JMS destinations over HTTP.
The Solace PubSub+ REST connectivity feature can operate in two modes: messaging and gateway. The default setting for a newly created event broker or cloud service is messaging but we need it operating in ‘gateway’ mode for this exercise.
Follow the instructions here to change the mode for your broker.
Assuming a Linux shell environment, we can use the curl client to make a translation request over the HTTP POST method. To facilitate this, we’ll put the relevant connectivity details into shell variables for convenience like so:
$ USER=solace-cloud-client $ PASS=your-password-here $ REST_ENDPOINT="http://your-instance-here.messaging.solace.cloud:9000/nlp/translation/requests"
You’ll note the REST endpoint adds the
nlp/translation/requests path as a way of matching up to the JMS program and the destination it is already listening to.
When the JMS programs receive requests and respond to them, they expect a
CorrelationID to be present to properly respond to the requests. For the HTTP POST we can pass this in the header, so let’s setup a variable for this too:
$ CORRELATION="Solace-Correlation-ID: aRandomString"
Lastly, another header is required to specify that this is plain text being sent and not, say, binary. This final shell variable can set this up too:
$ TYPE="Content-Type: text/plain"
That’s all that is required. We are ready to run the curl command with the relevant arguments:
$ curl -u $USER:$PASS -d "This request is via HTTP POST" -H "$TYPE" -H "$CORRELATION" -X POST $REST_ENDPOINT
MQTT is a low power and low bandwidth protocol which makes it a very popular choice for IoT systems. With these devices typically being supported by applications and services running elsewhere (such as on-premises or in a cloud) there is a need to get bidirectional data flows from these devices using MQTT to applications and services using different protocols. Fortunately, PubSub+ event brokers will easily do this protocol translation for you.
Keeping the same Java program running, let’s get a request for translation sent using the MQTT protocol so that the Java program can consume it over JMS.
You will recall that our JMS programs are utilizing a ‘request-reply’ pattern of message exchange, with a ‘reply-to’ topic being essential to see the translation response. As this hosted MQTT client is not carrying out all these necessary steps, the request will not be properly dealt with. However, evidence of the message arrival and processing of the content can be seen in the logs.
While the lightweight MQTT protocol does not explicitly define a request-reply mechanism, it can very easily be simulated using custom defined topics and headers. For further information on how you may build your own MQTT sender to properly implement the request-reply pattern to successfully get a translation response back to the MQTT sender, read the Request/Reply guide.
That’s the end of the tutorial. If you have any questions or comments, you can find me at solace.community.