Newer Version Available
PackageSubscriber
Represents an installation of a package in an org. This object
contains installation information for managed packages developed in the org you’re
logged in to.
One record is created per installation. For example, if 5 orgs installed 2 packages, 10 records are created.
Supported Calls
describeSObjects(), query(), retrieve()
Fields
| Field Name | Details |
|---|---|
| InstalledStatus |
|
| InstanceName |
|
| MetadataPackageVersionId |
|
| OrgKey |
|
| OrgName |
|
| OrgStatus |
|
| OrgType |
|
Usage
Here are examples of the types of API queries you can perform.
| Query | String |
|---|---|
| Get all package subscriber orgs with a specific package ID | SELECT Id, OrgKey, OrgStatus, OrgName, OrgType FROM PackageSubscriber WHERE MetadataPackageVersionId = '04t...' |
| Get all package subscriber orgs that have an installed package created by the org you’re logged in to | SELECT Id, OrgKey, OrgStatus, OrgName, OrgType FROM PackageSubscriber WHERE InstalledStatus = 'i' |
Filter PackageSubscriber Objects by Instance
If you have packages with many subscribers, querying PackageSubscriber objects can take a while. To improve query performance, add filters to your PackageSubscriber queries, such as an InstanceName filter. InstanceName is a field that represents the instance that the subscriber org is hosted on.
- Get the org’s managed package and the latest released version of the
package.
1/** 2* Get the MetadataPackage object corresponding to this org's managed package 3*/ 4public MetadataPackage getMetadataPackage() throws ConnectionException { 5 // retrieve the managed package, which won’t have an empty namespace 6 QueryResult result = conn.query("select id from MetadataPackage where namespaceprefix <> ''"); 7 8 return (MetadataPackage) result.getRecords()[0]; 9} 10 11/** 12* Get the latest MetadataPackageVersion object of the given MetadataPackage 13*/ 14public MetadataPackageVersion getLatestMetadataPackageVersion(MetadataPackage metadataPackage) 15throws ConnectionException { 16 // get the latest released version of the given package 17 String query = "Select id, ReleaseState, MajorVersion, MinorVersion, PatchVersion, 18MetadataPackageId" 19 + " From MetadataPackageVersion" 20 + " Where MetadataPackageId = '%s' and ReleaseState = 'Released'" 21 + " Order by majorversion desc, minorversion desc, patchversion desc"; 22 23 QueryResult result = conn.query(String.format(query, metadataPackage.getId())); 24 25 return (MetadataPackageVersion) result.getRecords()[0]; 26} - Get eligible subscribers. The following query strings and methods are modified
to allow querying for PackageSubscribers filtered by an
instance.
1static final String PACKAGE_SUBSCRIBER_ORG_KEY_QUERY = "Select OrgKey from PackageSubscribers where OrgStatus = 'Active'" 2 + " and InstalledStatus = 'I'" 3 + " and InstanceName = '%s'"; // placeholder for instance values 4 5static final String METADATA_PACKAGE_VERSION_QUERY = "Select Id, Name, ReleaseState, (%s) from MetadataPackageVersion" 6 + " where MetadataPackageId = '%s' AND ReleaseState = 'Released'" 7 + " AND (MajorVersion < %s OR (MajorVersion = %s and MinorVersion < %s)" 8 + " OR (MajorVersion = %s and MinorVersion = %s and PatchVersion < %s))"; 9 10/** 11* Get all PackageSubscribers on the given instance that are eligible to upgrade to the given 12* MetadataPackageVersion 13*/ 14public PackageSubscriber[] getEligibleSubscriberIds(MetadataPackageVersion version, String instanceName) throws ConnectionException { 15 String allPackageId = version.getMetadataPackageId(); 16 Integer major = version.getMajorVersion(); 17 Integer minor = version.getMinorVersion(); 18 Integer patch = version.getPatchVersion(); 19 20 return getEligibleSubscriberIds(major, minor, patch, allPackageId, instanceName); 21}1public PackageSubscriber[] getEligibleSubscriberIds(Integer major, Integer minor, Integer patch, String packageId, String instanceName) throws ConnectionException { 2 String subscriberQuery = String.format(PACKAGE_SUBSCRIBER_ORG_KEY_QUERY, instanceName); 3QueryResult results = conn.query(String.format(METADATA_PACKAGE_VERSION_QUERY, 4subscriberQuery, packageId, major, major, minor, major, minor, patch)); 5 6 return Arrays.stream(results.getRecords()).map(MetadataPackageVersion.class::cast) 7 .filter(mpv -> mpv.getPackageSubscribers() != null) 8 .flatMap(mpv -> Arrays.stream(mpv.getPackageSubscribers().getRecords())) 9 .map(PackageSubscriber.class::cast) 10 .toArray(PackageSubscriber[]::new); 11} - Put it all together. The following code sample shows how to use the previous methods to
modify the workflow to perform package pushes by
instance.
1String[] instances = { "NA4" }; // Here we list the instances we would like to push to 2MetadataPackage metadataPackage = api.getMetadataPackage(); 3MetadataPackageVersion version = api.getLatestMetadataPackageVersion(metadataPackage); 4 5// do pushes by instance to avoid API timeouts retrieving PackageSubscribers 6for (String instanceName : instances) { 7PackageSubscriber[] eligibleSubscribers = api.getEligibleSubscriberIds(version, 8instanceName); 9 10// ... proceed with creating PushRequests and PushJobs as before