Showing posts filed under:

Salesforce

Salesforce OpenID Connect

In addition to the proprietary Authentication Provider types (Facebook, Janrain, Salesforce) Winter ’14 (v29.0) added support for the OpenID Connect protocol, enabling off-platform authentication via any compatible OpenID Provider (Google, PayPal, Amazon and others). This post provides a basic implementation overview.

OpenID Connect what is it?
OpenID Connect is a lightweight authentication (identity verification) protocol built on top of modern web standards (OAuth 2.0, REST and JSON). OpenID Connect supersedes OpenID 2.0 and amongst other goals is intended to promote interoperability, be accessible to developers and to provide greater support for mobile use cases.

The OpenID Connect standard was recently ratified by members of the OpenID foundation and announced publicly at the Mobile World Congress in Barcelona on 26th February 2014. The standard is supported by Google, Microsoft, Salesforce, AOL, Ping and others.

The protocol works on the principal of an “Authorization Server” or OpenID Provider (OP) (e.g. Google), authenticating users on behalf of a “Client” or Relying Party (RP) (e.g. Salesforce). With the current implementation Salesforce can be configured as a RP but not an OP. In this context an Authentication Provider is configured in Salesforce with the type set to OpenID Connect. Note OP is also referred to as IDP, confusingly we have 3 seemingly interchangeable terms – however the OP term is the one defined in the standard.

Please refer to the excellent OpenID website for more details in regard to specifications, implementations, useful FAQs etc..

Identity Use Cases
In simple terms, users can single sign-on (SSO) into Salesforce using external web application credentials. A Salesforce user record can be created just-in-time on the first authentication event, subsequent events for the user map to this user record. Note, usefully it’s also possible to map existing users via the [Existing User Linking URL].

A key use case here is B2C portals and communities, however internal users and partners can also use this authentication approach. For internal users SSO via a Google Account could make sense where an enterprise has adopted Google Apps for Business.

What’s important to understand is that Salesforce supports external Authentication Providers for all user types (with the exception of Chatter External) with SAML, OAuth and OpenID Connect protocol support. This provides a high degree of flexibility in the terms of how identity management is implemented.

Implementation Steps
The Salesforce help providers a detailed series of steps to follow. The following high-level example shows a basic implementation of a Google Accounts Authentication Provider.

1. Register an OpenID Connect Application.
As per Salesforce Connected Apps, within your Google account an application is required, within which OAuth is configured. Applications are created via the Google developers console. The Redirect URI won’t be known until the Authentication Provider is configured in Salesforce.

7. Google Developers Console

2. Create an Authentication Provider.
Consumer Key = Client ID
Consumer Secret = Client secret
Scope = profile email openid

8. Salesforce Auth Provider Detail Page

3. Update OpenID Connect Application.
Copy the Salesforce [Callback URL] to the Google [Redirect URI] field and save.

4. Add Authentication Provider to Login Page (Standard App or Community).
This step requires a My Domain where the internal app login page is customised.

9. Salesforce Login Page Customisation

5. Configure a Registration Handler class.
Within the Authentication Provider configuration a Registration Handler class can be specified, this class implements the Auth.RegistrationHandler interface and is invoked to create new users or map to existing users in response to authentication events.

[code language=”java”]

global class GoogleAccountsRegistrationHandler implements Auth.RegistrationHandler{
global Boolean canCreateUser(Auth.UserData data) {
//Check whether we want to allow creation of a user?
return true;
}

global User createUser(Id portalId, Auth.UserData data){
if(!canCreateUser(data)) {
//Returning null or throwing an exception fails the SSO flow
return null;
}
if(data.attributeMap.containsKey(‘sfdc_networkid’)) {
//We have a community id, so create a user with community access.
//.. create community user.
} else {
//.. create standard user.
return u;
}
}

global void updateUser(Id userId, Id portalId, Auth.UserData data){
User u = new User(id=userId);
//.. update fields if required.
update(u);
}
}
[/code]

Testing
1. Initialisation
The [Test-Only Initialization URL] provided on the Authentication Provider detail page can be pasted into a browser address bar and used to examine the raw output provided back from the Authorization Server.

1. Test Initialisation Output

2. Authentication
The following screenshots show the basic authentication flow. Note, as with SAML based SSO, errors are appended to the URL querystring.

Customised login page showing the Google Account Authentication Provider.

2. Login Page With Auth Providers

Clicking the button redirects the browser to the Google Service Login page to authenticate (unless a Google Accounts session exists).

3. Google Service Login Page

For new users the user consent page is displayed. This page can be customised via the Google Developer console.

10. User Consent page

Authentication errors are appended to the URL, as-per SAML authentication errors.

4. Error Page 1

5. Error Page 2

Finally, a Salesforce session is established. New users can be provisioned automatically, script within the Registration Handler class controls the configuration of such User records.

6. Auto-provisioned User Detail Page

Implementation Notes
1. Google Developer Console. Remember to turn ON – Google+ API access. This is required.

2. The auto-created Registration Handler class template must be modified as the default code will fail in many cases.
canCreateUser is false by default – in most cases this must be changed to true.

The Combination of values below don’t work if the user isn’t configured with US locale.
u.languagelocalekey = UserInfo.getLocale();
u.localesidkey = UserInfo.getLocale();
u.emailEncodingKey = ‘UTF-8’;
u.timeZoneSidKey = ‘America/Los_Angeles’;

3. Activation code entry appears to fail within an Internal Server error, but the code has been successful so subsequent attempts will succeed. This may be specific to my context.

4. As a best practice map the user Id from the OpenID Provider (Google Account Id in the example) into a custom field on the User record. This provides a robust mapping between the 2 system identifiers that can be used by the Registration Handler script.

5. Access can be revoked via the Third Party Account Link related list on the User detail page.

6. Make the OpenID Connect Application name meaningful to the end-users, the Google user consent page will display this in a “[AppName] is requesting access” format, anything weird or meaningless may cause concern.

Protocol Flow
Please treat the diagram below as indicative only, I put this together from a combination of browser profiling and assumptions made on the basis of reading the OpenID Connect specification.

As always, corrections would be appreciated.

OpenID Connect - SF Process Flow

Final Thoughts
OpenID Connect support is a highly useful extension to the Authentication Provider platform capability. For B2C portals and communities it makes sense to offer as many sign-in-via options as possible (Facebook, Google etc.) removing as much friction to user adoption as possible. As a personal opinion, over time I’m becoming less tolerant to having to register a new user account on each and every authenticated web site I interact with, particularly where I view the interaction as transient. Some users may have concerns around data security, i.e. by signing-in with a Google account are they implicitly giving Google access to the data held in the portal? In the majority case however, users will appreciate the improved user experience. For internal users OpenID Connect makes single sign-on via one or more of a multitude of current and future web platforms incredibly straightforward to implement. In the Salesforce context the key challenge will ultimately relate to reconciliation and rationalisation of identities (i.e. User records).

References
http://openid.net/connect/
http://openid.net/developers/specs/
https://developers.google.com/accounts/docs/OAuth2Login
https://console.developers.google.com/project

Salesforce Naming Conventions – Declarative

Updated – 2014-11-18

This post follows on from my last post on Custom Settings and provides coverage of the wider set of naming conventions I apply across the various component types of the declarative build environment. The list isn’t exhaustive or necessarily better than any other set of standards. Having a set of conventions applied consistently across the build is key, the specifics of those conventions can be subjective. A key principle applied is that of consistency with established standard conventions wherever possible. For example, standard objects and fields don’t have underscores in the API names and follow simple patterns in terms of naming, there’s no good reason to deviate from this for custom objects and fields. Naming conventions shouldn’t be considered an area for creative thinking, instead creative energy should be focused on the functional and technical design, the conventions applied should be mundane and predictable.

Convention A – Custom Object

[Object name]. Singular, Pascal Case (upper camel case) and no underscores.
e.g. Data Source -> DataSource__c

Consistent use of the default naming style, i.e. with underscores is acceptable also. it can be difficult to avoid this approach in a team environment.
e.g. Data Source -> Data_Source__c

Note – the Description attribute for Custom Objects must always be populated appropriately. A self describing configuration is key to future maintenance.

Convention B – Custom Field

[Field name]. Pascal Case (upper camel case) and no underscores.

e.g. Date of Birth -> DateOfBirth__c

Consistent use of the default naming style, i.e. with underscores is acceptable also. it can be difficult to avoid this approach in a team environment.
e.g. Date of Birth -> Date_Of_Birth__c

In the scenario where an implementation is comprised of distinct functional domains, with custom fields relating specifically (and exclusively) to one single domain, the following convention should be applied.

Each functional domain has a defined field name Prefix. e.g. HR, FINANCE, SALES etc.
Fields exclusive to one domain have their API name prefixed with the domain prefix.
e.g. Payroll Number -> FINANCE_PayrollNumber__c
e.g. Industry Segment -> SALES_IndustrySegment__c

This convention allows a logical structure to be applied in isolating fields specific to a single functional domain.

Note – the Description attribute for Custom Fields must always be populated appropriately. A self describing configuration is key to future maintenance.

Note – the Help Text attribute for Custom Fields must always be populated appropriately. Inline user assistance can improve the end user experience greatly and reduce ongoing support.

Convention C – Child Relationships

Singular, Pascal Case (upper camel case) and no underscores.
e.g. Account->AccountMetrics__c relationship = Account.AccountMetrics__r

Convention D – Page Layout

[[Function] | [Object]] Layout

e.g. Pricing Case Layout
e.g. Pricing Case Close Layout

Convention E – Custom Setting

Custom Setting Label – Pluralised in all cases (e.g. Data Sources). No “Setting[s]” suffix.

API Name – List Settings
– [Data entity that each list entry represents]ListSetting__c

Each record represents an individual entry and as such singular naming is applied, as per objects.

e.g. Analytic Views – AnalyticViewListSetting__c
e.g. Data Sources – DataSourceListSetting__c

API Name – Hierarchy Settings
– [Function of the settings]Settings__c

Each record represents the same set of settings applied at different levels. In concept this differs from objects and list settings, the plural naming reflects this.

e.g. Org Behaviour Settings – OrgBehaviourSettings__c
e.g. My App Settings – MyApplicationSettings__c

Convention F – Workflow Rule
Always separate the condition from the outcome when configuring workflow. The Workflow Rule is the condition, the associated Actions are the outcome. In many cases the 2 become entwined resulting in duplicated rules, or rules with actions unrelated to the stated purpose of the rule. A clear set of rules related to conditions promotes re-use.

[Object]: [Criteria Description i.e. Condition]

Convention G – Workflow Action

Field Update –
[Object]: Set [Field] to [Value]

Email Alert –
[Object]: Send [Template short description]

Task –
[Object]: [Task Subject]

Convention H – Sharing Rule

OBS: [Object] [From selection] to [To selection]
CBS: [Object] [Criteria] to [To selection]

Convention I – Custom Report Type

[Primary Object] with [Child object]s [and [Grandchild object]s]

Convention J – Custom Label

Define sensible categories for the labels. e.g. UI Button Label, UI Text, UI Error Message etc.

Name = [Category with underscores]_[Value with underscores] e.g. UI_Button_Label_Proceed
Category = [Category with underscores] e.g. UI_Button_Label
ShortDescription = [Category] [Value] e.g. UI Button Label Proceed
Value = [Value] e.g. Proceed

Convention K – Validation Rule

Single field :
[Field Label] [rule applied]
Mailing City Is Required
Start Date Must Be a Weekday

Multiple fields :
[Field grouping term] [rule applied]
Billing Address Must Be Complete

Cross object :
[Object Name] [Field Label] [rule applied]
Opportunity Stage Is Closed No Edit Of Opportunity Products

Convention L – Publisher Action

[Verb] [Noun]
New Invoice
Update Order
Alert Executive Team

Convention M – User Profile

[[Job Function] | [Department] | [Company]] [[User] | [System Administrator]]
Accounts Payable User
Marketing Executive User
Acme System Administrator

Convention N – Permission Set

Single Permissions :
Name must match the permission assigned.
Case Feed
Manage Dashboards
Manage Public List Views

Simple Combined Permissions :
[Verb] [Noun]
Manage Invoices

Combined Permissions :
[Feature Area Descriptor] [User Type]
Work.com Administrator
CloudInvoices User
Knowledge Contributor

Convention O – Public Group

[Grouping term] [[Users] | [Members]]

EU Users
Sales Users
HR Users
Project A Members

Convention P – Reports and Dashboard Folders

[Grouping term] Reports (adhoc reports related to a specific department, team, project etc.)
[Grouping term] Dashboard Reports (best practice to isolate dashboard reports in clear location)
[Grouping term] Dashboards

Finance Reports
HR Dashboards
HR Dashboard Reports

Note – the [Report Description] attribute for Reports must always be populated appropriately. A self describing configuration is key to future maintenance.

Salesforce Identity Connect

Over the recent years I’ve spent focused on the Salesforce architecture domain I’ve designed and implemented federated single sign-on (SSO) schemes many times (and the proprietary Delegated Authentication on rare occasions). Whilst each implementation has its nuances in terms of specific access use cases (mobile, composite app, public internet versus corporate network only etc.) and infrastructure deployment topology, there is typically a high degree of commonality. For instance, most corporate environments utilise Active Directory as the primary enterprise identity store, this is inarguable. Equally common in such environments, at least in my experience, is the absence of Active Directory Federation Services (ADFS), or any federated identity service (Ping Identity, Okta etc.). As such the introduction of SSO for Salesforce typically means introducing the infrastructure to support federated SSO as a generic service. Notable exceptions to this are corporates that have transitioned to the Office365 cloud productivity suite, where federated SSO is highly desirable for the same good reasons as those for Salesforce SSO, namely security, support and end-user experience.

Following the idea that Active Directory is pervasive in today’s corporate infrastructure environments and that Salesforce SSO implementations typically conform to a set of patterns and related technology solutions, implementing SSO becomes a question of mapping a specific set of identity management requirements appropriately.

Example patterns (illustrative and not exhaustive)

SAML Service Provider initiated flow with optional automated user provisioning.
Solution Option – ADFS (possible with AD groups and conditional custom claims rules) with SAML based JIT user provisioning.
Rationale – Simple, cost-effective solution using standardised technology. If the IT department supports AD, ADFS shouldn’t cause any alarm.

SAML Service Provider initiated flow with bi-directional identity synchronisation.
Solution Options – ADFS with middleware-based data synchronisation between Salesforce User records and AD User Principals. Or, 3rd party identity management service offering user synchronisation capability. For a simple one app, point solution Okta Cloud Connect is a free service to be evaluated alongside equivalent competitor offerings.
Rationale – ADFS has no native identity synchronisation capability. Users can be provisioned into Salesforce, and updates applied to certain fields, via SAML JIT provisioning at the time of access, however there are no background updates and perhaps most crucially there is not automated de-activation of users.

SAML Identity Provider initiated flow with bi-directional identity synchronisation.
Solution Option – 3rd party identity management service.
Rationale – ADFS offers no native user-facing IdP capability, 3rd party services offer great flexibility in this area. Salesforce itself can be used as an IdP – a subject beyond the scope of this post.

As the example patterns show, there are a number of factors to consider and a multitude of enabling technologies, each with different levels of capability (at a reflective price point). Given the complexity of a federated SSO solution, and accepting that an enterprise-wide solution should be considered over a point solution, it is key to understand the solution options available and to consider some degree of future proofing.

A relatively recent arrival in the market is Salesforce Identity Connect (October 2013), an add-on component to Salesforce Identity, providing connection to on-premise identity directories, namely Active Directory. The rest of this post outlines the result of a high-level investigation into the capabilities of Salesforce Identity connect.

Salesforce Identity Connect
Salesforce Identity Connect, hereafter referred to as SIC, is built on the ForgeRock Bridge Service Provider Edition (SPE) technology and falls into the category of 3rd identity service.

What is it?
Informal notes in no order.

On-premise identity service with a browser-based admin UI.
Supports Windows, OSX and Linux hosts.
Can be installed on Windows as a service.
Install, configure, run service. Quick to get up and running.
No ADFS proxy equivalent.
An org must be activated for Salesforce identity, this adds a download link to the setup menu and feature licenses.
One SIC instance can support multiple orgs (with different configurations). Sandboxes are supported.
Setup steps; create connections (SF and AD, define mappings, set schedule, configure SSO)
No local storage of users and passwords, user associations are held in a local MySQL db.
Connects to a SF org via OAuth 2.0
Multiple direct AD Domain Controller connections are not supported, instead a connection should be made to the Global Catalogue where multiple domains must be spanned. Note this approach requires manual modification of the AD schema.
User licenses are managed via Permission Set Licensing, not feature licensing.
Org must have Multiple SAML Configurations enabled.

What does it do?

User Authentication – Federated user authentication is supported via SAML 2.0 Service Provider Initiated and Identity Provider Initiated flows. SPI is the common case, where users access the SF My Domain and are redirected to the IdP (SIC, Identity Connect) for either seamless integrated authentication (IWA) or prompted AD login. For IWA to work there are a number of complex Kerberos authentication related setup steps to be applied to the SIC host, this can be a challenge as technical expertise in this subject area is limited. There are also end-user browser configuration changes to be applied, for IE users a GPO would cover this, for Firefox a manual configuration would be necessary. Not ideal.

User Synchronisation – Automated background synchronisation, not JIT. Mapping can be attribute-based (AD User attribute to Salesforce User field), AD Group membership to User Profile or AD Group membership to Permission Set. In the attribute case, direct mappings, transformations via JavaScript or default static values can be applied. Where transformations are applied ternary expressions are a useful convention where only populated field values are transformed to provide the target value. In the Group to Profile case, a list of AD groups are mapped to specific profiles, such mappings are defined with a precedence order such that the result is always a single profile, regardless of how many groups a user is a member of. A default profile must be defined as a catch-all. Tracking of users provisioned into Salesforce occurs via Permission Set Licenses for the Identity Connect Permission Set. User associations established by the SIC Reconciliation Report can be manually edited via the web interface. The applied association rules can also be modified where necessary. Synchronisation can be configured to run in Live Update or Scheduled Update mode. The former being more timely, but more prone to inconsistency the latter being more comprehensive approach with the typical periodic scheduling frequencies. It would be nice to have the option to combine live updates with a scheduled daily synchronisation – this doesn’t appear to be possible.

Licensing?
Salesforce Identity Connect is licensed as an add-on to Salesforce Identity at £1 per-user, per-month regardless of Edition. Current pricing can be found via this link.

Conclusions
Salesforce Identity Connect provides a capable user authentication and synchronisation service. Good points being the ease of configuration of the Salesforce side of things plus the multiple org support, the attribute and group mapping functionality is also very nice. The two downsides being the cost, although it’s an expensive area of technology, and the complexity of configuring Integrated Windows Authentication (IWA). The SSO aspect to the service is only meaningful if the SSO is seamless. Coming back to the cost, ADFS is free-of-charge but provides no user synchronisation (other than via SAML JIT). I believe many people will take this route regardless, simply to avoid any cost whatsoever, although £1 per user/month does represent a significant outlay for larger installs and could be hard to justify for performance edition customers particularly. In addition to the run cost there is also the technical complexity of establishing IWA to consider; many IT departments will look nervously at the long list of Kerberos configuration tasks and may resist the approach in terms of the effort, expertise and deployment cost involved.

To be compelling services such as SIC need to be simple and reasonably non-technical to install and run. SIC achieves this nicely for the run aspect, for the install aspect there’s some room for improvement. For many organisations the installation experience will not be an issue, the focus will be on the end-user experience and the administrative functionality, in these areas Salesforce Identity Connect looks a solid offering.

Links
Really good, short walk through video on YouTube

Implementation Guide PDF

Salesforce Implementation Game Plan

Whether you’re managing a commercial software development, leading a consultancy project or building an IKEA table a game plan is absolutely key to successful delivery. In the latter example IKEA recognises the importance of prescriptive guidance and supplies an instruction leaflet in the box. This however covers only one dimension of successful delivery, the ‘What’ (i.e. what you need to do) – the ‘Who’, the ‘How’ and the ‘When’ are left up to you. In the case of an IKEA table this is acceptable as the resource is probably you (who will likely build the table in your own way regardless of advice received) and the timeline may not be critical. Moving away from this tenuous example, in non-trivial situations all the dimensions of successful delivery are equally significant and must combine cohesively to achieve the defined objective. This calm, controlled, empowering and productive state is precisely what planning is intended to achieve. This success delivery-state is rarely the norm, for various reasons; inexperience, over-optimism, command and control culture, inadequate expertise, process rigidity, poor communication etc. The net effect of such factors being a distress delivery-state where productivity is low and the sense of team is diminished in terms of empowerment, trust and accountability.

Like many people I often find myself misquoting Leo Tolstoy, who didn’t say that failing projects fail for a variety of reasons but succeeding projects succeed for the same reason. He did say this however – “All happy families are alike; each unhappy family is unhappy in its own way.” (Leo Tolstoy, Anna Karina) – where the interpretation comes from. I definitely read this somewhere, apologies if this was your book or blog.

So the idea is that all successful projects succeed for the same reason – that reason being in my view that the project was able to achieve a success delivery-state, i.e. the plan encompassed all the requisite dimensions and maintained the agility to react and adapt during flight. In this context it matters little which project process, methodology, framework etc. you employ what matters is that you have a well conceived plan from the outset, or game plan as I like to call it, and execute on that plan in a disciplined manner.

A game plan can take many forms (spreadsheet, picture, diagram, A3 sheet pinned to the wall etc.) whichever way you go the end result should be an engaging, high-level fusion of vision and planning and be tuned for effective communication to your specific audience.

The game plan should influence the detailed planning, but is a higher level concern that outlines the fundaments of how the project will succeed, covering the essential aspects only. My preference in the past has been an annotated timeline diagram, showing clearly the basis upon which I’m confident of success – this can be highly effective in terms of establishing confidence within the delivery team and across stakeholders. I don’t believe this is possible with a Gantt chart or spreadsheet, even where progression metrics are added.

By way of illustration the following sections outline an example Game Plan related to a fictitious Salesforce implementation project.

gameplan example

In summary, the game plan concept applied to project delivery can be a powerful tool. It matters little how the game plan is presented or what it contains, simply having one in any form can make a big difference in terms of confidence, focus and communication.

Salesforce Communities at a Glance

This long overdue post provides a quick review of the Salesforce Communities functionality which became GA in the Summer ’13 release.

In my simplistic view Salesforce Communities is a way to bring external users directly into a Salesforce org in a restricted manner with a branded user-experience. This may be for collaboration purposes in the social enterprise sense (i.e. Chatter) or simply to extend a business process out to external parties.

In user license terms a single Community can support internal users and both customer and partner users – a key differentiator from the preceding portal functionality, where portals were limited to either customers or partners with no internal user access. A highly customised portal experience can be delivered using Force.com Sites (and Visualforce etc.), as per the traditional manner – or via Site.com, with its rich drag-and-drop build model. In both cases unauthenticated and authenticated interactions can be delivered. With Communities however the traditional (I mean outdated) portal look-and-feel is replaced with the standard Salesforce aesthetics, with the option to customise the header, footer and colour palette. It’s also straightforward to deliver a branded login page on a custom URL. All in all I think Communities provides a great advancement in terms of delivering branded, collaborative customer/partner interactions using the declarative build tools. Add to that the full collaborative power of Chatter and the Communities proposition is a compelling one.

Salesforce Communities

Communities 1

A very basic Community in preview mode – note the custom colour palette. The rather invasive Global Header can also be seen, thankfully this is now optional page furniture.

Communities 2

Chatter email branding – a previous pain point with branded Chatter implementations.

Communities 3

Branded login page with Authentication Service buttons.

What is it?
In principle a portal technology, in practice a restricted access entry point to a subset of data and functions from an internal Salesforce organisation – presented with a customised/branded UI and custom url.

Key points.
– Internal and external members. A community can contain members with Partner and Customer Community licenses, internal org licenses and legacy portal licenses.

– Custom URL. Communities can be exposed on a custom domain. The default is a subdomain on the force.com domain as-per Force.com Sites etc. Note, I’m unclear on how this works in terms of SSL, at this time it is not possible to upload a server certificate for a custom domain, therefore SSL isn’t supported. This limiting situation may change imminently, I believe a beta for exactly this type of functionality ran last year.

– Communities are built in Preview status, then published.

– Community tabs can be either Salesforce tabs (custom or otherwise) or provided by Site.com.

– Branded login page (header logo and footer text) – see screenshot. Basic customisation is possible, how effective this is will largely depend on the image etc. The login page supports selection of enabled Authentication Providers.

– Branded UI (header, footer images and colour palette). Again, this is light-touch cosmetic customisation and will work where a minimal brand presence is required – which is advisable for an immersive application.

– Accounts are enabled for Partner Communities. Up to 3 roles can be specified (which are direct children of the Account owner in the role hierarchy – consistent with legacy portal roles. The super user concept is also supported.

– Contacts are enabled for Customer Communities (HVPU – i.e. no role or sharing rules = Sharing Sets and Share Groups).

– Person Account can’t be enabled for Partner Communities. Person Accounts can’t be enabled as Partner Accounts and therefore can’t access partner portals, so this limitation is consistent.

– User Sharing can be used to control who can see who within the Community (as-per the internal org). A useful capability particularly in scenarios where senior employees may wish to observe a community but not be visible to all.

– Communities support self-registration.

– Mobile access enabled.

– Unauthenticated content, or highly customised interactions can be supported by either Force.com Sites or Site.com.

– Force.com Sites pages inherit the Community branding by default.

– Chatter Email Branding. System emails generated by Chatter can be branded in terms of logo and footer text. This removes the Salesforce branding which has historically been problematic with branded Chatter implementations.

– Ideas, Chatter Answers and Salesforce Knowledge can be enabled within a Community.

– Communities supports SSO for internal and external users via the SAML protocol and a SAML enabled Identity provider, or via external service providers (Facebook, Open ID Connect, Janrain and Salesforce).

User Licensing?
Customer Community License – Equates to a High Volume Portal User License (HVPU). Therefore the usual restrictions on HVPU record access apply (no role and no ownership or criteria-based sharing rules). Sharing Sets and Share Groups must be understood when considering an effective record access model.

Partner Community License – Equates to Gold Partner License.

The new Community user license types represent the two extremes of the portal licensing scale, with significant differences in capability and pricing. It is therefore good news that a single Salesforce Community can support both types enabling a blended view to be taken on the license model.

One final observation, the two key pre-requisites to implementing Salesforce Communities are a rigorous audit of the current state security model (record access, profile/permission sets, groups, folders, listviews etc. etc.) and a detailed future state design. In both cases this should cover specifics such as Chatter groups, user-sharing etc.. In my view it’s always better to be proactive and pessimistic when it comes to security.

Salesforce Spring ’14 Highlights

After a short period of blindly exploring a pre-release Spring ’14 org, the release notes are now available.

With Salesforce1 released recently it’s unsurprising that Spring ’14 isn’t a significant release in terms of new features and that a lot of the highlights are currently at Pilot status. I expected a low-key release with incremental improvements to Salesforce1, the usual evolution to Chatter and a number of older pre-release features becoming GA – this would seem to be the case. A few personal highlights below in no particular order, following a quick read of the release notes.

Skills and Endorsements (Pilot) – Skills reference data (ProfileSkill) can be added and associated with People (ProfileSkillUser). The skills profile for a User is displayed on the Chatter profile page and each skill can be endorsed by other users (ProfileSkillEndorsement). Skills can be managed via Chatter or via the Setup pages (Manage Users etc.). Interesting LinkedIn style concept.

Feed-Based Page Layouts – The Case Feed experience now available for Account, Contact, Lead, Opportunity and Custom Objects. The concept here is to split the record feed from the record details via tabs, enabling a more focused view with easy switching. For implementations where Chatter is used extensively at the record level, this provides a convenient efficiency.

Sharing Sets Enhancements (Pilot) – Sharing sets for HVPU now support indirect lookups to Account, Contact, Case, Service Contract, User and Custom Object records. Previously only directly related records to the Account and Contact were accessible, now a second level of related records can be accessed.

Launch Flows from Workflow (Flow Triggers) – A new Flow Trigger Workflow Action has been added which enables UI-less flows to be executed as per standard workflow actions (email, task etc.). This could provide a non-code alternative to Apex Triggers in some cases.

Orders / Place Order REST API – Basic standard objects and accompanying REST API to support the order management process (contract, orders and order products). There doesn’t appear to be any relationship (or automated synchronisation) with Opportunity or Quote. Definitely a feature intended for customisation.

API Limit App Quotas (Pilot) – Connected Apps can have 24 hour API quotas set for standard, bulk and streaming API consumption. I like where this is heading in terms of providing proactive API management tools – up to this point it’s all been reactive.

New User Interface for Monitoring Deployments – Clean new UI to view (and cancel) running deployments made via the metadata API.

Visualforce Remote Objects (Developer Preview) – Data proxies for standard objects that make SObject DML operations directly accessible in JavaScript code without the need for @RemoteAction methods. Another highly useful feature for developing in JavaScript which also avoids API limit consumption (as per JavaScript remoting).

Canvas App Accessible from the Salesforce1 Menu – Force.com Canvas apps can now be placed directly into the Salesforce1 navigation menu. I think we’ll see Canvas becoming a more important technology in the future as integration at the application level becomes more widespread. Where some degree of application blending is achievable, UI-level integration can be significantly less expensive to implement than at the data-level.

Independent Auto-Number Sequence for Unit Tests – It’s always puzzled me as to why the auto-number sequence increments in response to the creation of test data records (which are ultimately rolled-back). Surely, the unit test context should be better isolated? Anyway, with Spring ’14 we can now set the flag below to achieve this.

Develop->Apex Test Execution->Options->Independent Auto-Number Sequence

Usage Metrics (Pilot) – ISVs can now access the following metrics (via API only) per subscriber org:

Record count for custom objects
Access count for Visualforce pages (over the last 24 hours)

This feature requires an Environment Hub setup, with one org designated as the reporting org where the metrics are delivered. This long awaited feature will be well received by the ISV community.

View and Manage User Sessions – View and invalidate (end) user sessions as required. A useful administrator feature.

Mass Assign Permission Sets – At long last users can be assigned-to and removed-from Permission Sets en-masse. Previously this was a painful user-at-a-time process.

Analytics API Available in Apex – All the capabilities of the REST Analytics API are now available directly to Apex, enabling reports to run etc. (..Reports.ReportManager.runReport(myReportId)..).

Salesforce Platform Limits – Designing for Scale

A Salesforce instance is a constrained environment where limits exist in respect to capacity and execution. Examples of capacity limits being data storage, number of active users, number of custom objects/custom fields/picklists etc. examples of execution limits being API calls per 24-hour period, SOQL queries executed within an Apex transaction, Viewstate size in Visualforce pages etc.. In both the capacity limit and execution limit case it is imperative that the existence and implications of the constraints are factored into the solution design from the outset. Each and every constrained resource must be treated as a precious asset and consumed in an optimised manner even on seemingly trivial implementation projects. From experience it is often the case that a Salesforce implementation grows (in terms of both use and breadth of functionality) at a rapid rate once it gains traction in an enterprise. If you’ve carelessly exhausted all the constrained resources in the first release, what happens next? Note, some soft limits can be increased by Salesforce on a discretional or paid-for basis, however this doesn’t negate the need to make responsible design decisions and at the very least the highlight the possible additional cost associated with a particular approach. Hard limits do exist in key areas, the Spanning Relationships Limit or cross-object reference limit as it also referred is a strong example of this.

Designing for scale simply requires an intelligent consumption of such resources and appropriate solution design decisions in a limited number of areas. The proliferation of Apex and Visualforce related execution limits don’t necessarily impact the scalability of the implementation, the impact is isolated to the micro level. The selected limits listed below however apply at the org level (Salesforce instance) and can constrain the scalability of an implementation (in functional terms). This list is not exhaustive, for a complete picture refer to the Salesforce Limits Quick Reference Guide.

Limits Primarily Influenced by User License Model

Asynchronous Apex Method Executions :
This limit includes @futures, Batch Apex (start, execute and finish method invocations and Scheduled Apex (execute method invocations). Future method calls made from Apex Triggers can be a risk in relation to this limit. For example, Apex Triggers which fire on record updates which make callouts via @futures can cause scalability issues as data volumes grow. In this example it may become necessary to bulk process the modifications via Batch Apex, assuming a batch style of integration is acceptable. What if near real-time (NRT) is necessary?

The calculated limit is the higher number of 250K or (200 * user license count), where the applicable licenses to this calculation are full Salesforce and Force.com App Subscription only.

Total API Request Limit :
Enterprise Edition = 1,000 per Salesforce and Salesforce platform license, 200 for Force.com App subscription license
Unlimited/Performance Edition = 5,000 per Salesforce and Salesforce platform license, 200 per Force.com app subscription license

Note, sandboxes have a flat limit of 5M which can give a false impression of the limits applied in production.

All inbound API traffic counts towards this limit, including Outlook plug-ins, Data Loader etc. For implementations with limited Standard users this limit can be restrictive, and it is reasonably common for extension packs to be purchased to mitigate this. In all cases consumption must optimised by batching updates and use of the Bulk API where possible.

Limits Primarily Influenced by Salesforce Edition

Workflow Time Triggers Per Hour :
Enterprise Edition = 500
Unlimited/Performance Edition = 1000

This limit can be an issue for implementations with high volume transaction processing throughputs, where time-based workflow is employed to send reminder emails etc. If the hourly limit is exceeded triggers are processed in the next hour and so on. This may cause issue if the actions are time critical.

Workflow Emails Per Day :
1,000 per standard Salesforce license, capped at 2 million.

Apex Emails Per Day:
1,000 in total. The maximum message count per send is limited per edition.
Enterprise Edition = 500
Unlimited/Production Edition = 1000

An unlimited number of emails can be sent per day to Users by using the SingleEmailmessage.setTargetObjectId() and MassEmailmessage.setTargetobjsctIds() methods. This includes customer and partner portal users and even high volume portal users.

This limit is critical to understand and to mitigate in a scalable solution design. In short don’t use Apex to send email unless the recipient is a User. In portal cases use the User Id and not the Contact Id. Prefer Workflow based email sending, as the limits Are considerably higher, and perhaps use Apex script to set criteria picked up by a Workflow rule.

Additional Limits to Consider

Batch Apex (5 pending or active)
Scheduled Jobs (100 scheduled)
Apex Script Characters (3M)
Dynamic Apex Describes
Cross Object References

From a best practice perspective a Platform Limits Reference document should be maintained for all Salesforce implementations that lists the applicable limits and related consumption. This approach surfaces the existence of the limits and should provide design principles such as using Workflow to send customer emails in preference to Apex script. Without an ordered approach where limit consumption is proactively tracked it is highly likely that expensive refactoring exercises or multi-org strategies become necessary over time that could have been minimised,deferred or entirely avoided.

Salesforce1 App Customisation

At the time I started writing this post we were living in a Chatter Mobile world, this is no longer the case. As announced recently at Dreamforce ’13 we have entered the Salesforce1 era, the direction of which will no doubt become clearer as we transition to the Spring ’14 release. What is clear now however is that the unified platform is the focus this time, providing mobile enablement (apps) via a rich set of platform services (APIs x 10). A rich set of robust APIs is always great news for any development community, whether you’re connecting a mobile device or sensor device (IoT). I won’t venture further into what Salesforce1 is in concept or the implications, some of this is yet to be seen. In any case this blog is focused on the practical application of the Salesforce and Force.com technologies, and as such the following summary is a point-in-time outline of the information available at the time of writing.

So, on to the topic in hand, customisation options for the Salesforce1 mobile application.

As with most things in life, to make good design decisions it helps to understand the full set of options available (and to see the big picture). This obvious point is fundamental in architecting Salesforce platform solutions; it’s key to have knowledge of the complete standard feature set and extension points (declarative build model) such that technical solution components are minimised. Simply put, in the mobile context this guiding principle means exhaust the potential of the standard apps (meaning Salesforce1) and the customisation options before building a new custom mobile app from scratch.

The following summary notes attempt to clarify the function of the Salesforce1 app and the various customisation options.

The Salesforce1 App – What is it?
In application development terms the Salesforce1 app provides a flexible mobile container into which a blend of standard and custom functionality can be presented on a variety of connected devices (mobile, tablet etc.). The container itself comes in 2 forms; downloadable native app (iOS and Android) and mobile browser app. In either form Salesforce1 employs a feed-first paradigm, with publisher actions and a notification platform. The mobile browser app must be enabled from the setup menu under Mobile Administration->Salesforce1 and becomes the default when accessing Salesforce from supported devices (as-per Salesforce Touch). Salesforce1 does not replace the standard Salesforce web app, or Full Site as it is referred. Salesforce1 does replace Salesforce Touch, Chatter Mobile and Salesforce mobile apps.

Ok, so assuming we’re comfortable with the idea that Salesforce1 is a application container, how can we extend the functionality of the container to deliver custom application interactions?

Customisation Options
The following summary notes attempt to clarify the customisation options available with the Salesforce1 mobile app. Also included in the list are standard capabilities of the container app, provided for completeness. The Salesforce1 App Development Guide provides a comprehensive coverage of the topics including example code that can be loaded into a development org (via github) to experiment with.

— Mobile Navigation
Within the setup menu under Mobile Administration, the Mobile Navigation option provides the ability to define the content and structure of the left hand side menu of the container app (as shown in the screenshot below).

Salesforce1 Tablet

Note. The first item in the list becomes the home page.

— Custom Objects (declarative)
Self explanatory. Recently searched for objects appear under the Recent section in the mobile menu structure according to profile permissions. It would appear that page layouts are shared between Salesforce1 and the standard Salesforce web app. This may prove difficult in terms of providing a balanced structure that is effective in both views.

— Flexible Page Tabs (declarative and technical)
I’m not 100% clear on the use cases for Flexible pages, however they do exist and can be added to Flexible page Tabs and ultimately rendered in the container app via inclusion in the menu structure (via Mobile Navigation). I need to do some further investigation into the potential of Flexible Pages, perhaps I’m missing something obvious.

A Flexible Page can have global publisher actions, list views and scoped recently used items. A maximum of 25 components can be added to the page, this constraint applies to listviews and recently used items.

In terms of definition a Flexible page is manually created in XML and deployed to an org via the Force.com Migration Tool or IDE. Once a Flexible page exists in an org the Create->Tabs page will present a Flexible Page Tabs list (as per Visualforce tabs etc.).

— Publisher Actions (declarative and technical)
Publisher actions are accessed via the (+) button on the home page, Chatter tab, Chatter group and record detail pages.

Actions can be Standard or Custom and Global or Object scoped.

Standard actions include;
Create a Record – respects Validation Rules etc. A Create action defined for a object will automatically relate created child records.
Log a Call – record a completed Task
Update – update a record from the Chatter feed

Default standard actions are provided for the core standard objects (create and update), such actions have configurable layouts and the ability to predefine field values.

Custom actions include;
Visualforce pages
Canvas apps

Interestingly actions can be described and invoked via the REST API, resource paths below.
/services/data/v29.0/quickActions (Global)
/services/data/v29.0/sobjects/[object]/quickActions (Object)

— Compact Layouts (declarative)
Compact layouts are defined at the object level and are simply an ordered list of fields by definition. Compact layouts apply in the following areas;

Record highlights fields (first 4 fields in the ordered field list). The record highlights are displayed in the top region of a record detail display under the icon.
Defines the fields that appear in the Chatter feed if a record us created via publisher action.
Enhanced lookup mobile card (more on this below)
Object record preview card

— Mobile Cards (declarative)
Page layouts now have a section for Mobile Cards, the following items can be added which then appear as a swipe-to card within the record detail view within the Salesforce1 app only.

Visualforce Page
Expanded Lookup. Related object (via Lookup) Custom Layout fields are displayed.

— Visualforce Pages (technical)
There are a number of extension points within the Salesforce1 app where Visualforce pages can be employed.

Mobile Card
Custom Publisher Action
Visualforce Tab added to the Mobile Navigation

In all cases the page must be mobile enabled and designed specifically for rendering on constrained devices, i.e mobile plus tablet on a variety of form factors. A best practice to consider in this respect is the development of adaptable pages that support both Salesforce1 and standard Salesforce web app execution. There are 3 development models in this respect classic Visualforce, Visualforce mixed with JavaScript, JavaScript and static HTML only with JS remoting. In all models the recently added (to Visualforce) ability to pass through attributes (HTML5) will be of use. Additionally, Salesforce1 comes with a highly useful navigation framework JavaScript library.

In short, where branded or complex UI interactions are required Visualforce provides a good option. Such pages must be carefully designed to deliver a optimal mobile experience and where possible be adaptable to also work in the standard Salesforce web app. This latter point relates to the cost of development and maintenance, adaptability is better than duplication – at the cost of smart design.

— Force.com Canvas Apps (technical)
There are a number of extension points within the Salesforce1 app where Force.com Canvas apps can be employed. Pilot program currently.

Custom Publisher action – post to the feed from a Canvas app
Chatter Feed – Canvas app rendered in a feed item

The use cases for the above will be varied and no doubt very interesting. Over time I think we’ll see more traction in the area of application composition. The ability to compose experiences and interactions across applications seamlessly (with context) and securely is a powerful concept.

— Smart Search Items
Recently searched for objects for the user. Searches performed in the full web app appear can appear In the left navigation menu, pin objects in the full site to keep at the top of this list.

— Notifications (declarative)
The Salesforce1 notifications platform supports 2 types of notification;

In App – Appear in the app itself and can be accessed manually via the bell icon (top right hand corner)
Push – Mobile device applications only, push notifications not supported by the mobile browser app. Such notifications will appear as badges on the app icon etc.

The notifications are limited to Chatter (mentions, posts, comments etc.) and Approval requests. Notifications are enabled at the org-level, not per-user.

Final Thoughts
In application development terms, Salesforce1 provides a rich set of declarative and programmatic techniques for the development of mobile interactions. Building out compelling mobile experiences that replace or augment existing Saleforce functionality (custom or standard) should be highly achievable whether you’re technically minded or not. This in my view is the real power of the Saleforce1 app, once you accept the proprietary approach there are no barriers to rapid mobile enablement.

Salesforce Certified Architect – Value Proposition

A real challenge for all Salesforce Architects is keeping up-to-date on the constantly evolving native platform capabilities and customisation/extension points. It’s a truism that nothing stands still, this is especially true in the Salesforce world, with 3 releases a year, frequent off-cycle incremental feature enhancements, acquisitions etc. etc.. This constant evolution is of course great for Salesforce customers, the potential return on investment in respect to business value derivable from the license spend grows in parallel. The business challenges in this respect are those of understanding the potential, making appropriate tactical design and implementation decisions and rationalising a sensible and adaptable strategic roadmap.

In order to address these challenges, and mitigate the consequential risk of not doing so, the business must have access to experienced Salesforce architects with a deep understanding of the current Salesforce release and future product roadmap. This is a difficult proposition where competent Salesforce architects are currently a small community (which is expanding year-on-year) and those that exist are typically occupied in solution delivery not strategic advisory roles.

My advice to any business using Salesforce for anything beyond an out-of-the-box CRM implementation is to engage, or employ, a Salesforce Certified Technical Architect (CTA). This stringent accreditation provides the highest degree of assurance that the individual really understands the Salesforce platform and can provide the right guidance around platform potential (vision), tactical design decisions, strategic roadmap, platform governance and development process. Given that the number of CTA is a small subset of the Salesforce architect community this would seem an impossible task, however there is a growing number of CTAs to be found in the Salesforce partner community and via Salesforce Strategic Services (i.e. salesforce.com). An alternative approach would be to invest in an internal resource and provide the opportunity to advance through the Salesforce certifications step-by-step advancing up to the CTA level. This approach will take time, measured in years not months, and is not without risk, internal resources may lack the breadth of exposure to the Salesforce platform gained through (perhaps) more diverse consultancy projects. Additionally, as an internal CTA is a highly valuable asset to any business, it may be difficult to retain their services.

The CTA should be considered a strategic advisor not an implementation resource, and given the following type of accountabilities:

1. Upfront. Data Architecture (data model, quality management processes etc.).
2. Upfront. Integration Architecture (logical and physical architecture, integration patterns, protocols, tools and technologies).
3. Upfront. Standards. Technical standards, conventions and construction patterns.
4. Upfront. Development process. Methodology guidance. Platform governance. Release management and source code control. Environment strategy. Change management. Risk management.
5. Upfront and ongoing. Solution Design. Exploitation and augmentation of standard features, solution options for gaps.
6. Ongoing. Quality Assurance. Build reviews. Tactical advice on solution build.
7. Ongoing. Quality Assurance. Testing strategy guidance.
8. Ongoing. Strategic advisory. Communication of platform potential and new capabilities to project stakeholders.
9. Ongoing. Guidance on fit between new business requirements and Salesforce. High level estimation and project scoping. Vendor cost assessment.
10. Ongoing. Strategic advisory. Strategic roadmap definition and communication.

Taking the 10 preceding points as indicative, the overarching principles are that the CTA sets the scene for a successful implementation, underwrites the delivery through periodic review and quality assurance processes and finally defines the strategic roadmap. Taking each point in turn; setting the scene is perhaps the most critical aspect as a flawed data model, inaccurate mapping of business requirement to native feature, inexpert selection of solution options to plug the gaps etc. can be incredibly cost expensive to rectify at a later date or impossible to remediate. Underwriting the delivery is perhaps the least well defined area, but at a minimum the CTA should be engaged to review progress and take design decisions required while the implementation is in flight. Additional to this should be a retrospective consideration of the development process, project standards etc. which a view to adaptation in light of findings established via practical application. Finally the strategic roadmap aspect to the CTA value proposition is imperative in ensuring that the Salesforce implementation is sustainable, integral to the organisation’s enterprise architecture and evolving to drive the maximum business value from the investment over time in response to defined or emerging business goals.

In summary, a high degree of expertise applied at the start of a project and on a periodic basis can increase greatly the chances of a successful and cost effective Salesforce implementation. Most projects won’t have access to a full time CTA, for cost or availability reasons, however, most projects should consider a part-time CTA in an advisory role, like a good tax accountant they should pay for themselves.

Salesforce to Salesforce – A Short Case Study

First of all let me be clear on one thing, I’m a big advocate for Salesforce-to-Salesforce, for many org-to-org data convergence/integration use cases S2S is an efficient, cost effective solution.

Over the last couple of years I’ve had the pleasure to work with a non-profit organisation, via the Salesforce foundation, on an interesting use case for data integration with Salesforce to Salesforce. I won’t disclose the organisation name or the nature of the data in play; this isn’t relevant directly to the purpose of this post which is to concisely outline the integration pattern. Hopefully in considering this short case study, the potential of S2S for multiple-org architectures and other record sharing use cases will be clear. S2S isn’t just for sharing Leads and Opportunities!

Case Study Context
The organisation provides a variety of support services, both directly to individuals and also to other charitable organisations. In respect to individuals, external partners/providers are utilised in service delivery.

In this context Salesforce is implemented as a data hub tracking individuals and the services they receive from external providers by location. This aggregation of data enables a 360 degree (or holistic) view to be taken on the support individuals are receiving. The primary challenge in delivering this view has been the implementation of a consistent and controlled aggregation of data across external providers. To address the consistency aspect the organisation developed a managed package containing the required custom objects for the service provider to populate, and advises on Salesforce implementation. To address the data integration challenge, the initial implementation approach employed middleware technology to extract, transform and load data from the multiple provider orgs into the central hub org. For a number of reasons (including cost, complexity, requisite expertise) the middleware approach to data aggregation didn’t provide a sustainable solution. Having in-house Salesforce expertise, the organisation identified Salesforce to Salesforce as a potential option to deliver a simplified data aggregation solution built on native Salesforce functionality.

Solution Outline
S2S 2

Technical challenges
To understand the requisite implementation steps for S2S, refer to the help documentation. In summary objects and fields are published from one org and subscribed to in another org in the context of an established partner connection. This configuration takes place within standard functionality using the Connections tab. The partner connection is established through a connection request (via email verification link) initiated from one of the orgs. Once the partner connection, publications and subscriptions are configured records can be shared manually with various UI elements added in both orgs to indicate the external sharing status. Note, the relationship between the two orgs within a partner connection is bi-directional, both orgs can define publications and subscriptions.

Whilst S2S fully automates the synchronisation of records between publications and subscriptions, there are a number of areas where complementary technical customisation can be required.

1. Automated record sharing.
S2S requires records to be manually shared, in many cases it is preferable to automate this via Apex Trigger script. Basic example below demonstrating how record Ids can be inserted into the PartnerNetworkRecordConnection standard object to initiate sharing. Note, the PartnerNetworkConnection standard object holds the connection details.

[sourcecode language=”java”]
trigger AccountAfterInsert on Account (after insert) {
if (!S2S_Configuration_Setting__c.getInstance().External_Sharing_Active__c) return;
if (S2S_Configuration_Setting__c.getInstance().Org_Connection_Name__c==null) return;

String connectionId = S2SConnectionHelper.getConnectionId(S2S_Configuration_Setting__c.getInstance().Org_Connection_Name__c);
if (connectionId==null) return;

Map<Id,SObject> idToAccount = new Map<Id,SObject>();
for (Account a : Trigger.new){
if (a.ConnectionReceivedId==null){
idToAccount.put(a.Id, a);
}
}
S2SExternalSharingHelper.shareRecords(idToAccount, connectionId, null);
}

public with sharing class S2SExternalSharingHelper {
public static void shareRecords(Map idToSObject, Id connectionId, String parentFieldName){
try {
List shareRecords = new List();

for (Id i : idToSObject.keySet()){
String parentRecordId;

if (parentFieldName!=null) {
SObject o = idToSObject.get(i);
parentRecordId = (String)o.get(parentFieldName);
}

PartnerNetworkRecordConnection s = new PartnerNetworkRecordConnection(ConnectionId = connectionId,
LocalRecordId = i,
ParentRecordId = parentRecordId,
SendClosedTasks = false,
SendOpenTasks = false,
SendEmails = false);
shareRecords.add(s);
}

if (shareRecords.size()>0) insert shareRecords;
} catch (Exception e){
//& always add exception handling logic – no silent failures..
}
}
}
[/sourcecode]

2. Re-parenting records in the hub org.

Parent-child record relationships must be re-established in the target org, this does not happen automatically. To do this a custom formula field can be added to the shared record which contains the parent record identifier as known in the source org – lookup fields can’t be published. This custom formula field (ParentIdAtSource__c for example) is published to the connection. In the target org this field is mapped in the subscription to a custom field. An Apex Trigger can then be used to lookup the correct Id for the parent record as known in the target org which can then set the related relationship field value. Specifically the logic should query the PartnerNetworkRecordConnection object for the LocalRecordId which matches the PartnerRecordId value held in the custom field.

3. Record merges in the source org.

In the record merge case the update to the surviving parent record flows via S2S without issue, re-parented child records however do not. To address this an Apex Trigger (on delete of the parent record) can be used to “touch” the child records as shown in the basic example below.

[sourcecode language=”java”]
trigger AccountBeforeDelete on Account (before delete) {
try {
if (Trigger.isBefore && Trigger.isDelete) {
// call @future method to do a pseudo update on the contacts so that the reparenting flows via S2S
List<Contact> contactsToUpdate = [select Id from Contact where Accountid in :Trigger.old];
Map<Id,Contact> idToContact = new Map<Id,Contact>();
idToContact.putAll(contactListForUpdate);

if (idToContact.keySet().size() > 0) {
S2SExternalSharingHelper.touchContactsForAccountMerge(idToContact.keySet());
}
}
} catch (System.Exception ex) {
//& always add exception handling logic – no silent failures..
}
}

@future
public static void touchContactsForAccountMerge(Set<Id> contactIds) {
List<Contact> contactList = [SELECT Id FROM Contact Where id in :contactIds];
database.update(contactList,false);
}
[/sourcecode]

4. Data clean-up.

Record deletions are not propagated via S2S instead the Status field in the PartnerNetworkRecordConnection object is set to ‘Deleted’ with no further action taken. A batch process in the target org may add value in flagging such records for attention or automating deletion.

5. Unit test coverage.

Unfortunately, the PartnerNetworkConnection object is not creatable (insertable), therefore unit test code is reliant on the existence of an active connection in the org. The ConnectionReceivedId field on standard and custom objects is also not createable or updateable, requiring shared records to be in place (and SeeAllDate=true) in order to test custom functionality in the target org. Not ideal.

Note, S2S record sharing interactions count against standard API limits and speed of update is not guaranteed. In my experience the updates are typically sub 5 seconds latency. My understanding is that the underlying synchronisation process runs on a polling schedule and therefore the speed of update will vary based on the distance to the next poll cycle.

Useful Links
An Introduction to Salesforce to Salesforce
Best Practices for Salesforce to Salesforce