/// <summary> /// Initializes a new instance of the <see cref="UserSettings"/> class. /// </summary> /// <param name="logger">The logger to use.</param> /// <param name="configName">The name to use for the config file.</param> public UserSettings(ConnectedServiceLogger logger, string configName = "Settings") { this.configName = configName; this.logger = logger; // Desired defaults GeneratedFileNamePrefix = Constants.DefaultReferenceFileName; ServiceName = Constants.DefaultServiceName; UseDataServiceCollection = true; // To support entity and property tracking EnableNamingAlias = true; // To force upper camel case in the event that entities are named in lower camel case IgnoreUnexpectedElementsAndAttributes = true; // Ignore unexpected elements and attributes in the metadata document ExcludedBoundOperations = new List <string>(); ExcludedOperationImports = new List <string>(); ExcludedSchemaTypes = new List <string>(); MruEndpoints = new ObservableCollection <string>(); UserSettingsPersistenceHelper.Load <UserSettings>( providerId: Constants.ProviderId, name: configName, onLoaded: (userSettings) => { // onLoaded action is currently triggered only if settings are loaded from config file // Do this defensively all the same... if (userSettings != null) { foreach (var mruEndpoint in userSettings.MruEndpoints) { MruEndpoints.Add(mruEndpoint); } } }, logger: logger); }
/// <summary> /// Ensures the appropriate version of the specified packages are installed. If an existing version of the package /// already exists the following will happen: /// If a semantically compatible version already exists, no change is made to the package. /// If an older major version exists, a warning is logged and the package is upgraded. /// If an older minor/build version exists, an information message is logged and the package is upgraded. /// If a newer major version exists, a warning is logged and no change is made to the package. /// </summary> public static async Task InstallPackagesAsync( Dictionary<string, string> packages, string extensionId, ConnectedServiceLogger logger, Project project, IVsPackageInstallerServices packageInstallerServices, IVsPackageInstaller packageInstaller) { Dictionary<string, string> packagesToInstall = new Dictionary<string, string>(); await NuGetUtilities.InstallPackagesAsync( project, packages, (packageId, packageVersion) => { packagesToInstall.Add(packageId, packageVersion); return Task.FromResult<object>(null); }, logger, packageInstallerServices); if (packagesToInstall.Any()) { packageInstaller.InstallPackagesFromVSExtensionRepository(extensionId, false, false, project, packagesToInstall); } }
/// <summary> /// Ensures the appropriate version of the specified packages are installed. If an existing version of the package /// already exists the following will happen: /// If a semantically compatible version already exists, no change is made to the package. /// If an older major version exists, a warning is logged and the package is upgraded. /// If an older minor/build version exists, an information message is logged and the package is upgraded. /// If a newer major version exists, a warning is logged and no change is made to the package. /// </summary> public static async Task InstallPackagesAsync( Dictionary <string, string> packages, string extensionId, ConnectedServiceLogger logger, Project project, IVsPackageInstallerServices packageInstallerServices, IVsPackageInstaller packageInstaller) { Dictionary <string, string> packagesToInstall = new Dictionary <string, string>(); await NuGetUtilities.InstallPackagesAsync( project, packages, (packageId, packageVersion) => { packagesToInstall.Add(packageId, packageVersion); return(Task.FromResult <object>(null)); }, logger, packageInstallerServices); if (packagesToInstall.Any()) { packageInstaller.InstallPackagesFromVSExtensionRepository(extensionId, false, false, project, packagesToInstall); } }
public static async Task <UserSettings> LoadAsync(ConnectedServiceLogger logger) { var userSettings = await UserSettingsPersistenceHelper.LoadAsync <UserSettings>( Constants.ProviderId, UserSettings.Name, null, logger) ?? new UserSettings(); userSettings._logger = logger; return(userSettings); }
private static IEnumerable<GeneratedStorageProperty> BuildStorageProperties(SObjectDescription objDescription, ConnectedServiceLogger logger) { return objDescription.Fields .Select(f => CodeModelBuilder.BuildStorageProperty( f, (soapType) => logger.WriteMessageAsync(LoggerMessageCategory.Error, Resources.LogMessage_UnsupportedSoapType, soapType, objDescription.Name, f.Name))) .ToArray(); }
public static UserSettings Load(ConnectedServiceLogger logger) { var userSettings = UserSettingsPersistenceHelper.Load <UserSettings>( Constants.ProviderId, UserSettings.Name, null, logger) ?? new UserSettings(); userSettings._logger = logger; return(userSettings); }
private static async Task CreateConnectedAppAsync( SalesforceConnectedServiceInstance salesforceInstance, MetadataService metadataService, ConnectedServiceLogger logger, Project project) { salesforceInstance.ConnectedAppName = ConnectedAppHelper.GetUniqueConnectedAppName(metadataService, project); ConnectedApp connectedApp = ConnectedAppHelper.ConstructConnectedApp(salesforceInstance, project); SaveResult[] saveResults = metadataService.createMetadata(new Metadata[] { connectedApp }); if (ConnectedAppHelper.DoSaveResultsIndicateDuplicateValue(saveResults)) { // The connected app failed to be created because one already exists with the specified name. This implies that the // attempt to generate a unique name by reading the existing connected apps failed. It is unknown at this point what // causes the Salesforce server to sometimes respond to a SOAP ReadMetadata request by returning nil for a Connected App // name that actually exists. In this case, retry using a random number as the app name's suffix. Debug.Fail("A connected app named '{0}' already exists. This implies that the Salesforce server responded to the SOAP ReadMetadata request to read this Connected App by returning nil for it even though it actually exists." .FormatCurrentCulture(salesforceInstance.ConnectedAppName)); string secondAttemptConnectedAppName = ConnectedAppHelper.GetUniqueConnectedAppName(metadataService, project, true); await logger.WriteMessageAsync(LoggerMessageCategory.Information, Resources.LogMessage_DuplicateConnectedAppName, salesforceInstance.ConnectedAppName, secondAttemptConnectedAppName); salesforceInstance.ConnectedAppName = secondAttemptConnectedAppName; connectedApp = ConnectedAppHelper.ConstructConnectedApp(salesforceInstance, project); saveResults = metadataService.createMetadata(new Metadata[] { connectedApp }); } if (saveResults.Length != 1 || !saveResults[0].success) { string errorMessages = saveResults.SelectMany(r => r.errors) .Select(e => e.message) .Aggregate((w, n) => w + "\r\n" + n); throw new InvalidOperationException(Resources.ConnectedAppHelper_FailedToCreateConnectedApp.FormatCurrentCulture(errorMessages)); } else { ConnectedApp readConnectedApp = ConnectedAppHelper.GetConnectedAppByName(connectedApp.fullName, metadataService); if (readConnectedApp != null) { salesforceInstance.RuntimeAuthentication.ConsumerKey = readConnectedApp.oauthConfig.consumerKey; } else { await logger.WriteMessageAsync(LoggerMessageCategory.Warning, Resources.LogMessage_FailedReadingConnectedApp); salesforceInstance.RuntimeAuthentication.ConsumerKey = Constants.ConfigValue_RequiredDefault; } } }
private static void ExecuteNoncriticalOperation( Action operation, ConnectedServiceLogger logger, string failureMessage, string failureMessageArg) { try { operation(); } catch (Exception ex) { logger.WriteMessageAsync(LoggerMessageCategory.Warning, failureMessage, failureMessageArg, ex); } }
public static async Task CreateConnectedAppAsync( SalesforceConnectedServiceInstance salesforceInstance, ConnectedServiceLogger logger, Project project) { using (MetadataService metadataService = new MetadataService()) { metadataService.Url = salesforceInstance.DesignTimeAuthentication.MetadataServiceUrl; metadataService.SessionHeaderValue = new SessionHeader(); metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken; await AuthenticationHelper.ExecuteSalesforceRequestAsync<SoapHeaderException>( salesforceInstance.DesignTimeAuthentication, async () => await ConnectedAppHelper.CreateConnectedAppAsync(salesforceInstance, metadataService, logger, project), (e) => e.Message.StartsWith("INVALID_SESSION_ID", StringComparison.OrdinalIgnoreCase), () => metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken); } }
public static async Task CreateConnectedAppAsync( SalesforceConnectedServiceInstance salesforceInstance, ConnectedServiceLogger logger, Project project) { using (MetadataService metadataService = new MetadataService()) { metadataService.Url = salesforceInstance.DesignTimeAuthentication.MetadataServiceUrl; metadataService.SessionHeaderValue = new SessionHeader(); metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken; await AuthenticationHelper.ExecuteSalesforceRequestAsync <SoapHeaderException>( salesforceInstance.DesignTimeAuthentication, async() => await ConnectedAppHelper.CreateConnectedAppAsync(salesforceInstance, metadataService, logger, project), (e) => e.Message.StartsWith("INVALID_SESSION_ID", StringComparison.OrdinalIgnoreCase), () => metadataService.SessionHeaderValue.sessionId = salesforceInstance.DesignTimeAuthentication.AccessToken); } }
public static async Task <IEnumerable <GeneratedObject> > BuildObjectModelAsync( IEnumerable <SObjectDescription> sObjects, DesignTimeAuthentication authentication, GeneratedService generatedService, ConnectedServiceLogger logger) { IEnumerable <SObjectDescription> sObjectsWithDetails = await MetadataLoader.LoadObjectDetailsAsync(sObjects, authentication); IEnumerable <GeneratedObject> generatedObjects = sObjectsWithDetails .Select(o => new GeneratedObject() { Model = o, Service = generatedService, StorageProperties = CodeModelBuilder.BuildStorageProperties(o, logger) }) .ToArray(); return(generatedObjects); }
private static void ExecuteNoncriticalOperation( Action operation, ConnectedServiceLogger logger, string failureMessage, string failureMessageArg) { try { operation(); } catch (Exception ex) { var loggerTask = logger.WriteMessageAsync(LoggerMessageCategory.Warning, failureMessage, failureMessageArg, ex); if (!loggerTask.IsCompleted) { loggerTask.RunSynchronously(); } } }
public static async Task<IEnumerable<GeneratedObject>> BuildObjectModelAsync( IEnumerable<SObjectDescription> sObjects, DesignTimeAuthentication authentication, GeneratedService generatedService, ConnectedServiceLogger logger) { IEnumerable<SObjectDescription> sObjectsWithDetails = await MetadataLoader.LoadObjectDetailsAsync(sObjects, authentication); IEnumerable<GeneratedObject> generatedObjects = sObjectsWithDetails .Select(o => new GeneratedObject() { Model = o, Service = generatedService, StorageProperties = CodeModelBuilder.BuildStorageProperties(o, logger) }) .ToArray(); return generatedObjects; }
/// <summary> /// Uninstall the packages that exist in the project. /// </summary> public static async Task UninstallPackagesAsync( Project targetProject, ISet<string> packages, Func<string, Task> uninstallPackage, ConnectedServiceLogger logger, IVsPackageInstallerServices packageInstallerServices) { IEnumerable<IVsPackageMetadata> installedPackages = packageInstallerServices.GetInstalledPackages(targetProject); foreach (string packageId in packages) { IVsPackageMetadata installedPackage = installedPackages.FirstOrDefault(p => p.Id == packageId); if (installedPackage != null) { await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_RemovingNuGetPackage, packageId, installedPackage.VersionString); await uninstallPackage(packageId); } } }
/// <summary> /// Uninstall the packages that exist in the project. /// </summary> public static async Task UninstallPackagesAsync( Project targetProject, ISet <string> packages, Func <string, Task> uninstallPackage, ConnectedServiceLogger logger, IVsPackageInstallerServices packageInstallerServices) { IEnumerable <IVsPackageMetadata> installedPackages = packageInstallerServices.GetInstalledPackages(targetProject); foreach (string packageId in packages) { IVsPackageMetadata installedPackage = installedPackages.FirstOrDefault(p => p.Id == packageId); if (installedPackage != null) { await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_RemovingNuGetPackage, packageId, installedPackage.VersionString); await uninstallPackage(packageId); } } }
private static IEnumerable <GeneratedStorageProperty> BuildStorageProperties(SObjectDescription objDescription, ConnectedServiceLogger logger) { return(objDescription.Fields .Select(f => CodeModelBuilder.BuildStorageProperty( f, (soapType) => logger.WriteMessageAsync(LoggerMessageCategory.Error, Resources.LogMessage_UnsupportedSoapType, soapType, objDescription.Name, f.Name))) .ToArray()); }
/// <summary> /// Ensures the appropriate version of the specified packages are installed. If an existing version of the package /// already exists the following will happen: /// If a semantically compatible version already exists, no change is made to the package. /// If an older major version exists, a warning is logged and the package is upgraded. /// If an older minor/build version exists, an information message is logged and the package is upgraded. /// If a newer major version exists, a warning is logged and no change is made to the package. /// </summary> public static async Task InstallPackagesAsync( Project targetProject, Dictionary <string, string> packages, Func <string, string, Task> installPackage, ConnectedServiceLogger logger, IVsPackageInstallerServices packageInstallerServices) { IEnumerable <IVsPackageMetadata> installedPackages; try { installedPackages = packageInstallerServices.GetInstalledPackages(targetProject); } catch (ArgumentException) { // This happens for C++ projects installedPackages = new List <IVsPackageMetadata>(); } foreach (KeyValuePair <string, string> requiredPackage in packages) { IVsPackageMetadata installedPackage = installedPackages.FirstOrDefault(p => p.Id == requiredPackage.Key); if (installedPackage == null) { // The package does not exist - notify and install the package. await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_AddingNuGetPackage, requiredPackage.Key, requiredPackage.Value); } else { Version installedVersion = NuGetUtilities.GetVersion(installedPackage.VersionString); Version requiredVersion = NuGetUtilities.GetVersion(requiredPackage.Value); if (installedVersion == null || requiredVersion == null) { // Unable to parse the version - continue. continue; } else if (installedVersion.Major < requiredVersion.Major) { // An older potentially non-compatible version of the package already exists - warn and upgrade the package. await logger.WriteMessageAsync( LoggerMessageCategory.Warning, Resource.LogMessage_OlderMajorVersionNuGetPackageExists, requiredPackage.Key, installedPackage.VersionString, requiredPackage.Value); } else if (installedVersion.Major > requiredVersion.Major) { // A newer potentially non-compatible version of the package already exists - warn and continue. await logger.WriteMessageAsync( LoggerMessageCategory.Warning, Resource.LogMessage_NewerMajorVersionNuGetPackageExists, requiredPackage.Key, requiredPackage.Value, installedPackage.VersionString); continue; } else if (installedVersion >= requiredVersion) { // A semantically compatible version of the package already exists - continue. continue; } else { // An older semantically compatible version of the package exists - notify and upgrade the package. await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_UpgradingNuGetPackage, requiredPackage.Key, installedPackage.VersionString, requiredPackage.Value); } } await installPackage(requiredPackage.Key, requiredPackage.Value); } }
/// <summary> /// Saves user settings to isolated storage. The data is stored with the user's roaming profile. /// </summary> /// <remarks> /// Non-critical exceptions are handled by writing an error message in the output window. /// </remarks> public static void Save(object userSettings, string providerId, string name, Action onSaved, ConnectedServiceLogger logger) { string fileName = UserSettingsPersistenceHelper.GetStorageFileName(providerId, name); UserSettingsPersistenceHelper.ExecuteNoncriticalOperation( () => { using (IsolatedStorageFile file = UserSettingsPersistenceHelper.GetIsolatedStorageFile()) { IsolatedStorageFileStream stream = null; try { // note: this overwrites existing settings file if it exists stream = file.OpenFile(fileName, FileMode.Create); using (XmlWriter writer = XmlWriter.Create(stream)) { stream = null; DataContractSerializer dcs = new DataContractSerializer(userSettings.GetType()); dcs.WriteObject(writer, userSettings); writer.Flush(); } } finally { if (stream != null) { stream.Dispose(); } } } if (onSaved != null) { onSaved(); } }, logger, Resources.UserSettingsHelper_FailedSaving, fileName); }
/// <summary> /// Saves user settings to isolated storage. The data is stored with the user's roaming profile. /// </summary> /// <remarks> /// Non-critical exceptions are handled by writing an error message in the output window. /// </remarks> public static void Save(object userSettings, string providerId, string name, Action onSaved, ConnectedServiceLogger logger) { var fileName = UserSettingsPersistenceHelper.GetStorageFileName(providerId, name); UserSettingsPersistenceHelper.ExecuteNoncriticalOperation( () => { using (var file = UserSettingsPersistenceHelper.GetIsolatedStorageFile()) { IsolatedStorageFileStream stream = null; try { // note: this overwrites existing settings file if it exists stream = file.OpenFile(fileName, FileMode.Create); using (var writer = XmlWriter.Create(stream)) { stream = null; var dcs = new DataContractSerializer(userSettings.GetType()); dcs.WriteObject(writer, userSettings); writer.Flush(); } } finally { stream?.Dispose(); } } onSaved?.Invoke(); }, logger, "Failed loading the {0} user settings", fileName); }
/// <summary> /// Ensures the appropriate version of the specified packages are installed. If an existing version of the package /// already exists the following will happen: /// If a semantically compatible version already exists, no change is made to the package. /// If an older major version exists, a warning is logged and the package is upgraded. /// If an older minor/build version exists, an information message is logged and the package is upgraded. /// If a newer major version exists, a warning is logged and no change is made to the package. /// </summary> public static async Task InstallPackagesAsync( Project targetProject, Dictionary<string, string> packages, Func<string, string, Task> installPackage, ConnectedServiceLogger logger, IVsPackageInstallerServices packageInstallerServices) { IEnumerable<IVsPackageMetadata> installedPackages; try { installedPackages = packageInstallerServices.GetInstalledPackages(targetProject); } catch (ArgumentException) { // This happens for C++ projects installedPackages = new List<IVsPackageMetadata>(); } foreach (KeyValuePair<string, string> requiredPackage in packages) { IVsPackageMetadata installedPackage = installedPackages.FirstOrDefault(p => p.Id == requiredPackage.Key); if (installedPackage == null) { // The package does not exist - notify and install the package. await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_AddingNuGetPackage, requiredPackage.Key, requiredPackage.Value); } else { Version installedVersion = NuGetUtilities.GetVersion(installedPackage.VersionString); Version requiredVersion = NuGetUtilities.GetVersion(requiredPackage.Value); if (installedVersion == null || requiredVersion == null) { // Unable to parse the version - continue. continue; } else if (installedVersion.Major < requiredVersion.Major) { // An older potentially non-compatible version of the package already exists - warn and upgrade the package. await logger.WriteMessageAsync( LoggerMessageCategory.Warning, Resource.LogMessage_OlderMajorVersionNuGetPackageExists, requiredPackage.Key, installedPackage.VersionString, requiredPackage.Value); } else if (installedVersion.Major > requiredVersion.Major) { // A newer potentially non-compatible version of the package already exists - warn and continue. await logger.WriteMessageAsync( LoggerMessageCategory.Warning, Resource.LogMessage_NewerMajorVersionNuGetPackageExists, requiredPackage.Key, requiredPackage.Value, installedPackage.VersionString); continue; } else if (installedVersion >= requiredVersion) { // A semantically compatible version of the package already exists - continue. continue; } else { // An older semantically compatible version of the package exists - notify and upgrade the package. await logger.WriteMessageAsync( LoggerMessageCategory.Information, Resource.LogMessage_UpgradingNuGetPackage, requiredPackage.Key, installedPackage.VersionString, requiredPackage.Value); } } await installPackage(requiredPackage.Key, requiredPackage.Value); } }
/// <summary> /// Loads user settings from isolated storage. /// </summary> /// <remarks> /// Non-critical exceptions are handled by writing an error message in the output window and /// returning null. /// </remarks> public static T Load <T>(string providerId, string name, Action <T> onLoaded, ConnectedServiceLogger logger) where T : class { var fileName = UserSettingsPersistenceHelper.GetStorageFileName(providerId, name); T result = null; UserSettingsPersistenceHelper.ExecuteNoncriticalOperation( () => { using (var file = UserSettingsPersistenceHelper.GetIsolatedStorageFile()) { if (file.FileExists(fileName)) { IsolatedStorageFileStream stream = null; try { stream = file.OpenFile(fileName, FileMode.Open); var settings = new XmlReaderSettings() { XmlResolver = null }; using (var reader = XmlReader.Create(stream, settings)) { stream = null; var dcs = new DataContractSerializer(typeof(T)); result = dcs.ReadObject(reader) as T; } } finally { stream?.Dispose(); } if (onLoaded != null && result != null) { onLoaded(result); } } } }, logger, "Failed loading the {0} user settings", fileName); return(result); }
/// <summary> /// Constructor. /// </summary> /// <param name="serviceLogger">service logger</param> public TraceLogger(ConnectedServiceLogger serviceLogger) { this._serviceLogger = serviceLogger; }