/// <summary> /// Determine if this is a variable that should be set directly or should be merged with the new value /// </summary> /// <param name="variableToCheck"></param> /// <returns>True if the variable should be merged, false if the value should be replaced instead</returns> private static bool ShouldMerge(Variable variableToCheck) { return string.Equals(variableToCheck.name, Resources.RuntimeTypeKey, StringComparison.OrdinalIgnoreCase) || string.Equals(variableToCheck.name, Resources.RuntimeUrlKey, StringComparison.OrdinalIgnoreCase); }
protected override void ApplyScaffoldingChanges(CloudRuntimePackage package) { string rootPath = General.GetServiceRootPath(FilePath); if (CloudServiceProject.Components.StartupTaskExists(RoleName, Resources.CacheStartupCommand)) { CloudServiceProject.Components.SetStartupTaskVariable( RoleName, Resources.CacheRuntimeUrl, package.PackageUri.ToString(), Resources.CacheStartupCommand); } else { Variable emulated = new Variable { name = Resources.EmulatedKey, RoleInstanceValue = new RoleInstanceValueElement { xpath = "/RoleEnvironment/Deployment/@emulated" } }; Variable cacheRuntimeUrl = new Variable { name = Resources.CacheRuntimeUrl, value = package.PackageUri.ToString() }; CloudServiceProject.Components.AddStartupTask( RoleName, Resources.CacheStartupCommand, ExecutionContext.elevated, emulated, cacheRuntimeUrl); } }
static void ClearEnvironmentValue(Variable[] environment, string key) { foreach (Variable variable in environment) { if (string.Equals(key, variable.name, StringComparison.OrdinalIgnoreCase)) { variable.value = ""; } } }
/// <summary> /// Set the variable value given a new value. Replace or add the value to the variable, as appropriate /// </summary> /// <param name="inVariable">The variable to change</param> /// <param name="addedValue">The new value to </param> private static void SetVariableValue(Variable inVariable, string addedValue) { if (!string.IsNullOrEmpty(inVariable.value) && ShouldMerge(inVariable)) { if (inVariable.value.IndexOf(addedValue, 0, inVariable.value.Length, StringComparison.OrdinalIgnoreCase) == -1) { inVariable.value = string.Concat(inVariable.value, ";", addedValue); } } else { inVariable.value = addedValue; } }
private static Variable[] ApplySettingChanges(Dictionary<string, string> settings, Variable[] roleVariables) { int roleVariableCount = (roleVariables == null ? 0 : roleVariables.Length); if (roleVariableCount > 0) { for (int j = 0; j < roleVariables.Length; ++j) { if (settings.ContainsKey(roleVariables[j].name)) { SetVariableValue(roleVariables[j], settings[roleVariables[j].name]); settings.Remove(roleVariables[j].name); } } } int settingsCount = (settings == null ? 0 : settings.Count); Variable[] newSettings = new Variable[settingsCount + roleVariableCount]; int i = 0; foreach (string key in settings.Keys) { newSettings[i] = new Variable { name = key, value = settings[key] }; ++i; } for (int j = 0; j < roleVariables.Length; ++j) { newSettings[i + j] = roleVariables[j]; } return newSettings; }
/// <summary> /// Adds the specified runtime environment setting to the specified runtime environment - either changes the setting in /// the environment if the setting already exists, or adds a new setting if it does not /// </summary> /// <param name="environment">The source runtime environment</param> /// <param name="keyName">The variable key</param> /// <param name="keyValue">The variable value</param> /// <returns>The runtime environment with the given setting applied</returns> private static Variable[] SetRuntimeEnvironment(IEnumerable<Variable> environment, string keyName, string keyValue) { Variable v = environment.FirstOrDefault<Variable>(variable => string.Equals(variable.name, keyName, StringComparison.OrdinalIgnoreCase)); if (v != null) { v.value = keyValue; return environment.ToArray<Variable>(); } else { v = new Variable { name = keyName, value = keyValue }; return environment.Concat<Variable>(new List<Variable> { v }).ToArray<Variable>(); } }
/// <summary> /// Apply the specified Variable values to the specified role's startup task environment /// </summary> /// <param name="definition">The service definition containing the role</param> /// <param name="roleName">The name of the role to change</param> /// <param name="environment">The Variables containing the changes</param> /// <returns>true if the variables environment is successfully changed</returns> private static bool ApplyRuntimeChanges(ServiceDefinition definition, string roleName, Variable[] environment) { WebRole webRole; if (TryGetWebRole(definition, roleName, out webRole)) { CloudRuntime.GetRuntimeStartupTask(webRole.Startup).Environment = environment; return true; } WorkerRole workerRole; if (TryGetWorkerRole(definition, roleName, out workerRole)) { CloudRuntime.GetRuntimeStartupTask(workerRole.Startup).Environment = environment; return true; } return false; }
/// <summary> /// Sets a startup task environment variable. /// </summary> /// <param name="roleName">The role name</param> /// <param name="name">The environment variable name</param> /// <param name="value">The environment variable value</param> /// <param name="commandLines">The command line to match task.</param> public void SetStartupTaskVariable(string roleName, string name, string value, params string[] commandLines) { Task task = GetStartupTask(roleName, commandLines); bool found = false; if (task != null && task.Environment != null) { for (int i = 0; i < task.Environment.Length; i++) { if (task.Environment[i].name.Equals(name, StringComparison.OrdinalIgnoreCase)) { task.Environment[i].value = value; found = true; break; } } if (!found) { Variable var = new Variable() { name = name, value = value }; task.Environment = General.ExtendArray<Variable>(task.Environment, var); } } }
/// <summary> /// Applies required configuration for enabling cache in SDK 1.8.0 version by: /// * Add MemcacheShim runtime installation. /// * Add startup task to install memcache shim on the client side. /// * Add default memcache internal endpoint. /// * Add cache diagnostic to local resources. /// * Add ClientDiagnosticLevel setting to service configuration. /// * Adjust web.config to enable auto discovery for the caching role. /// </summary> /// <param name="azureService">The azure service instance</param> /// <param name="webRole">The web role to enable caching on</param> /// <param name="isWebRole">Flag indicating if the provided role is web or not</param> /// <param name="cacheWorkerRole">The memcache worker role name</param> /// <param name="startup">The role startup</param> /// <param name="endpoints">The role endpoints</param> /// <param name="localResources">The role local resources</param> /// <param name="configurationSettings">The role configuration settings</param> private void Version180Configuration( AzureService azureService, string roleName, bool isWebRole, string cacheWorkerRole, Startup startup, Endpoints endpoints, LocalResources localResources, ref DefinitionConfigurationSetting[] configurationSettings) { if (isWebRole) { // Generate cache scaffolding for web role azureService.GenerateScaffolding(Path.Combine(Resources.CacheScaffolding, RoleType.WebRole.ToString()), roleName, new Dictionary<string, object>()); // Adjust web.config to enable auto discovery for the caching role. string webCloudConfigPath = Path.Combine(azureService.Paths.RootPath, roleName, Resources.WebCloudConfig); string webConfigPath = Path.Combine(azureService.Paths.RootPath, roleName, Resources.WebConfigTemplateFileName); UpdateWebConfig(roleName, cacheWorkerRole, webCloudConfigPath); UpdateWebConfig(roleName, cacheWorkerRole, webConfigPath); } else { // Generate cache scaffolding for worker role Dictionary<string, object> parameters = new Dictionary<string, object>(); parameters[ScaffoldParams.RoleName] = cacheWorkerRole; azureService.GenerateScaffolding(Path.Combine(Resources.CacheScaffolding, RoleType.WorkerRole.ToString()), roleName, parameters); } // Add startup task to install memcache shim on the client side. string cacheRuntimeUri = CloudRuntimeCollection.GetRuntimeUrl(Resources.CacheRuntimeValue, CacheRuntimeVersion); Debug.Assert(!string.IsNullOrEmpty(cacheRuntimeUri)); Variable emulated = new Variable { name = Resources.EmulatedKey, RoleInstanceValue = new RoleInstanceValueElement { xpath = "/RoleEnvironment/Deployment/@emulated" } }; Variable[] env = { emulated, new Variable { name = Resources.CacheRuntimeUrl, value = cacheRuntimeUri } }; Task shimStartupTask = new Task { Environment = env, commandLine = Resources.CacheStartupCommand, executionContext = ExecutionContext.elevated }; startup.Task = General.ExtendArray<Task>(startup.Task, shimStartupTask); // Add default memcache internal endpoint. InternalEndpoint memcacheEndpoint = new InternalEndpoint { name = Resources.MemcacheEndpointName, protocol = InternalProtocol.tcp, port = Resources.MemcacheEndpointPort }; endpoints.InternalEndpoint = General.ExtendArray<InternalEndpoint>(endpoints.InternalEndpoint, memcacheEndpoint); // Enable cache diagnostic LocalStore localStore = new LocalStore { name = Resources.CacheDiagnosticStoreName, cleanOnRoleRecycle = false }; localResources.LocalStorage = General.ExtendArray<LocalStore>(localResources.LocalStorage, localStore); DefinitionConfigurationSetting diagnosticLevel = new DefinitionConfigurationSetting { name = Resources.CacheClientDiagnosticLevelAssemblyName }; configurationSettings = General.ExtendArray<DefinitionConfigurationSetting>(configurationSettings, diagnosticLevel); // Add ClientDiagnosticLevel setting to service configuration. AddClientDiagnosticLevelToConfig(azureService.Components.GetCloudConfigRole(roleName)); AddClientDiagnosticLevelToConfig(azureService.Components.GetLocalConfigRole(roleName)); }