Archive for the ‘Uncategorized’ Category

August Jam Session: “Introducing VoiceObjects 10 and VoiceObjects On-Demand”

Tuesday, August 17th, 2010

Join our upcoming developer jam session on August 26, 2010.

In this jam session, Stefan Besling will introduce VoiceObjects On-Demand, a major new capability in the upcoming VoiceObjects 10 release.

Now you can combine the power of the VoiceObjects environment with the convenience of Voxeo’s proven hosting infrastructure in a seamlessly integrated package.
Develop, deploy, and manage your apps more easily than ever before and use our new hosted application analytics to monitor traffic and understand caller behavior.

Date: Thursday, August 26, 2010

Time: 8:00 AM Western, 11:00 AM Eastern, 5:00 PM Central European

Developer Jam Session: Introducing VoiceObjects 10 and VoiceObjects On-Demand

Wednesday, August 4th, 2010

We would like to invite you to our upcoming jam session which is scheduled for August 26, 2010.

In this jam session, Stefan Besling will give you an introduction to VoiceObjects On-Demand, a major new capability in the upcoming VoiceObjects 10 release. Now you can combine the power of the VoiceObjects environment with the convenience of Voxeo’s proven hosting infrastructure in a seamlessly integrated package. Develop, deploy, and manage your apps more easily than ever before – and use our new hosted application analytics to monitor traffic and understand caller behavior.

Join us for this session on August 26, 2010

Time: 8:00 AM Western, 11:00 AM Eastern, 5:00 PM Central European

REGISTER NOW

FREE VoiceObjects training in Orlando: July 26-30th, 2010

Friday, July 2nd, 2010

We still have some space available in our next VoiceObjects training in Orlando (FL):

  • Voxeo VoiceObjects Overview – July 26-27th, 2010
  • Developing Voice Applications using VoiceObjects Desktop, July 28-30th, 2010

Both courses are free of charge, therefore reserve your spot soon! For more information and online registration please visit Voxeo University.

CU soon!

VoiceObjects Back-End Integration – Part III: CGI Connector

Friday, June 4th, 2010

In the first two parts of this series about back-end integration with VoiceObjects we have seen an overview of the different approaches that are available with VoiceObjects 9.1 as well as a detailed examination of the Java Connector. Now, in this third part, we will take a closer look at the CGI Connector.

Basics

The basic idea of the CGI Connector is that you implement an integration layer that provides an HTTP interface for the VoiceObjects Server. To communicate with the back-end system, the VoiceObjects Server sends an HTTP POST request to your integration layer, which talks to the beck-end and sends an HTTP response back to the VoiceObjects Server. The integration layer is typically deployed on a separate web server.

Deployment Diagram of a CGI Connector

As the communication between VoiceObjects Server and the integration layer is plain HTTP, there are no restrictions or constraints to use a specific programming language, framework, technology for the implementation of the integration layer (Java Servlets, PHP, Perl, ASP, …) – it’s completely up to you.

For the integration layer’s HTTP interface, two different CGI Connector options are available – an XML API and a simple plain HTTP mode.

  • XML API: In this mode, the VoiceObjects Server sends one single HTTP parameter called OVAPRequest, which contains an XML structure (request XML). This XML structure contains all parameters that are defined in the VoiceObjects Connector object. The response of the integration layer contains an XML structure (result XML) with all return values, error code, and error message. All of these will automatically be assigned to the appropriate objects in the VoiceObjects application. Request XML and result XML have a predefined structure (see the VoiceObjects Object Reference).
  • Simple HTTP mode: In this mode, the VoiceObjects Server sends each parameter that is defined in the VoiceObjects Connector object as a single HTTP POST parameter. The integration layer can return an arbitrary value (e.g. XML documents or plain text). The interpretation and/or parsing of this return value is left to the VoiceObjects application.

A very basic implementation of the integration layer using PHP and simple HTTP mode can look like this.

CGIConnector_basicSampleCode

This code expects 2 HTTP POST parameters – myFirstParam and mySecondParam. It just adds the values of both parameters and returns the sum as the result (as a single plain text result value).

How it works (using XML API)

Now, let’s take a look at how you can pass your parameters to your integration layer and retrieve the return values using the XML API.

First, you create your integration layer that accepts HTTP requests from the VoiceObjects Server, processes the parameters, communicates with your back-end system and returns result values (for XML API, a Java Servlet based framework is available that allows an easy implementation of the CGI layer – see below for an example).

Now, you create a Connector object in your VoiceObjects application that will use the integration layer. The following figure shows an example based using the CGI Connector in XML API mode.

Here are the key things you need in your Connector object (also see the documentation of the Connector object in the VoiceObjects Object Reference):

  • Location: a Resource Locator pointing at the location of your integration layer (e.g. http://myIntegrationServer/CGIConnector/)
  • File: the name of the CGI script, Servlet, JSP, ASP you are calling
  • Parameter Set: a list of parameters you want to exchange with your integration layer. For each parameter, enter the parameter ID that the integration layer is expecting in the Alias/Property filed. If you leave if empty, the Reference ID of your parameter object will automatically be sent as the parameter ID.

You also might want to set the HTTP connector timeout value. This defines the maximum time the Connector object will be waiting for a response from your integration layer. The default value is defined at the Service level. You can also access the HTTP status code if required by linking a Variable object to the Return value field. The status code will be assigned to that Variable object.

When the Connector object is executed in XML API mode, it sends an HTTP POST request to the URL that is constructed out of the values in the Location and File fields. The HTTP POST will contain one single parameter OVAPRequest and the value of that parameter will be an XML structure containing the parameters from your parameter list.

Here is an example request XML (for more information about the XML structures, please see the documentation of the Connector object in the VoiceObjects Object Reference):

<?xml version=”1.0″ encoding=”UTF-8″?>
<request>
<root>
<row>
<col name=”type”>expression</col>
<col name=”name”>dialogID</col>
<col name=”referenceID”>dialogID</col>
<col name=”value”><![CDATA[OVAPac16172d000000000000058e000000f490ffef8b]]></col>
</row>
<row>
<col name=”type”>expression</col>
<col name=”name”>ANI</col>
<col name=”referenceID”>ANI</col>
<col name=”value”><![CDATA[12345]]></col>
</row>
<row>
<col name=”type”>expression</col>
<col name=”name”>DNIS</col>
<col name=”referenceID”>DNIS</col>
<col name=”value”><![CDATA[4085371847]]></col>
</row>
<row>
<col name=”type”>variable</col>
<col name=”name”>Company Stock Symbol</col>
<col name=”referenceID”>stockName</col>
<col name=”value”><![CDATA[GOOG]]></col>
</row>
<row>
<col name=”type”>variable</col>
<col name=”name”>Stock Quote</col>
<col name=”referenceID”>stockPrice</col>
<col name=”value”><![CDATA[]]>
</col>
</row>
</root>
</request>

As you can see, there is one row element per parameter item. In addition to the parameter items that you define in your parameter set, the dialog ID, the ANI, and the DNIS of the current session will always be sent automatically. In the col element with name=”referenceID” you will find the name you entered in the Alias/Property field of your parameters. This is used to identify your parameters.

Now, the integration layer has to parse this XML structure, extract all values it needs to process the request and communicate with the back-end system and finally send a result XML containing the result values back to the VoiceObjects Server. This is an example for a result XML:

<?xml version=”1.0″ encoding=”UTF-8″?>
<result>
<root>
<row>
<col name=”referenceID”>stockPrice</col>
<col name=”value”><![CDATA[509.42]]></col>
</row>
</root>
<error>
<code>0</code>
<message>No error</message>
</error>
</result>

So in this case, the parameter with the referenceID stockPrice is returned to the Connector object which assigns the value to the Variable object in your parameter list accordingly (the one where we entered stockPrice in the Alias/Property field). In the error node, the result XML contains an error code and an error message. These are treated the same way as the error code and error message that we already saw with the Java Connector. The error codes 0 (Zero) and below 0 indicate that no error occurred. Values above 0 indicate an error and will trigger an Error-Connector in VoiceObjects. In the VoiecObjects application the error code and error message can be accessed using the Expression functions ERRORCODE and ERRORMESSAGE.

That were the basics of XML API mode.

How it works (using simple HTTP mode)

To use simple HTTP mode, you only have to check the Use simple HTTP mode check-box.

In simple HTTP mode, all parameters that are defined in the parameter set are sent as separate CGI parameters in the HTTP POST request. The name of the CGI parameter is defined by the Alias/Property field. So in this example, the name of the CGI parameter will be stockName containing the value of Variable object Company Stock Symbol. In simple HTTP mode, the parameter set is only used for the input parameters.

The content of the HTTP response is accessible via the Return value. If you link a Variable object to the Return value field, the complete content of the HTTP response will be assigned to this Variable. Depending on the interface of your integration code, this can be a single value (e.g. a number or a string) or some complex structure like XML or something similar. If this return value is an XML document, you can use the result mapping section to directly assign certain parts of your XML (e.g. node values or attribute values) to Variable, Collection, or Layer objects using XPath expressions.

A Sample Implementation Using Simple HTTP Mode

Now, let’s take a look at a first sample application using simple HTTP mode. We will re-use our sample application from VoiceObjects Back-End Integration Part II: Java Connector. The application asks for a company name, retrieves the stock quote for this company using a Connector and says the stock quote (the export of the VoiceObjects application can be found in the resources section at the end of this article).

This time we just use a CGI Connector to retrieve the stock quote instead of the Java Connector we were using last time. We will use the simple HTTP mode and implement our integration layer in PHP. Here is our PHP code (the source code can be found in the resources section at the end of this article):

Our integration layer expects a CGI parameter stockName and will just return one single value – the stock quote for this name that has been given. As we don’t have a real back-end system to connect to, we are just returning a random stock quote. In the real world you would get it from a database or from some other external system.

Here is the Connector object definition for our sample application:

The Resource Locator Connector Locator contains the base URL. Together with the content of the File field it defines the URL of our PHP script. The Connector has one single parameter in the parameter set – the input parameter stockName. The result of our PHP script is available in the Return value which is assigned to Variable Stock Quote. As the return value is the plain stock quote (i.e. no structured XML data), we don’t need any Result Mapping definition. Please note that the Use simple HTTP mode checkbox is checked.

A Sample Implementation Using XML API

Now we will take a look at a sample implementation using the XML API. For this purpose we will re-use another sample application form VoiceObjects Back-End Integration Part II: Java Connector. It will fetch multiple stock quotes at once which will then be presented using a List object (the export of the VoiceObjects application can be found in the resources section at the end of this article).

The basic idea is that it works based on a Collection of stock quotes. The Collection has the following format:

<root>
<row>
<col name=”name”>cmp1</col>
<col name=”fullname”>company1</col>
<col name=”price”>12.34</col>
</row>
<row>
<col name=”name”>cmp2</col>
<col name=”fullname”>company2</col>
<col name=”price”>9.12</col>
</row>
<row>
<col name=”name”>cmp3</col>
<col name=”fullname”>company3</col>
<col name=”price”>543.23</col>
</row>
</root>

The application sends a Collection with name and fullname columns filled but with empty price column to the CGI layer:

<root>
<row>
<col name=”name”>cmp1</col>
<col name=”fullname”>company1</col>
<col name=”price”></col>
</row>
<row>
<col name=”name”>cmp2</col>
<col name=”fullname”>company2</col>
<col name=”price”></col>
</row>
<row>
<col name=”name”>cmp3</col>
<col name=”fullname”>company3</col>
<col name=”price”></col>
</row>
</root>

The CGI layer iterates over all rows in the Collection, determines the stock quote for each company and writes it into price column accordingly. Then it returns the Collection containing the price info to the VoiceObjects application. In the VoiceObjects application, the List object is used to present the stock quote for each company in the Collection.

For the implementation of the CGI layer, the CGI Connector Framework that is part of the VoiceObjects distribution (see VoiceObjects Object Reference) is used. It provides an easy way to implement a Java Servlet based CGI integration layer for the XML API without having to worry about Servlets, JSPs, parsing XML, etc.  The actual source code of this example is part of your VoiceObjects installation and can be found in the Platform/Resources/CGIConnector/Sources/SampleConnector directory of your installation. The relevant part of the code is shown here (the full source code can be found in the resources section at the end of this article).

It just consists of a single Java class that extends ConnectorServlet (which is part of the framework) and implements a single method. This method gets a parameter map as an input parameter and returns a ConnectorResult. It uses the VOCollection utility class that is part of the framework to access the Collection data structure. This class is deployed in a Java Servlet container (e.g. Tomcat) and acts as our CGI integration layer.

Here is the Connector object definition for this sample application:

The Resource Locator Connector Locator together with the value from the File field again build the URL of our CGI integration layer. In this scenario we only have one single parameter in the Parameter Set, which is used as input and output parameter. The Stock List Collection is sent to the integration layer, which returns a modified version of the Collection. The new Collection definition is assigned to the Stock List Collection. As we are using XML API mode, the Use simple HTTP mode checkbox is unchecked.

Pros and Cons of the CGI Connector

Here is a quick overview of the Pros and Cons of the CGI Connector to help you assess if the CGI Connector is the adequate connector type for your use-case (for a direct comparison with the other connector types, please see VoiceObjects Back-End Integration – Part I: Overview).

Pros

  • Dedicated, decoupled integration layer: As the CGI Connector is executed in a separate web server, the integration layer is decoupled from the VoiceObjects Server. This gives you a dedicated integration layer that does not impact stability or performance of your VoiceObjects Server.
  • Full flexibility: As the communication between the VoiceObjects Server and your integration layer is plain HTTP, you have the choice to use the technology, the programming language, and any existing libraries for integration with your back-end system that you consider as appropriate.

Cons

  • Requires a web server: As the CGI Connector works via HTTP, a web server (e.g. Apache, Tomcat, IIS, etc.) is required for the deployment of your integration code.

Is the CGI Connector the Right Thing for me?

It is, if

  • you prefer a dedicated data access layer in your integration architecture
  • you want to have all options for the choice of programming languages, frameworks, libraries, etc for integration with your back-end system
  • you have to implement custom code for back-end integration and you don’t want to risk stability or performance of your VoiceObjects server instances

It is not, if

  • a web server is not an option in your integration architecture

Resources

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<request>
<root>
<row>
<col name=”type”>expression</col>
<col name=”name”>dialogID</col>
<col name=”referenceID”>dialogID</col>
<col name=”value”>
<![CDATA[OVAPac16172d000000000000058e000000f490ffef8b]]>
</col>
</row>
<row>
<col name=”type”>expression</col>
<col name=”name”>ANI</col>
<col name=”referenceID”>ANI</col>
<col name=”value”>
<![CDATA[12345]]>
</col>
</row>
<row>
<col name=”type”>expression</col>
<col name=”name”>DNIS</col>
<col name=”referenceID”>DNIS</col>
<col name=”value”>
<![CDATA[4085371847]]>
</col>
</row>
<row>
<col name=”type”>variable</col>
<col name=”name”>Company Stock Symbol</col>
<col name=”referenceID”>stockName</col>
<col name=”value”><![CDATA[GOOG]]></col>
</row>
<row>
<col name=”type”>variable</col>
<col name=”name”>Stock Quote</col>
<col name=”referenceID”>stockPrice</col>
<col name=”value”><![CDATA[]]>
</col>
</row>
</root>
</request>

Visit Voxeo at SpeechTEK Europe in London

Wednesday, May 19th, 2010

 

Visit Voxeo at booth #4 during SpeechTEK Europe in the Copthorne tara Hotel in London, May 26-27, 2010.

Get an update on Voxeo offerings including free developer solutions, leading multi-channel self-service capabilities and Unlocked Communications.

Get your free exhibit pass or a discounted conference pass.

Contact us to schedule  a meeting at SpeechTEK Europe.

Reserve Your All Access Pass for Voxeo’s Customer Summit 2010

Tuesday, May 11th, 2010

Register for Voxeo’s 2010 Customer Summit today!

  • Learn new ways to increase your competitive edge
  • Get an insider’s look at the product raodmap
  • Meet with Voxeo executives
  • Interact with your Customer Obsession Teams
  • Network with Industry experts

Register now for this Voxeo event on June 21-23,  2010 in the Hard Rock Hotel at Universal Orlando.

Join us for the Voxeo Customer Summit which is created for customers, partners, developers and other fans of Voxeo.

SPACE IS LIMITED. SAVE YOUR SEAT TODAY!

Join our Jam Session “Web Development with VoiceObjects for iPhone and other Mobile Browsers”

Wednesday, April 21st, 2010

In this session, Andreas Volmer will show how to create state-of-the-art mobile web applications, based on service configuration in the VoiceObjects Desktop environment, cascading style sheets, and customized rendering templates. Learn how to create web applications for the iPhone that look and behave similar to native apps.

Date: April 22, 2010
Time: 11:00 AM Eastern, 8:00 AM Western, 5:00 PM Central European

register-now

Webinar of the week “How To Transform Customer’s Experience While Driving Down Costs”

Tuesday, April 13th, 2010

Join us for our Business Webinar on April 15th, 2010.

Dan York, Director Conversations at Voxeo and Elizabeth Herrell, Vice President and Principal Analyst, Forrester Research, Inc. will talk about customer expectations on phone self-services, benefits of multi-channel strategies, and the usage of new channels such as social medias within the service offerings. Read More

register-now

Seats available: 5 days free VO9.1 overview and developer training

Tuesday, March 30th, 2010

In our additional VoiceObjects training classes scheduled for April in Cologne we still have some FREE seats available:

  • Voxeo VoiceObjects Overview, April 12-13
  • Developing Voice Applications using VoiceObjects Desktop, April 14-16

For more information and online registration – first come first served! – check our website or send an email to university@voxeo.com.

VoiceObjects Back-End Integration – Part II: Java Connector

Wednesday, March 24th, 2010

In the first part of this series about back-end integration with VoiceObjects we have seen an overview of the different approaches that are available with VoiceObjects 9.1. Now, in this second part, we will take a closer look at the Java Connector.

Basics

The basic idea of the Java Connector is that you implement a Java class for back-end integration. This Java class is instantiated directly by the VoiceObjects Server instance (i.e. it is running in the same Java Virtual Machine as the VoiceObjects Server instance), and the VoiceObjects Connector object of your VoiceObjects dialog implementation directly uses instances of your custom Java class.

BackendIntegration_Deployment_JavaConnector

Your Java class has to follow some conventions to allow the VoiceObjects Server to use it (your class does not have to implement any specific interface or extend any specific super-class).

  • It has to be a Java Bean that provides public set methods for your input parameters and public get methods for your return parameters.
  • All parameters (input and return parameters) have to be of type String (java.lang.String).
  • Your Java Bean also needs to have one public business method – a method that performs the actual back-end access. The business method typically uses the Bean properties containing the input parameters (the ones that have been set using the set methods) and it populates the Bean properties containing the return parameters (the ones that will be read using the get methods).
  • The business method must not have any parameters (it solely operates on the parameters that are set using the set methods).

For error handling, you can implement two additional get methods (in addition to the methods for your return parameters) – getErrorCode and getErrorMessage. Both methods have to return a String – the return value of getErrorCode is actually a number in wrapped in a String. The error codes “0″ (Zero) and below 0 indicate that no error occurred. Values above 0 indicate an error and will trigger an Error-Connector in VoiceObjects. In the VoiecObjects application the results of getErrorCode and getErrorMessage can be accessed using the Expression functions ERRORCODE and ERRORMESSAGE. It is important to catch all Exceptions that might occur in your Java code. It is not recommended to propagate any Exceptions from your Java code to the VoiceObjects Server instance. For error handling, please use error code and error message as explained above.

So a very basic implementation can look like this.

Java_Connector_basicSampleCode2

The basic idea is, that first the VoiceObjects Server (based on the definition of the Connector object in your VoiceObjects application) will call the set methods of your class to set the input parameters for your back-end access. Then the VoiceObjects Server will call your business method. And lastly it will call the get methods to retrieve the return values (as well as error code and error message).

JavaConnectors_SequenceDiagram_concept2

How it works

Now, let’s take a look at how you can pass parameters from your VoiceObjects application to your Java class, call your business method, and retrieve the return values for further processing in your VoiceObjects application.

First, you need to compile your Java class and create a jar file containing your class (and all your other custom classes that might be needed by your business method).

Now, you create a Connector object in your VoiceObjects application that will use your Java class. The following figure shows an example based on the basic Java sample code above.

JavaConnector_objectEditor

Here are the key things you need in your Connector object (also see the documentation of the Connector object the VoiceObjects Object Reference Guide):

  • Location: a Resource Locator pointing at the location of your jar file (HTTP or file URL)
  • File: the filename of your jar (if you need more than just one jar, you can provide a comma-separated list of filenames – only use comma as a separator – no spaces)
  • Class/Port: the fully qualified class name of your Java Bean
  • Method: the name of the business method in your Java Bean
  • Parameter Set: the list of parameters you want to exchange with your Java Bean. In the Alias/Property field you have to specify the name of the Java Bean property (following the Java Bean conventions). Example: If your get method is called getAResultValue(), in the Alias/Property field you have to specify aResultValue. To pass parameters to your Java code using set methods, you can use Variables, Collections, Expressions, Layers, Scripts, Resource Locators, or constants. In either case you will receive a String on the Java side. Return parameters from your Java code (retrieved using the get methods) can be assigned to Variables, Layers, or Collections. In either case the get method has to return a String (i.e. to return a Collection your get method needs to return the Collection’s XML representation in a String).

When the VoiceObjects Connector object is executed, the VoiceObjects Server performs the following steps:

  1. Iterate over all parameters in the parameter set and check for each parameter if the Java Bean provides a set method. If so, the set method is called and the value of the parameter field is passed as an argument of type String.
  2. Call the business method of the Java Bean.
  3. Iterate over all parameters in the parameter set and check for each parameter if the Java Bean provides a get method. If so, the get method is called and the return value is stored in the corresponding Variable, Layer, or Collection object.

So in our example, this is what happens:

JavaConnectors_SequenceDiagram_basicExample2

This assumes your Java Bean object has already been instantiated. So the question is: when is it instantiated and is it shared between sessions? The answer is simple: It’s up to you. This can be controlled using the Class persistence level field of the Connector object. Your options are:

  • None: A new object is created every time the Connector object is executed.
  • Dialog: A new object is created the first time in each dialog session the Connector object is executed. Subsequent connector executions in this session (i.e. in the same dialog) will re-use the existing instance.
  • Service: A new object is created the first time the Connector object is executed for your service. Subsequent connector executions for this service will re-use the existing instance (i.e. it will be shared by all sessions for this service).
  • Server Instance: A new object is created the first time the Connector object is executed for your VoiceObjects server instance. All subsequent executions of this connector on this server instance will re-use the existing instance (i.e. it will be shared by all sessions for all services on this server instance).

If you are using class persistent level Service or Server Instance you have to make sure that your Java code is thread-safe, as multiple threads will be using the same instance of your Java class in parallel.

A Simple Sample Implementation

Now, let’s take a look at a first sample application. Our sample application is going to ask for a company name and will present us the latest stock quote for this company. Here is our simple dialog structure (the export of the VoiceObjects application can be found in the resources section at the end of this article).

JavaConnector_sampleApp1_dialog

The application is pretty simple – we ask for a company name, retrieve the stock quote using a Connector and say the stock quote.

Our Java Bean provides the following methods for retrieval of the stock quotes (the full source code can be found in the resources section at the end of this article):

Java_Connector_sampleCode_singleStockQuote

So there is one input parameter – companyName – the name (i.e. the stock symbol) of the company, and there is only one return parameter – stockQuote – the last stock quote for the given company name. Out business method is called execute and we also have the usual methods for accessing error code and error message. The Java code of this sample implementation will not connect to a real back-end system. Instead it reads the stock quotes from a properties file on the local disk. To be able to use this connector code, we compile the Java code and create a jar file called sample_java_connector.jar. In our sample implementation the jar file also contains the properties file with the stock quotes (the jar file can also be found in the resources section below).

Based on our Java Bean, this is our Connector object definition:

JavaConnector_sampleApp1_connector

We just have to make sure that our jar file is available at the location that is defined in Connector Locator. When the Connector object is executed, the setCompanyName method is called (this is the only set method that is called, our Java Bean does not define a set method for stockQuote). Then our business method execute is called, and finally the getStockQuote method is called retrieve the stock quote and assign it to the corresponding Variable object.

This sample implementation only uses data types that do not require any parsing or special processing (i.e. no Collections are used). In the next example we will take a look at how you can work with Collections in your Java connector.

A Sample Implementation using Collections

To illustrate the usage of Collections in a Java connector, we will extend our sample application a bit. It will now fetch multiple stock quotes at once which will then be presented using a List object. Here is our dialog structure (the export of the VoiceObjects application can be found in the resources section at the end of this article):

JavaConnector_sampleApp2_dialog

The basic idea is that it works based on a Collection of stock quotes. The Collection has the following format:

<root>
<row>
<col name=”name”>cmp1</col>
<col name=”fullname”>company1</col>
<col name=”price”>12.34</col>
</row>
<row>
<col name=”name”>cmp2</col>
<col name=”fullname”>company2</col>
<col name=”price”>9.12</col>
</row>
<row>
<col name=”name”>cmp3</col>
<col name=”fullname”>company3</col>
<col name=”price”>543.23</col>
</row>
</root>

There is one row per company containing three columns – the name (i.e. the stock symbol), the full company name, and the stock price.

So for this application, we create a Java Bean that provides the following methods for the retrieval of stock quotes:

Java_Connector_sampleCode_multipleStockQuotes

The Collection (with empty values for the price column) is set as an input parameter using the method setStockList (just like a Variable or any other VoiceObjects type, on the Java side it appears as a String). The execute method will iterate over all rows of the Collection, determine the latest stock quote (again based on a simple look-up in the properties file) and will fill in the stock quotes into the price column. The method getStockList will return a String containing the Collection’s XML.

To implement the processing of the Collection on the Java side (parsing the XML, manipulating cell contents, generating XML), you can use a utility class that is part of your VoiceObjects installation. The jar file is called ConnectorUtil.jar and resides in the directory Platform/Resources/CGIConnector/WEB-INF/lib/ of your VoiceObjects installation. The class that is relevant here is com.voiceobjects.connector.util.VOCollection. A JavaDoc documentation can be found at Platform /Resources/CGIConnector/doc/. This is the relevant part of the sample code that processes the Collection:

Java_Connector_sampleCode_Collections

As you can see, the VOCollection class encapsulates the XML processing and allows easy access and manipulation of the Collection.

Here is the VoiceObjects Connector object definition for out sample applicaiton that retrieves multiple stock quotes:

JavaConnector_sampleApp2_connector

In this case there is only one single parameter – the Collection StockList - that is used as input and output parameter. This is also an example for the usage of more than one jar file (as our code relies on ConnectorUtil.jar). So we have to make sure both jars are available at the location that Connector Locator is pointing to.

Class Loading and Versioning

As your custom Java classes are executed inside the same Java Virtual Machine as the VoiceObjects Server instance, changing your jar files requires a restart of your VoiceObjects Server instances. There is a way to monitor the jar files and to dynamically reload them when they were changed (see VoiceObjects Object Reference Guide). However, this is not recommended in production environments, as it will impact performance.

To avoid the need for restarting, you can use names for jar files and for java packages that reflect the versioning of your Java Connectors. Example:

The jar file could be called sample_java_connector.v1.jar and the package contained in this file could be called com.voxeo.connector.sample.v1. So if you make changes to your Java implementation, you increment the version numbers in your jar file as well as in your package name. You adapt the definition of the VoiceObjects Connector object accordingly and you can deploy a new version of your application without restarting the server instances. The old classes will still be loaded, but they won’t be used anymore.

Pros and Cons of the Java Connector

Here is a quick overview of the Pros and Cons of the Java Connector to help you assess if the Java Connector is the adequate connector type for your use-case (for a direct comparison with the other connector types, please see VoiceObjects Back-End Integration – Part I: Overview).

Pros

  • No communication overhead: As the Java Bean is executed in the same JVM as the VoiceObjects Server instance, the communication between these components are plain Java method invocations. There is no additional communication overhead like HTTP requests, assembling and parsing XML, etc. This allows high performance and low latency implementations.
  • Simple architecture: The Java Connector does not require any additional components (e.g. application servers, middleware, etc) for back-end integration. This results in a simple 2-tier architecture.

Cons

  • Impact on VoiceObjects Server instance: As the Java Bean is executed in the same JVM as the VoiceObjects Server instance, the performance of the custom Java code can have a negative impact on the VoiceObjects Server. This holds for memory consumption (if your Java code requires a significant amount of main memory, you have to take this into account in the memory configuration of your VO Server), impact on garbage collection (if your Java code creates a lot of objects, this might lead to increased garbage collection, which might have a negative impact on the response times of the VO Server), CPU load, and code stability (unstable code might negatively impact the stability of the VoiceObjects Server).
  • Class loading for new versions: If your Java code changes frequently, you will either have to restart your VoiceObjects Server instances from time to time to load the new classes or you have to follow the naming convention that includes version numbers in jar and package names to avoid restarting.

Is the Java Connector the right Thing for me?

It is, if

  • you want to avoid any communication overhead
  • HTTP(S) communication for back-end integration is not allowed
  • you want to implement your back-end integration in Java
  • you don’t want to have a 3-tier architecture with a dedicated data-access layer

It is not, if

  • Java programming is not an option
  • your integration code requires a significant amount of main memory, creates a large number of objects, or uses a large number of threads
  • your integration code depends on a large number of external jar files
  • you are concerned about the quality of your integration code (as bad integration code in a Java Connector can have negative effects on the stability of your VO Server)
  • your integration code is not under your control (e.g. if you are building a hosting platform and your clients will write their own back-end integration code)
  • your integration code changes frequently

Resources