Developing your own server-side push initiator

Before you start developing your server-side push initiator, consider the following:

  • Whether the server-side push initiator uses the BlackBerry Internet Service, the BlackBerry Enterprise Server, the BlackBerry Device Service, or all three as the PPG
  • The maximum number of push request messages that the server-side push initiator might send to the PPG per day
  • The maximum size of the file or content that the server-side push initiator might include in a push request message

To use the BlackBerry Internet Service as the PPG, you must register with BlackBerry, and users must have a data plan with their service provider that provides a connection to the Wi-Fi network or mobile network.

To use the BlackBerry Enterprise Server or the BlackBerry Device Service as the PPG, a user must be activated on the BlackBerry Enterprise Server or the BlackBerry Device Service to receive push messages. In this environment, at least one instance of the BlackBerry MDS Connection Service in an organization's BlackBerry Domain acts as the PPG and uses push technology to deliver push messages to BlackBerry device users.

Using the low-level APIs

You can access the low-level APIs through the Commons and Push Access Protocol (PAP) components. These APIs create a simple and effective Java API layer on top of PAP XML so that you don't need to write and parse PAP XML and multipart MIME messages.

For more information about the APIs, see the low-level API reference.

Technology stack

The following diagram shows you the technologies that make up a push solution and where the Commons and PAP components that contain the low-level APIs are located in the stack.

Low_level_tech_stack_2

Files to include in your classpath

You should include all of the files from the following pushsdk-low-level subfolders in your classpath: components, configuration, and dependencies-lib.

You don't have to use the Spring Framework. If you decide not to use the framework, you don't need to include the Spring Framework library files from the dependencies-lib folder or the Spring context XML files from the configuration folder.

How to use the APIs

The following sections provide details about using the PAP functionality in the low-level APIs to develop your server-side push initiator. You should also look at the source code for the low-level sample server-side push initiator because it provides examples that you can use to develop your server-side push initiator. You can find the source code in the following location: pushsdk-low-level\low-level-sample\low-level-sample-1.2.x.xx-sources.jar.

Sending a push message

Before you send a push message, you need the following items:

  • A username and password that the PPG authenticates. If you're using the BlackBerry Internet Service as the PPG, the username is the application ID and the password is the app password. If you're using the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG, the username and password depends on whether the PPG is configured to authenticate each push message. Check with your administrator to see if you need a username and password.
  • The destination of the push message. If you're using the BlackBerry Internet Service or BlackBerry Device Service as the PPG, the destination is the application ID. If you're using the BlackBerry Enterprise Server as the PPG, the destination is a null value if you're sending the push message to the browser or the port on the BlackBerry device that receives push messages.
  • The information for the fields that are required by the PushMessageControl class, such as the list of addresses that the push messages should be sent to.
  • The content for the push message. For more information, see the implementations of the Content abstract class in the Commons component.

Here's a code sample that shows you how to send a push message when you use the BlackBerry Internet Service as the PPG:

PushMessageControl pushMessageControl = new PushMessageControl(
  PPGType.PUBLIC_PUSH);

Content content = new TextContent("My content to push");

PushResponse response = papService.push(pushApplicationId, password, 
  pushApplicationId, pushMessageControl, content);
if(response.getCode() == StatusCode.ACCEPTED) ...

For more information about sending a push message, see the push() method of the PapService interface.

Status of a push message

The push() method of the PapService interface returns an instance of the PushResponse class, which contains the outcome of the push request. You should pay attention to the ResponseResult object because that class contains the status code that indicates whether the push request was accepted by the PPG for further processing. If the status code indicates that the push message wasn't accepted, you might need to send the push message again.

The status code doesn't indicate the delivery status of a push message to each of the addresses that you specified. You must query the status of a push message or receive a result notification for that purpose.

Querying the status of a push message

A status query lets you examine the delivery status of a push message to each subscriber. You should wait a few minutes after you send a push message for the message to be fully processed before you try to perform a status query.

You can query the status of a push message if your app uses the BlackBerry Internet Service as the PPG and has a service level of Push Plus, or if your app uses the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG.

Before you query the status of a push message, you need the following items:

  • A username and password that the PPG authenticates. If you're using the BlackBerry Internet Service as the PPG, the username is the application ID and the password is the app password. If you're using the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG, the username and password depends on whether the PPG is configured to authenticate each push message. Check with your administrator to see if you need a username and password.
  • The information for the fields that are required by the StatusQueryMessageControl class, such as the push ID associated with the PAP control and the list of addresses that you want to query the status for. To query the status for all of the addresses that the message was sent to, you can specify null for the list of addresses.

The object that is returned by the status query is an instance of the StatusQueryResponse class. The instance contains a list of results as StatusQueryResult objects.  Each result indicates a delivery status that is current at the time of the query and the addresses that have the delivery status. For a complete list of delivery statuses, see the MessageState class.

Here's a code sample that shows you how to query the status of a push message when you use the BlackBerry Internet Service as the PPG:

StatusQueryMessageControl statusQueryMessageControl = new 
  StatusQueryMessageControl(PPGType.PUBLIC_PUSH);
    
StatusQueryResponse response = papService.statusQuery(
  pushApplicationId, password, statusQueryMessageControl);

For more information about performing a status query, see the statusQuery() method of the PapService interface.

Canceling a push message

The cancel operation lets you try to cancel a push message that you sent to all subscribers or a subset of those subscribers. A BlackBerry device must be out of coverage range for at least ten minutes before you can successfully cancel a push message to the subscriber.

Before you cancel a push message, you need the following items:

  • A username and password that the PPG authenticates. If you're using the BlackBerry Internet Service as the PPG, the username is the application ID and the password is the app password. If you're using the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG, the username and password depends on whether the PPG is configured to authenticate each push message. Check with your administrator to see if you need a username and password.
  • The information for the fields that are required by the CancelMessageControl class, such as the push ID associated with the PAP control, and the list of addresses that you want to cancel the push message for. To cancel the push message for all of the addresses that it was sent to, you can specify null for the list of addresses.

Here's a code sample that shows you how to cancel a push message when you use the BlackBerry Internet Service as the PPG:

CancelMessageControl cancelMessageControl = new CancelMessageControl(
  PPGType.PUBLIC_PUSH);

CancelResponse response = papService.cancel(pushApplicationId, 
  password, cancelMessageControl);

For more information about performing a cancel operation, including a code sample, see the cancel() method for the PapService interface.

Handling result notifications

A result notification is a message that the PPG sends that indicates the final delivery status of a push message.

Using the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG

You must specify a full notify URL as the value for the ppgNotifyRequestedTo parameter when you construct the PushMessageControl object that is passed into the push() method. You specify the URL in the form https://<content_provider_domain>/notification). The URL is the domain where result notifications are sent.

Result notification servlet

The BasicNotificationServlet class is included with the PAP component in the net.rim.pushsdk.pap.web package. To correctly handle result notifications, you must write a servlet that extends the BasicNotificationServlet class. In your servlet, you must provide an implementation of the getPapService() method. This method must return an instance of a class that implements the PapService interface.

The default implementation of the PapService interface is the PapServiceImpl class. The default implementation of the onNotification() method in PapServiceImpl is a no-op implementation. To handle result notifications in a way that's appropriate for your environment, you might want to extend the default implementation of PapServiceImpl and write your own implementation of onNotification(). For example, when you receive a result notification, you could update the status of a push request in persistent storage.

For more information about the default behavior, see the BasicNotificationServlet class.

Querying the status of a subscriber on the PPG

If you're using the BlackBerry Internet Service as the PPG, you can query the status of a subscriber on the PPG. This approach can be useful if you think the status of a subscriber on the PPG might have changed (for example, from active to unsubscribed). For more information, see the SubscriptionQueryService interface.

Using the high-level APIs

You can access the high-level APIs through the Core, Acknowledgement, and Monitoring components. The high-level APIs are built on top of the low-level APIs that are in the Commons and PAP components. The advantage of using the high-level APIs is that a lot of the major implementation of the server-side push initiator is taken care of for you. You need to focus only on generating the content that you want to deliver in push messages and specifying the subscribers that receive the content.

For more information about the APIs, see the high-level API reference.

Technology stack

The following diagram shows you the technologies that make up a push solution, and where the Core, Acknowledgement, and Monitoring components that contain the high-level APIs are located in the stack.

High_level_tech_stack_2

Files to include in your classpath

You should include all of the files from the following pushsdk-high-level subfolders in your classpath: components, configuration, and dependencies-lib.

You can store Push Service SDK data in system memory instead of in a database by changing the dao.type property in the PushSDK.properties file. For more information about changing the property, see Specify the configuration properties for the database.

If you decide to use system memory, you don't need to include the commons-dbcp and commons-pool libraries from the dependencies-lib folder, or the mysql.properties, oracle.properties from the configuration folder.

How to use the APIs

The following sections provide details about using the high-level APIs to develop your server-side push initiator. You should also look at the source code for the high-level server-side push initiator sample because it provides examples that you can use to develop your server-side push initiator. You can find the source code in the following path: pushsdk-high-level\high-level-sample\high-level-sample-1.2.x.xx-sources.jar.

Managing a push-enabled app

To add, update, list, and perform other actions for a PushApplication object, see the methods for the PushApplicationService interface. A PushApplication object represents the details and attributes of a push-enabled app. A push-enabled app is installed on a BlackBerry device, and receives push messages.

Handling subscriptions

Subscriber IDs

Subscribed users are identified using a subscriber ID. The advantage of using subscriber IDs instead of device PINs is that the SDK provides an extra layer of abstraction that allows users to change devices without you having to change the addresses to send push messages to. The SDK handles the mapping between IDs and PINs for you. You need to decide what value to give to the subscriber ID (for example, an email address, a unique ID used by one of your existing systems, or some other identifier).

You also need to have a way to authenticate and translate a username and password to a user’s subscriber ID in a subscribe request. The SDK supports container-managed authentication or programmatic authentication through callbacks. To use programmatic authentication through callbacks, you need to implement the ContentProviderAuthenticationService interface, and point to your implementation by changing the class attribute of the contentProviderAuthenticationService Spring bean in pushsdk-subscription-context.xml.

Subscription servlets

You should use the subscription servlets that are provided with the SDK to subscribe, unsubscribe, resume, and suspend users. The servlets are SubscribeServlet, UnsubscribeServlet, ResumeServlet, and SuspendServlet. To see the request parameters that these servlets take and their return codes, see the net.rim.pushsdk.subscription.web package.

When you call a subscription servlet, the SDK performs its own subscription operations in the background. You can provide additional code that runs when a subscribe, unsubscribe, resume, or suspend operation succeeds or fails by implementing the ContentProviderSubscriptionService interface, and pointing to your implementation by changing the class attribute of the contentProviderSubscriptionService Spring bean in pushsdk-subscription-context.xml.

Queries

To see how to query for subscribers using different parameters, such as application ID and status, see the SubscriptionService interface.

To see how to query the status of a subscriber on the PPG if you're using the BlackBerry Internet Service as the PPG, see the SubscriptionQueryService interface. These queries can be useful if you think that the status between the subscriber record on the PPG and the SDK might be out of sync.

Forcing a sync

To see how to force a sync of the status of a subscriber between the PPG and SDK, see the SubscriptionService interface. The API reference also includes the rules that determine the final status of a subscriber when the PPG and SDK are out of sync. If your PushApplication object has a service level of Push Essentials, you should perform a sync regularly to keep the PPG and SDK current.

If your PushApplication object has a service level of Push Plus, you don't need to sync the PPG and SDK as often. Only a PushApplication object with a type of PUBLIC_PUSH (including mixed types such as PUBLIC_AND_BDS_PUSH) can use this functionality. Additionally, for mixed types with PUBLIC in them, only subscribers on PPGs that use the BlackBerry Internet Service are involved in the syncing process.

Sending a push message

To send a push message, you need the ID of the push-enabled app and the list of subscribers that you're sending the push message to, along with the content that you want to send to the subscribers. For more information, see Managing a push-enabled app and Handling subscriptions, and the implementations of the Content abstract class in the Commons component.

The push() method in the PushService interface returns an instance of the PushResult class, which contains the outcome of the push request. You should pay attention to the failedPushResults set in the PushResult class. The failedPushResults set contains a list of subscriber IDs that you couldn't send a push message to, and the reason (in a status code) why the push message wasn't delivered.

You should review the list in the set when deciding which subscribers to send a push message to again. The other sets in the PushResult class list which subscribers you can't send a message to because they don't exist in the system, or they're inactive or suspended. For more information about the available sets, see the PushResult class.

Here's a code sample that shows you how to send a push message:

Content content = new TextContent("My content to push");

PushParameters pushParameters = PushParameters("myApplicationId", 
  "subscriberId1", content);

PushService pushService = <obtain instance of PushServiceImpl...>

PushResult pushResult = pushService.push(pushParameters);

if(pushResult.getCode() == StatusCode.ACCEPTED) ...

For more details about sending a push message, see the push() method in the PushService interface.

Querying the status of a push message

A status query lets you examine the delivery status of a push message to each subscriber. You should wait a few minutes after you send a push message for the message to be fully processed before you try to perform a status query.

Depending on the delivery status that is returned by the status query, you might want to try sending the push message again if the delivery status is EXPIRED or UNDELIVERABLE. For a complete list of delivery statuses, see the MessageState class.

Here's a code sample that shows you how to query the status of a push message:

PushService pushService = <obtain instance of PushServiceImpl...>

StatusResult statusResult = pushService.statusQueryAll(
  "myApplicationId", pushResult.getPushId(), "subscriberId1");

For more information about performing a status query, see the statusQuery() methods for the PushService interface.

Canceling a push message

The cancel operation lets you try to cancel a push message that you sent to all subscribers or a subset of those subscribers. A BlackBerry device must be out of coverage range for at least ten minutes before you can successfully cancel a push message to the subscriber.

Here's a code sample that shows you how to cancel a push message:

PushService pushService = <obtain instance of PushServiceImpl...>

CancelResult cancelResult = pushService.cancel("myApplicationId", 
  pushResult.getPushId(), "subscriberId1");

For more information about performing a cancel operation, see the cancel() methods for the PushService interface.

Handling result notifications

A result notification is a message that the PPG sends that indicates the final delivery status of a push message. Only apps that have a service level of Push Plus can receive acknowledgments (result notifications).

Using the BlackBerry Internet Service as the PPG

If you want to handle result notifications, you need to provide a base notify URL when you register with BlackBerry to use the Push Service. On the registration page, you need to select the Push Plus service level in the Push Service Type drop-down list, and then type the base notify URL in the form https://<content_provider_domain>. The URL is the domain where response notifications are sent.

You need to specify the remaining suffix of the notify URL (for example, /notification) as the value of the publicNotifyUrl parameter for the PushApplication object when you add your push-enabled app using the addPushApplication() method for the PushApplicationService interface.

Using the BlackBerry Enterprise Server or BlackBerry Device Service as the PPG

You need to specify a full notify URL as the value of the enterpriseNotifyUrl or bdsNotifyUrl parameter for the PushApplication object when you add your push-enabled app using the addPushApplication() method for the PushApplicationService interface. You specify the URL in the form https://<content_provider_domain>/notification.

Result notification servlet

The NotificationServletis included in the Acknowledgement component that you can use to receive and process an incoming result notification, and return a response to the PPG.

When the PPG calls the NotificationServlet, the Push Service SDK performs its own processing in the background. You can provide your own code that is executed if the incoming result notification indicates that the push message succeeded or failed. You can write your code by extending SuccessNotificationListener, FailureNotificationListener, or AnyNotificationListener, and by writing your own implementation of the processNotification() method. Add your new listener implementations as Spring beans to pushsdk-acknowledgement-context.xml.

You also need to register the listeners by uncommenting the registerListeners bean at the bottom of pushsdk-acknowledgement-context.xml, replacing ${appid} with your application ID, and then referencing your own listener beans between the <list> </list> tags.

Detecting the last result notification

The LastNotificationListener class detects when the last result notification is returned for a push message. You can use this listener only with a PushApplication object that has the lastNotificationEnabled parameter to true.

The LastNotificationListener class is important because push messages are not guaranteed to be delivered in order. If you need to deliver push message in a particular order, this listener can help you determine when the previous push message was received by the devices, and when the next push message in the sequence should be sent.

By extending the LastNotificationListener class and providing your own implementation of the processNotification() method, you can perform a final action after you receive all of the result notifications for a push message. Note, however, that when you set the lastNotificationEnabled parameter set to true, there is a slight performance penalty associated with the parameter.

The Commons component

The Commons component contains APIs that can be shared across the other components of the server-side library. The Commons component contains base classes, base exceptions, utility classes, and helper classes. The database schema files are also located in the Commons component.

The classes and exceptions in this component provide APIs for:

  • Modeling the content that you deliver to users in a push message
  • Handling root level exceptions and HTTP client implementation
  • Validation
  • String manipulation
  • Data manipulation
  • Random data generation

The Commons component contains the commons package.

The PAP component

The PAP component contains the APIs to handle PAP messages, such as creating and sending PAP messages, and receiving and parsing PAP messages. The component also provides the APIs that you can use to make push message status and subscription status queries to the PPG.

The PAP component contains the pap and query packages.

The pap package

The pap package contains the APIs to create, send, receive, and parse PAP messages. The pap package includes:

  • Classes that represent the PAP status codes
  • PAP control objects
  • A servlet that unmarshals the result notification messages and sends the confirmation to the PPG
  • Enums that represent the PAP message state and message reliability
  • An exception that handles the rejection of PAP messages by the PPG

The pap package hides the details of the PAP and MIME messaging. Instead of using PAP XML directly, you can use the Java interface that is available in this package to develop and test your apps.

The pap package offers low-level APIs that are flexible to use and give you greater control over implementation. For a high-level API that offers many extra services, you can use the push package that is included in the Core component instead.

The query package

The query package contains the APIs to query the PPG for subscription status using XML messages in a format that is specified by BlackBerry. The query package includes:

  • Classes that represent the subscription query request messages and subscription query response messages
  • Enum values that represent subscription statuses
  • A class that unmarshals the subscription query response messages into Java objects
  • An exception that handles the rejection of subscription query request messages by the PPG

The Core component

The Core component contains the APIs to manage all aspects of delivering content using push technology, including the following:

  • Managing push messages
  • Managing subscriptions
  • Managing attributes of the push-enabled apps

The Core component contains the push, pushappmgmt, and subscription packages.

The push package

The push package contains the APIs to perform the following actions:

  • Validate and send push request messages
  • Cancel previously submitted push request messages
  • Query the status of previously submitted push request messages
  • Store the status of a push request message locally

The push package is designed as a layer on top of the pap package. The push package provides simple PAP messaging capabilities similar to those that are available in the pap package. The push package provides extra services such as validation, persistence, and smart defaulting for common attributes of a push request. Without persistence, you can query the Push Service for the status of a push request message only up to 24 hours after the Push Service receives the push request message. Persistence lets you query your local database for the status of a push request message any time in the future as long as you store the status of the message.

The push package is designed to hide the use of PAP. It is also designed to let you use subscriber IDs instead of BlackBerry device PINs or email addresses when you use the SDK APIs. APIs for mapping subscriber IDs to device PINs or email addresses are also available. The advantage of using subscriber IDs instead of device PINs is that the SDK provides an extra layer of abstraction that allows users to change devices without you having to change the addresses to send push messages to. The SDK handles the mapping between IDs and PINs for you.

The push package keeps statistics on the number of push request messages that were successfully accepted by the PPG.

The pushappmgmt package

The pushappmgmt package provides the APIs to:

  • Manage the attributes for your client-side push-enabled app
  • Store the records that are related to the attributes in storage
  • Specify the type of the server-side push initiator
  • Add, update, enable, disable, delete, or query for push-enabled apps using the attributes

By managing the attributes of the push-enabled app, the pushappmgmt package enables the method that sends the push request message (located in the push package) to use only the application ID to retrieve records that are related to the attributes of the push-enabled app from storage. Additionally, other attributes (such as the password, default time to live, and default reliability) can be included automatically as part of the push request message instead of passing these values through the APIs on every push request call.

In a server-side push initiator, a push-enabled app object is represented by an instance of the net.rim.pushsdk.pushappmgmt.PushApplication class.

The subscription package

The subscription package contains the APIs to handle the following subscription-related operations:

  • Subscribe
  • Unsubscribe
  • Suspend
  • Resume
User authentication

Subscription-related operations are handled by servlets. When a request for one of these operations is received by the specific servlet, the information that is received with the request is validated, processed, and then saved to storage. If you're not using container-managed security, the subscription package can provide your server-side push initiator with the functionalities to authenticate users as well as handle exceptions related to authentication.

You can customize the user authentication process to use extra properties in addition to the username and password. You can also take custom actions on subscribe, unsubscribe, resume, and suspend events. Usernames and passwords can support international characters if configured through the HTTP header or the app server configuration settings.

Managing subscribers

The subscription package includes find methods and methods to retrieve counts and statistics to manage subscribers and for reporting purposes. The subscription package also tries to automatically detect when a subscriber to the push-enabled app changes, and unsubscribes the old user to be safe. This change might occur when a user changes the SIM card or gives their device to someone else.

Validating subscriptions

The subscription package also contains APIs for validating subscriptions. The push package uses these APIs to prevent submitting push request messages to inactive, suspended, or nonexistent subscribers.

The Acknowledgement component

The Acknowledgement component contains the APIs to perform the following actions:

  • Manage result-notification request messages and result-notification response messages, collectively referred to as acknowledgments
  • Listen for result-notification request messages from the PPG regarding the successful or unsuccessful delivery of push request messages to BlackBerry devices
  • Reconcile the result-notification request messages with the push-request message details in storage
  • Send result-notification response messages to the PPG confirming the delivery of the result-notification request messages
Dependencies on other components

The Acknowledgement component depends on the PAP, Push, and Subscription components in the following ways:

  • The Acknowledgement component uses the PAP component to parse the PAP XML of the result-notification request messages and to construct the PAP XML of the result-notification response messages.
  • The Acknowledgement component uses the Push component to reconcile result-notification request messages with the push-request message details in the persistent store. Reconciliation allows the SDK to record, in storage, the delivery status of a push message for each subscriber the message was sent to.
  • The Acknowledgement component uses the Subscription component to map addresses in the PAP messages (for example, mapping the PINs to subscriber IDs).
Using the component

You can use the Acknowledgement component in one of three different ways.

  1. To listen to and parse the acknowledgments into simple Java objects that can be passed to a server-side push initiator, which uses the SDK server-side library for further processing of the objects.
  2. To listen to, parse, and reconcile the acknowledgments using only the SDK server-side library so that any user of the library can call one of the query APIs to get the status of a push request message.
  3. To listen to and reconcile the acknowledgments using the server-side library, and also to notify several client-side push-enabled apps that process certain types of notification messages based on the status code of the messages: success, failure, any, or last notification from the original push request.

    By using the component in this way, you can subclass the listener classes in the SDK server-side library to create custom implementations of the methods, and to further process the acknowledgments in your server-side push initiator.

The Monitoring component

The Monitoring component provides the APIs for you to use JMX during runtime to dynamically examine the statistics of the MBeans. The Monitoring component provides the APIs for you to retrieve counts and statistics that are related to the following:

  • Thread pools that handle the processing of result-notification messages
  • Thread pools that handle the notifying of the result-notification listeners
  • Work queues that hold tasks for notifying the result-notification listeners
  • Work queues that hold tasks for processing the result-notification messages
  • Memory queues of push stats objects
  • Memory queues of result-notification messages

The Monitoring component contains the monitoring package.

Changing the properties in the PushSDK.properties file

When you create a server-side push initiator that uses the server-side library components, you need to change the configuration properties in the PushSDK.properties file. This file contains general settings that you need to configure so that the SDK works correctly. Some of the properties in the files are related to the high-level APIs, some are related to the low-level APIs, and some are shared by both APIs.

If you're using only the low-level APIs, the properties are marked in the file with a @Required for low level APIs comment.

You can find the PushSDK.properties file in one of the following places after you install the SDK:

  • For high-level distributions, the path is: pushsdk-high-level/configuration/PushSDK.properties.
  • For low-level distributions, the path is: pushsdk-low-level/configuration/PushSDK.properties.

Specify the base URL for the PPG

Before you begin, obtain the following information:

  • If your server-side push initiator uses the BlackBerry Internet Service as the PPG, obtain the base PPG URL from the email message that you received when you registered with BlackBerry to use the Push Service. In these instructions, this server-side push initiator is called a PUBLIC_PUSH type of push initiator.
  • If your server-side push initiator uses the BlackBerry Enterprise Server as the PPG, ask the administrator for the URL of the BlackBerry MDS Connection Service. In these instructions, this server-side push initiator is called an ENTERPRISE_PUSH type of push initiator.
  • If your server-side push initiator uses the BlackBerry Device Service as the PPG, ask the BlackBerry Device Service administrator for the URL of the BlackBerry MDS Connection Service. In these instructions, this server-side push initiator is called a BDS_PUSH type of push initiator.

If you're developing a mixed type of server-side push initiator (for example, PUBLIC_PUSH and BDS_PUSH), you need to obtain one, two, or all three of these URLs.

  1. In a text editor, open the PushSDK.properties file.
  2. Perform one of the following actions:

    Task

    Steps

    Specify the URL for the PPG for a PUBLIC_PUSH type of server-side push initiator.

    In the Push management configuration properties section, for the public.ppg.address property, replace the ${ppg.base.url} token with the URL of the BlackBerry Internet Service. For example, the URL for your use in evaluation is https://cp<cpid>.pushapi.eval.blackberry.com), where <cpid> is your content provider ID.

    Specify the URL for the PPG for an ENTERPRISE_PUSH type of server-side push initiator.

    In the Push management configuration properties section, for the enterprise.ppg.address property, replace the ${bes.ppg.base.url} token with the host name and port number of the BlackBerry MDS Connection Service of the BlackBerry Enterprise Server in the following format: http://<host_name>:port number (For example, http://server:7000).

    Specify the URL for the PPG for a BDS_PUSH type of server-side push initiator.

    In the Push management configuration properties section, for the bds.ppg.address property property, replace the ${bds.ppg.base.url} token with the host name and port number of the BlackBerry MDS Connection Service of the BlackBerry Device Service in the following format: http://<host_name>:port number (For example, http://server:7000).

Configure the properties related to push

You can change the configuration properties that are related to submitting push request messages.

  1. In a text editor, open the PushSDK.properties file.
  2. In the Push management configuration properties section, change the values for the configuration properties as necessary.

Here are the configuration properties that you can change.

Configuration property

Description

public.ppg.address

This property specifies the address of the BlackBerry Infrastructure when the Push Service is used for submitting push request messages.

You must specify a value for this property.

The address to submit push request messages must be an absolute URL.

enterprise.ppg.address

This property specifies the address of the BlackBerry MDS Connection Service when the BlackBerry Enterprise Server is used for submitting push request messages.

You must specify a value for this property.

The address to submit push request messages must be an absolute URL.

bds.ppg.address

This property specifies the address of the BlackBerry MDS Connection Service when the BlackBerry Device Service is used for submitting push request messages.

You must specify a value for this property.

The address to submit push request messages must be an absolute URL.

regenerate.pushid.max.attempts

This property is applicable when the Store Push Requests attribute of a push-enabled app is set to true. The property specifies the maximum number of attempts that are available to the following method to generate a unique push ID before the operation to submit a push request message is terminated:

net.rim.pushsdk.commons.IdGeneratorImpl.
	generateId()

This property also applies if you use your own implementation of the net.rim.pushsdk.commons.IdGenerator interface for generating the push ID. When the specified number of attempts fail to generate a unique push ID and the operation to submit the push request message is terminated, the InvalidPushRequestException is thrown and a warning is logged.

The default value is 5.

When you use the high-level API features, this property is ignored if you set the push ID using the following method:

net.rim.pushsdk.push.PushParameters.
	setPushId(String)

default.deliver.before.timestamp.offset

This property is applicable only when you use the low-level API features. The property specifies the maximum time period (in milliseconds) within which the push message must be delivered to BlackBerry devices. This time includes any time spent retrying to send the push message. The time period starts when the PPG starts the push operation. After this period is over, the push operation is terminated.

The default value is 3600000.

This property is ignored when the time period is specified using the following method:

net.rim.pushsdk.pap.control.
	PushMessageControl().
	setDeliverBeforeTimestamp(Date)

push.request.detail.find.max.results

This property specifies the maximum number of PushRequestDetail objects that the following method returns:

net.rim.pushsdk.push.request.
	PushRequestDetailServiceImpl.
	findByDateRange()

This method finds all of the PushRequestDetail objects that are created within the period that is specified in the method's parameters. If you set a large value, make sure that you have a large amount of available memory in your push server.

The default value is 100000.

If you set a value that is too large, the Push Service SDK might use up a lot of system resources and negatively affect system performance or increase the risk of information loss in the event of a system failure.

push.stats.update.frequency

This property specifies the interval frequency (in seconds) of updates to push statistics in the SDK database. All counts and content sums are stored in system memory until a batch update of the data in the SDK database is done at the interval frequency. Between the intervals, there might be some inconsistencies in the statistics-related data between the system memory and the SDK database.

The default value is 120.

If you set a value that is too large, the chances of inconsistencies in the data between the system memory and the SDK database increases. If you set a value that is too small, the data in the SDK database stays more current, but the Push Service SDK might use up a lot of system resources and negatively affect system performance or increase the risk of information loss in the event of a system failure.

push.stats.update.queuesize

This property specifies the maximum size of the memory queue holding the statistics-related data, as the data waits before being used in the batch update of the SDK database.

The default value is 100000.

When the memory queue reaches the maximum size, it blocks until the size goes down.

Specify the configuration properties for the database

  1. In a text editor, open the PushSDK.properties file.
  2. In the Database configuration properties section, replace all of the tokens with values that correspond to your database environment and the way you want to configure the datasource.

Configuration properties for the datasource and the database connection pool that aren't specified in the PushSDK.properties file use the default values of the Apache Commons DBCP. For more information about these configuration properties and their default values, visit the Apache Commons website.

Here are the configuration properties that you can change:

Configuration property

Description

dao.type

This property specifies where you want to store SDK data.

The default value is RDBMS, which means that you want to store SDK data in a database.

The other choice is Memory, which means that you want to store SDK data in system memory.

database.type

This property specifies the type of the database that you use with the Push Service SDK.

The default value is mysql.

The possible choices are mysql or oracle.

driver.class.name

This property specifies the fully qualified Java class name of the JDBC driver you are using.

For example, a fully qualified Java class name of a JDBC driver for a MySQL database is com.mysql.jdbc.Driver. An example for an Oracle database is oracle.jdbc.driver.OracleDriver.

You must specify a value for this property.

db.connection.url

This property specifies the connection URL that is passed to your JDBC driver to establish a connection to the database.

Example of a URL for a MySQL database is jdbc:mysql://localhost:3306/pushsdk. An example for Oracle is jdbc:oracle:thin:@localhost:1522:pushsdk.

You must specify a value for this property.

db.username

This property specifies the username for the connection that is passed to your JDBC driver to establish a connection to the database.

You must specify a value for this property.

db.password

This property specifies the connection password that is passed to your JDBC driver to establish a connection to the database.

You must specify a value for this property.

db.initialSize

This property specifies the initial number of connections that are created when the database connection pool is started.

The default value is 10.

db.maxActive

This property specifies the maximum number of active connections that can be allocated from the database connection pool at the same time.

The default value is 100. A negative value means that there is no limit on the maximum number of active connections.

db.maxIdle

This property specifies the maximum number of connections that can remain idle in the database connection pool before unused connections are closed.

The default value is 10. A negative value means that there is no limit on the maximum number of idle connections.

If you specify a value that is too low for heavily loaded systems, it is possible that connections might close and new connections open almost immediately. This is a result of the active threads momentarily closing connections faster than they are opening them, causing the number of idle connections to rise above the specified value. The best value for heavily loaded systems varies, but the default value is a good starting point.

db.maxWait

This property specifies the maximum duration of time (in milliseconds) that the database connection pool waits (if no connections are available) for a connection to be returned before throwing an exception.

The default value is 30000.

A negative value causes the database connection pool to wait indefinitely for a connection to be returned when no connections are available.

db.testOnBorrow

This property specifies (as a Boolean value) whether objects are validated before they are borrowed from the database connection pool. If an object fails to be validated, it is dropped from the pool and an attempt is made to borrow another object. Validation of objects before being borrowed from the database connection pool has a negative performance impact, so it should be used with discretion.

The default value is true.

For the default value to have any effect, the db.validationQuery property must be set to a non-null string.

db.validationQuery

This property specifies the SQL query that is used to validate connections from the database connection pool before the connections are returned to the caller.

The default value is SELECT 1 FROM DUAL. If you specify a value, it must be a query that is an SQL SELECT statement that returns at least one row.

Connections are validated only if the db.testOnBorrow property is set to true.

max.in.clause.values

This property specifies the maximum number of SQL IN clause parameters that are allowed by the database that you use.

The default value is 1000.

For more information about specifying an appropriate value for this property for your database, see the documentation for the database from your database vendor.

Specify the base URL for subscription deregistration, suspend, resume, and query

If you create a server-side push initiator that delivers content using only the BlackBerry Internet Service, you need to specify the base URL for subscription deregistration, suspend, resume, and query. The base URL can be the same as the base URL of the BlackBerry Internet Service. You can obtain the base URL from the email message that you received when you registered with BlackBerry to use the Push Service.

If you create a server-side push initiator that delivers content using only the BlackBerry Enterprise Server or BlackBerry Device Service, this configuration property does not apply.

  1. In a text editor, open the PushSDK.properties file.
  2. In the Subscription configuration properties section, for the <subscription.*.url> properties, replace the ${ppg.sub.base.url} tokens with the URL of the BlackBerry Internet Service. For example, the URL for your use in evaluation is https://cp<cpid>.pushapi.eval.blackberry.com, where <cpid> is your content provider ID.

Configure the properties for actions related to subscriptions and subscribers

You can change configuration properties for actions that are related to subscription and subscribers.

  1. Open the PushSDK.properties file with a text editor.
  2. In the Subscription configuration properties section, change the values for the properties that you want to change.

Here are the configuration properties that you can change.

Configuration property

Description

subscription.deregistration.url

This property specifies the PPG address to use for deregistering subscribers if you configured the Push Service SDK to use the BlackBerry Internet Service as the PPG.

The default value is:

${ppg.sub.base.url}/mss/
	PD_cpDeregUser?pin=

where ${ppg.sub.base.url} is a token that you replace with an actual value.

For example, if the base URL of the PPG is:

https://cp<cpid>.
	pushapi.eval.blackberry.com

then the URL for deregistering subscribers is:

https://cp<cpid>.
	pushapi.eval.blackberry.com/mss/
	PD_cpDeregUser?pin=

where <cpid> is your content provider ID.

subscription.suspend.url

This property specifies the PPG address for suspending subscriptions if you configured the SDK to use the BlackBerry Internet Service as the PPG.

The default value is:

${ppg.sub.base.url}/mss/
	PD_cpSub?cpAction=suspend&pin=

where ${ppg.sub.base.url} is a token that you replace with an actual value.

For example, if the base URL of the PPG is:

https://cp<cpid>.pushapi.eval.
	blackberry.com

then the URL for suspending subscribers is:

https://cp<cpid>.
	pushapi.eval.blackberry.com/mss/
	PD_cpSub?cpAction=suspend&pin=

where <cpid> is your content provider ID.

subscription.resume.url

This property specifies the PPG address for resuming subscriptions if you configured the SDK to use the BlackBerry Internet Service as the PPG.

The default value is:

${ppg.sub.base.url}/mss/
	PD_cpSub?cpAction=resume&pin=

where ${ppg.sub.base.url} is a token that you replace with an actual value.

For example, if the base URL of the PPG is:

https://cp<cpid>.pushapi.eval.
	blackberry.com

then the URL for resuming subscription is:

https://cp<cpid>.
	pushapi.eval.blackberry.com/mss/
	PD_cpSub?cpAction=resume&pin=

where <cpid> is your content provider ID.

subscription.query.url

This property specifies the PPG address for querying subscriptions if you configured the SDK to use the BlackBerry Internet Service as the PPG.

The default value is:

${ppg.sub.base.url}/mss/PD_cpSubQuery

where ${ppg.sub.base.url} is a token that you replace with an actual value.

For example, if the base URL of the PPG is:

https://cp<cpid>.pushapi.eval.
	blackberry.com

then the URL for querying subscriptions is:

https://cp<cpid>.
	pushapi.eval.blackberry.com/mss/
	PD_cpSubQuery

where <cpid> is your content provider ID.

subscription.find.max.results

This property specifies the maximum limit on the number of results that might be returned by a subscriber find operation. A large value requires a large amount of available memory.

The default value is 100000.

subscription.validation.high.water.mark

This property specifies the maximum number of subscribers for validation. This property determines which optimized query to use. Below this limit, a query that is optimized for a small number of users is used. Above this limit, a query that is optimized for a large number of users is used.

The default value is 100000.

subscription.validation.batch.size

This property specifies the maximum number of subscribers to load at one time from the database for validation. A large value requires a large amount of available memory. A small value increases the number of calls to the persistent store.

The default value is 100000.

subscription.matching.max.threads

This property specifies the maximum number of threads to use for subscription validation when the number of subscribers is above the limit specified in subscription.validation.high.water.mark.

The default value is 5.

subscription.matching.queuesize

This property specifies the size of the queue for large subscription validation and subscription matching operations.

The default value is 50000.

subscription.ppg.sync.batch.size

This property specifies the batch size for each request to synchronize the status of subscribers between the server-side push initiator database and the PPG database, if you configured the SDK to use the Push Service as the PPG. BlackBerry configures the PPG to limit the maximum number of subscribers for inclusion in each request. If BlackBerry changes the limit on the PPG, you must update this property accordingly.

The default value is 10000.

subscription.ppg.sync.queuesize

This property specifies the size of the queue for synchronizing the status of subscribers between the server-side push initiator database and the PPG database.

The default value is 5000.

subscription.ppg.sync.timeout

This property specifies the duration of time (in minutes) to wait for synchronizing the status of subscribers between the server-side push initiator database and the PPG database before a timeout occurs and an exception is thrown.

The default value is 30.

subscription.ppg.sync.threads

This property specifies the maximum number of threads to use for synchronizing the status of subscribers between the server-side push initiator database and the PPG database.

The default value is 5.

Configure the properties of the HTTP client

You can change the configuration properties for the net.rim.pushsdk.commons.http.HttpClientImpl class. If you use an HTTP client other than the one created using the HttpClientImpl class that is available from the Push Service SDK, you don't need to perform this task.

  1. In a text editor, open the PushSDK.properties file.
  2. In the HTTP client configuration properties section, change the values for the properties that you want to change.

Here are the configuration properties that you can change.

Configuration property

Description

http.connection.timeout

This property specifies the duration of time (in milliseconds) that is allowed to establish an HTTP connection to the PPG by an HttpClientImpl object before a timeout error occurs and the connection attempt is terminated.

The default value is 60000, which is equivalent to 1 minute.

Setting this property to 0 indicates an infinite timeout.

http.read.timeout

This property specifies the maximum wait time (in milliseconds) that is allowed for data to become available for reading from an HTTP connection to the PPG by an HttpClientImpl object before a timeout error occurs and the read action is terminated.

The default value is 120000, which is equivalent to 2 minutes.

Setting this property to 0 indicates an infinite timeout.

http.is.persistent

This property specifies (as a Boolean value) whether the HttpClientImpl object uses a persistent HTTP connection to connect to the PPG.

The default value is true.

Setting this property to true or false might depend on the performance expectations of your app and on the resources that are available in your server and network environment.

Configure the properties related to acknowledgment

You can change the configuration properties that are related to the net.rim.pushsdk.acknowledgement.NotificationProcessorServiceImpl class.

  1. Open the PushSDK.properties file with a text editor.
  2. In the Acknowledgement configuration properties section, change the values for the properties you want to change.

Here are the configuration properties that you can change.

Configuration properties

Description

acknowledgement.max.queue.size

This property specifies the maximum size of the internal memory work queue for storing result-notification request messages that the PPG sends. When the queue reaches the maximum size, the Push Service SDK starts rejecting the messages and the PPG tries to send them again later.

The default value is 100000.

If you set a value that is too small, the Push Service SDK rejects the result-notification request messages that the PPG sends, and the PPG tries to send the messages up to five more times, with each attempt being delayed longer than the previous attempt. If you set a value that is too large, the Push Service SDK might use up a lot of system resources and negatively affect system performance or increase the risk of information loss in the event of a system failure.

acknowledgement.max.threads

This property specifies the maximum number of NotificationProcessorServiceImpl threads to use for processing the result-notification request messages from the internal memory work queue. When a thread is available, it goes to the queue to retrieve a batch of messages for processing.

The default value is 20.

If you increase the number of threads and adequate system resources are available, the performance of processing the result-notification request messages can be improved. When adequate system resources are not available, increasing the number of threads might use up a lot of system resources and negatively affect system performance or increase the risk of information loss in the event of a system failure.

acknowledgement.batch.size

This property specifies the maximum number of result-notification request messages that a NotificationProcessorServiceImpl thread reads as a batch from the internal memory queue to process at once. When a thread is available but the total number of result-notification request messages in the internal memory queue is less than the maximum size of the batch specified through this property, the thread reads and processes whatever number of messages are available.

The default value is 500.

acknowledgement.push.lookup.retry.delay

This property specifies the duration of time the NotificationProcessorServiceImpl waits before it tries again to look up the push request details in the SDK database when it does not find the push request details in the first attempt. If the retry attempt fails, the NotificationProcessorServiceImpl logs an error.

The default value is 5000.

Configure the properties related to the log file and logging

You need to perform this task to specify the default location of the log file. Optionally, you can perform this task if you want to change the default values for the logging level, date format, and other properties that are related to the log file and logging.

  1. In a text editor, open the log4j.xml file.
  2. Change the values for the properties that you want to change.

Using a different database

The Push Service SDK has default Data Access Object (DAO) implementations that work with MySQL or Oracle databases. With a few modifications to the SDK, you can use the same DAO implementations with databases that have similar SQL dialects, such as PostgreSQL.

The default implementations of the DAOs are injected with an instance of an object that implements the SQLProperties interface. Because the SQL can vary slightly between database vendors, the SQLProperties interface allows the SDK to abstract how the SQL statements that are used by the DAOs are obtained instead of hard coding them into the DAO implementation classes.

When you implement the SQLProperties interface, you can override the SQL statements that are used by the default DAO implementations of the SDK with your own SQL statements. The SQLProperties interface defines a getProperty(String sqlStatementProperty) API that returns the SQL statement for a given sqlStatementProperty property name. The SQLProperties interface defines all of the property names that are used by the DAO default implementations. You need to specify an SQL statement for each property name.

The default implementation of the SQLProperties interface, SQLPropertiesImpl, works by looking at the database.type property in the PushSDK.properties file. SQLPropertiesImpl then tries to load a property file from the classpath with a file name of <database.type>.properties. For example, if the <database.type> is set to mysql, SQLPropertiesImpl tries to load a file called mysql.properties. The property file is a standard Java property file in the form of key-value pairs. The key is the property name, and it uniquely identifies the SQL statement. The value is the actual SQL statement in the dialect of your database vendor.

If you want to use a different database, such as PostgreSQL, you need to perform the following actions:

  1. Create the schema that is required by the SDK for your database. You can start by editing and renaming one of the MySQL (pushsdk_schema_mysql.sql) or Oracle (pushsdk_schema_oracle.sql) database data definition language (DDL) files that are included in the SDK in the pushsdk-high-level\database-scripts folder. If necessary, change the SQL statements in the DDL file to work with the dialect of your database vendor.
  2. Edit the PushSDK.properties file and change the database.type property to a value of your choosing, such as postgresql.
  3. Create a property file with the same name as the property value you chose, such as postgresql.properties.
  4. Edit the postgresql.properties file and create key-value pairs for each SQL statement that is required by the SDK. There should be one key name for each constant field value in SQLProperties, and the value should be the corresponding SQL statement in the PostgreSQL database dialect.

    Instead of creating the postgresql.properties file from scratch, you can use either the mysql.properties or oracle.properties file that's included in the SDK in the pushsdk-high-level\configuration folder. You can rename the file you choose, and then edit the SQL statements so they match the dialect of your database vendor.

Implementing your own persistence layer

It's possible to replace the data access layer of the Push Service SDK with your own implementation. You can implement the interfaces of all of the SDK Data Access Objects (DAOs), and then inject your DAO instance into the corresponding service classes. You can implement your DAOs any way you want using any technology that you want. There are no other requirements other than implementing the APIs as specified by their documentation.

You might want to implement a cache mechanism in certain DAO implementations that have high volume API access, such as PushStatsDAO, PushApplicationDAO, and SubscriptionDAO.

If you're using the SDK service layer objects, you need to implement the following DAOs:

DAO Description
net.rim.pushsdk.push.count.PushCountDAO

An interface that defines data access methods that are needed to track when push requests are complete.

net.rim.pushsdk.push.request.PushRequestDAO

An interface that defines data access methods that are needed to manage PushRequest objects in data storage.

net.rim.pushsdk.push.request.PushRequestDetailDAO

An interface that defines data access methods that are needed to manage PushRequestDetail objects in data storage.

net.rim.pushsdk.push.stats.PushStatsDAO

An interface that defines data access methods that are needed to manage PushStats objects in data storage.

net.rim.pushsdk.pushappmgmt.PushApplicationDAO

An interface that defines data access methods that are needed to manage PushApplication objects in data storage.

net.rim.pushsdk.subscription.SubscriptionDAO

An interface that defines data access methods that are needed to manage subscription-related objects in data storage.

net.rim.pushsdk.subscription.sync.SubSyncByAddressDAO

A data access object for use during the syncing of subscriber statuses by address.

An example of replacing the PushApplicationDAO

To replace the PushApplicationDAO, you need to edit the pushsdk-push-app-context.xml file, and then do one of the following:

  • Define a new bean with your implementation and inject the bean into the service classes that need it.
  • Replace the existing bean definition with your own. For example:
    <bean id="pushRequestRDBMSDAO" class="my.own.custom.PushRequestRDBMSDAOImpl">
       <property name="dataSource" ref="myOwnDataSource" />
    </bean>
    

Last modified: 2015-06-11



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus