/// <summary>
        /// Replace the RelyingParty encryption keys with a new set of keys from a metadata update.
        /// </summary>
        static void UpdateRelyingPartyMetadata()
        {
            ManagementService svc = ManagementServiceHelper.CreateManagementServiceClient();

            Console.WriteLine(String.Format("Reading metadata from file '{0}'...\n", RPMetadataForUpdate));
            using (FileStream fileStream = new FileStream(RPMetadataForUpdate, FileMode.Open))
            {
                //
                // Note that this sample uses EntityID to correlate between the relying party originally imported
                // and the relying party to update.
                //
                EntityDescriptor        metadata = ReadMetadata(fileStream);
                List <X509Certificate2> rpKeys   = ExtractX509CertificatesFromMetadata <ApplicationServiceDescriptor>(metadata, KeyType.Encryption);
                string       relyingPartyName    = GetEntityName(metadata);
                RelyingParty relyingParty        = svc.GetRelyingPartyByName(relyingPartyName, true);

                Console.WriteLine(String.Format("Updating metadata for relying party '{0}'...\n", relyingPartyName));

                //
                // For the purposes of this sample, the existing keys are simply deleted and new ones added.
                // Metadata contains more information such as endpoint addresses.
                // Updating the remainder of these attributes is left as an exercise to the reader.
                //
                DeleteExistingRelyingPartyEncryptingKeys(svc, relyingParty);
                InsertRelyingPartyEncryptingKeysFromMetadata(svc, rpKeys, relyingParty);

                //
                // SaveChangesOptions.Batch guarantees a transaction across all operations prior to this call. This
                // is important because on a running service, the update must happen atomically or service calls may fail.
                //
                svc.SaveChangesBatch();
            }
        }
        /// <summary>
        /// Replace the IdentityProvider signing keys with a new set of keys from a metadata update.
        /// </summary>
        static void UpdateIdentityProviderMetadata()
        {
            ManagementService svc = ManagementServiceHelper.CreateManagementServiceClient();

            Console.WriteLine(String.Format("Reading metadata from file '{0}'...\n", IDPMetadataForUpdate));
            using (FileStream fileStream = new FileStream(IDPMetadataForUpdate, FileMode.Open))
            {
                //
                // Note that this sample uses EntityID to correlate between the identity provider originally imported
                // and the identity provider to update.
                //
                EntityDescriptor        metadata  = ReadMetadata(fileStream);
                List <X509Certificate2> idpKeys   = ExtractX509CertificatesFromMetadata <SecurityTokenServiceDescriptor>(metadata, KeyType.Signing);
                string           issuerName       = GetEntityName(metadata);
                IdentityProvider identityProvider = svc.GetIdentityProviderByName(issuerName, true);

                Console.WriteLine(String.Format("Updating metadata for issuer '{0}'...\n", issuerName));

                //
                // For the sake of simplicity, the existing keys are simply deleted and new ones added.
                // Metadata contains more information such as endpoint addresses, claim types issued, etc.
                // Updating the remainder of these attributes is left as an exercise to the reader.
                //
                DeleteExistingIdentityProviderSigningKeys(svc, identityProvider);
                InsertIdentityProviderSigningKeysFromMetadata(svc, idpKeys, identityProvider);

                //
                // SaveChangesOptions.Batch guarantees a transaction across all operations prior to this call. This
                // is important because on a running service, the update must happen atomically or service calls may fail.
                //
                svc.SaveChangesBatch();
            }
        }
        /// <summary>
        /// Import the relying party from metadata using a call to the management service.
        /// </summary>
        static void ImportRelyingPartyMetadata()
        {
            ManagementService svc = ManagementServiceHelper.CreateManagementServiceClient();

            Console.WriteLine(String.Format("Reading metadata from file '{0}'...\n", RPMetadataForImport));
            using (FileStream fileStream = new FileStream(RPMetadataForImport, FileMode.Open))
            {
                EntityDescriptor metadata         = ReadMetadata(fileStream);
                string           relyingPartyName = GetEntityName(metadata);
                svc.DeleteRelyingPartyByNameIfExists(relyingPartyName);
                svc.SaveChangesBatch();

                // Import the relying party from metadata.
                Console.WriteLine(String.Format("Importing metadata for relying party '{0}'...\n", relyingPartyName));
                fileStream.Seek(0, SeekOrigin.Begin);
                svc.ImportRelyingPartyFromStream(fileStream);
            }
        }
        /// <summary>
        /// Import the identity provider from metadata using a call to the management service.
        /// </summary>
        static void ImportIdentityProviderMetadata()
        {
            ManagementService svc = ManagementServiceHelper.CreateManagementServiceClient();

            Console.WriteLine(String.Format("Reading metadata from file '{0}'...\n", IDPMetadataForImport));
            using (FileStream fileStream = new FileStream(IDPMetadataForImport, FileMode.Open))
            {
                EntityDescriptor metadata   = ReadMetadata(fileStream);
                string           issuerName = GetEntityName(metadata);
                svc.DeleteIdentityProviderIfExists(issuerName);
                svc.SaveChangesBatch();

                // Import the identity provider from metadata.
                Console.WriteLine(String.Format("Importing metadata for issuer '{0}'...\n", issuerName));
                fileStream.Seek(0, SeekOrigin.Begin);
                svc.ImportIdentityProviderFromStream(fileStream);
            }
        }
        /// <summary>
        /// Extract the certificates for a specific role and use.
        /// </summary>
        /// <typeparam name="T">The derived type from RoleDescriptor which represents the role this entity is using to participate in the federation.</typeparam>
        /// <param name="metadata">EntityDescriptor representing the entity.</param>
        /// <param name="keyType">Usage for the certificate.</param>
        /// <returns>The list of certificates associated with the role and usage the entity is using to participate in the federation.</returns>
        static List <X509Certificate2> ExtractX509CertificatesFromMetadata <T>(EntityDescriptor metadata, KeyType keyType) where T : RoleDescriptor
        {
            List <X509Certificate2> certs = new List <X509Certificate2>();

            foreach (RoleDescriptor roleDescriptor in metadata.RoleDescriptors)
            {
                if (roleDescriptor.GetType() == typeof(T))
                {
                    foreach (KeyDescriptor keyDescriptor in roleDescriptor.Keys)
                    {
                        if (keyDescriptor.Use == keyType)
                        {
                            certs.AddRange(GetCertificatesFromKeyInfo(keyDescriptor.KeyInfo));
                        }
                    }
                }
            }

            return(certs);
        }
 /// <summary>
 /// Extract the entity id from an entity descriptor.
 /// </summary>
 /// <param name="metadata">EntityDescriptor representing the entity.</param>
 /// <returns>Name of the entity.</returns>
 static string GetEntityName(EntityDescriptor metadata)
 {
     return(metadata.EntityId.Id);
 }