4

Currently, our managed package responds to DML events in real-time for a static set of standard objects we support. Our package achieves this real-time responsiveness through Apex Triggers, one for each object in the set. Consequently, our package cannot be installed in an org unless each of these objects exists in the org.

We have two GOALS:

  1. Remove this limitation so that our package can be installed/upgraded regardless of which objects exist in the subscriber org.

  2. Respond to DML events in real-time for ANY Salesforce object (we would prefer to use triggers to accomplish this).

I know of two high-level OPTIONS:

  1. Move all object dependencies (including the triggers) to optional package extensions.
    The major advantage of this option over option 2 below is that it doesn't require all unit tests in the subscriber organization's namespace to pass for the triggers to be deployed (according to http://www.salesforce.com/us/developer/docs/packagingGuide/Content/packaging_component_behavior.htm). However, there are several disadvantages of this approach including:

    • Complicates dev process.
    • Subscribers have to install multiple packages to get real-time responsiveness.
    • Complicates package UNinstallation.
    • Set of real-time enabled objects is still static (unless we can dynamically create and install package extensions, which - correct me if I'm wrong - is impossible).
  2. Dynamically deploy Apex Triggers to subscriber orgs (assume we are talking about production orgs for the purpose of this discussion).

    • We've already done this using file-based Metadata API and the deploy() call, but it requires all unit tests in the subscriber organization's namespace to pass and, in our experience, they often fail. Given the frequency and difficulty of resolving these failures, we are looking for a better/more scalable/more customer-friendly solution.

QUESTIONS:

  1. Is there a way to do option 2 (i.e., dynamically deploy Apex Triggers to subscriber orgs) that does not require all org's unit tests to pass?

  2. If not, is there a better/more scalable/more customer-friendly way to do option 2?

  3. What approach would you recommend to achieve goals 1 and 2 ... option 1? Option 2? Something else?

Any help would be much appreciated!!

2

Great question!

Q1: The only way to get code into a production org without running all the tests in the subscriber org is via a managed package. Both Metadata API and the Tooling API will insist on running unmanaged code tests (effectively tests also in the default namespace your deploying code into). As you've pointed out in option one this has several draw backs, least of which, you cannot ask your subscribers to move all their custom objects into packaging orgs.

Q2: Not that I can think, I've gone over this exactly issue over and over when developing the Declarative Rollup Tool, which does exactly what your doing in option 2, dynamically deploying to the org the Apex Trigger. I've had a few reports, much the same about subscriber test failures blocking things, in the end though it has driven out some better practice in the subscriber org!

Q3: Beyond the options listed below, I would stick with option 2, its the most responsive and totally native. Also because in the final analysis I don't think option 1 is actually practical, most subscribers have already got their custom objects established, so moving them to a new package/namespace is not going to be something they will tolerate. It will be easier to fix unit tests!

Other Thoughts

  • Outbound Messaging (as per the docs). "Outbound messaging is part of the workflow rule functionality in Salesforce. Workflow rules watch for specific kinds of field changes and trigger automatic Salesforce actions, such as sending email alerts, creating task records, or sending an outbound message." "A single SOAP message can include up to 100 notifications.". You could use the Metadata API to dynamically create the Workflow rules. But this feature also queues events to some degree, so also erodes further away from true realtime. Plus you cannot implement the end point on the platform. You would at least need a Heroku end point based on the WSDL generated that calls back into say an Apex REST endpoint.
  • Salesforce Streaming API is a publish subscribe model, that in concept fits the requirement, with its generic Push Topic concept. But then lets itself down in the Messaging Reliability section, plus since there is no Deamon feature on Force.com, you'll need to host your listener off platform on Heroku. Anyway might be worth a thought?
  • Hybrid of Option 1 and 2? So option 1 will only give you coverage for a static set of the standard objects, across the various editions and configurations. Which results in a lot of packages, though the triggers need only be single line ones referring to a global trigger handler (see my Declarative Rollup Tool as an example), so may not, aside from the initial setup, complicate the dev process ongoing, since the extension package orgs should not need touching much after this. Then for the realtime dynamic enablement (of subscriber custom objects), tolerate option 2's down side of needing the unit tests running. This hybrid option, may reduce your solutions risk of hitting the unit test stability issue.

Auto Installing Packages from Apex. If you want to develop some kind of magic "Install and Uninstall the required extension packages" page, that uses an Apex Describe Global to determine the available standard objects / org features and then auto installs the packages you can do this via Apex, see here.

  • Thanks for the great response, @Andrew! Since auto-installing packages either directly or indirectly uses the Metadata API, does it also require tests in the subscriber org's namespace to run? If so, can the subscriber continue with the installation without resolving test failures? Does auto-installing bypass the entire package installation process? – Zach Nov 14 '13 at 21:02
  • 1
    No, installing managed packages into a subscriber org does not require any tests to run (thankfully those days are gone). When automating install you just get to given namespace (and optionally password for package). You cannot map profiles, a good reason to go permission sets! :) – Andrew Fawcett Nov 15 '13 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.