private string FindTargetNode(ACP acpClient, List <string> requested) { string hostName = string.Empty; try { NodePageResourceBase data = acpClient.GetNodeData(); double smallest = double.MaxValue; foreach (Node n in data.items) { foreach (NodeRole nr in n.nodeRoles) { double perMem = nr.allocatedMemory / nr.totalMemory; if (smallest > perMem && requested.Contains(n.name)) { smallest = perMem; hostName = n.name; } } } } catch (Exception ex) { this.log.Error($"Issues when finding the least loaded node on Apprenda: {ex}"); } return(hostName); }
public override void OnPromotingVersion( ReadOnlyVersionDataDTO version, ApplicationVersionStageDTO proposedStage) { Task.Run(async() => { try { this.snapSession = new SnapSession(); log.Info($"Authenticating with Apprenda. App = {version.ApplicationAlias}, Token= {SessionContext.Instance.SessionToken}."); snapSession.AppName = version.ApplicationAlias; var acpClient = new ACP(SessionContext.Instance.SessionToken); try { log.Info($"Loading Developer properties"); var customProperties = acpClient.GetComponentCustomProperties( version.ApplicationAlias, version.Alias, string.Empty).Payload; log.Info($"Loaded Developer custom properties"); foreach (CustomProperty cp in customProperties) { log.Info($"Prop Name: {cp.PropertyModel.Name}, Value: {cp.Values.First()}"); } var devDbCloneType = customProperties.First(p => p.PropertyModel.Name == CustomProperties.DBCloneType); log.Info($"Loaded clone type property and it is not null {devDbCloneType != null}"); if (devDbCloneType != null) { this.snapSession.CloneType = devDbCloneType.Values.First(); } log.Info($"Loaded Developer settings for clone type {this.snapSession.CloneType}"); var devDbName = customProperties.First(p => p.PropertyModel.Name == CustomProperties.SnapDBName); log.Info($"Loaded db name property and it is not null {devDbName != null}"); if (devDbName != null) { this.snapSession.DbName = devDbName.Values.First(); } log.Info($"Loaded Developer settings for DBName {this.snapSession.DbName}"); var devPlugin = customProperties.First(p => p.PropertyModel.Name == CustomProperties.SnapPlugin); log.Info($"Loaded Snap Plugin property and it is not null {devPlugin != null}"); if (devPlugin != null) { this.snapSession.Plugin = devPlugin.Values.First(); } log.Info($"Loaded Developer settings for Snap Plugin {this.snapSession.Plugin}"); } catch (Exception ex) { log.Error("Issues loading developer properties. Falling back on SOC defaults", ex); } log.Info($"Loading SOC properties"); var socprops = (await acpClient.GetAllCustomPropertiesAsync()).Payload; if (socprops != null) { if (socprops.items != null && socprops.items.Count > 0) { log.Info($"Loaded SOC properties"); var snapCloneType = socprops.items.First(p => p.name == CustomProperties.DBCloneType); if (string.IsNullOrEmpty(this.snapSession.CloneType) && (snapCloneType != null && snapCloneType.valueOptions.defaultValues != null && snapCloneType.valueOptions.defaultValues.Count > 0)) { this.snapSession.CloneType = snapCloneType.valueOptions.defaultValues[0]; } var snapPluginProp = socprops.items.First(p => p.name == CustomProperties.SnapPlugin); if (string.IsNullOrEmpty(this.snapSession.Plugin) && snapPluginProp != null && snapPluginProp.valueOptions.defaultValues != null && snapPluginProp.valueOptions.defaultValues.Count > 0) { this.snapSession.Plugin = snapPluginProp.valueOptions.defaultValues[0]; } var snapUrlProp = socprops.items.First(p => p.name == CustomProperties.SnapCenterUrl); if (snapUrlProp != null && snapUrlProp.valueOptions.defaultValues != null && snapUrlProp.valueOptions.defaultValues.Count > 0) { this.snapSession.Url = snapUrlProp.valueOptions.defaultValues[0]; } var snapAdminProp = socprops.items.First(p => p.name == CustomProperties.SnapCenterAdmin); if (snapAdminProp != null && snapAdminProp.valueOptions.defaultValues != null && snapAdminProp.valueOptions.defaultValues.Count > 0) { this.snapSession.Admin = snapAdminProp.valueOptions.defaultValues[0]; } var snapPassProp = socprops.items.First(p => p.name == CustomProperties.SnapCenterPassword); if (snapPassProp != null && snapPassProp.valueOptions.defaultValues != null && snapPassProp.valueOptions.defaultValues.Count > 0) { this.snapSession.Pass = snapPassProp.valueOptions.defaultValues[0]; } var dbNameProp = socprops.items.First(p => p.name == CustomProperties.SnapDBName); if (string.IsNullOrEmpty(this.snapSession.DbName) && dbNameProp != null && dbNameProp.valueOptions.defaultValues != null && dbNameProp.valueOptions.defaultValues.Count > 0) { this.snapSession.DbName = dbNameProp.valueOptions.defaultValues[0]; } var hostNameProp = socprops.items.First(p => p.name == CustomProperties.SnapDBHost); if (hostNameProp != null && hostNameProp.valueOptions.defaultValues != null && hostNameProp.valueOptions.defaultValues.Count > 0) { this.snapSession.HostName = hostNameProp.valueOptions.defaultValues[0]; } var cloneHostNameProp = socprops.items.First(p => p.name == CustomProperties.SnapDBCloneHost); this.log.Info($"Processing clone hostname settings"); if (cloneHostNameProp != null && cloneHostNameProp.valueOptions.defaultValues != null && cloneHostNameProp.valueOptions.defaultValues.Count > 0) { this.snapSession.CloneHostName = cloneHostNameProp.valueOptions.defaultValues[0]; this.log.Info($"Going with the default value {this.snapSession.CloneHostName}."); } else if (cloneHostNameProp != null && cloneHostNameProp.valueOptions.possibleValues != null && cloneHostNameProp.valueOptions.possibleValues.Count == 1) { this.log.Info($"Default is not set. Only one possible value found = {cloneHostNameProp.valueOptions.possibleValues[0]}. Use it"); this.snapSession.CloneHostName = cloneHostNameProp.valueOptions.possibleValues[0]; } else if (cloneHostNameProp != null && cloneHostNameProp.valueOptions.possibleValues != null && cloneHostNameProp.valueOptions.possibleValues.Count > 0) { this.log.Info($"Default is not set and multiple servers are configured. Will figure out which of the configured servers is less busy"); string preferred = FindTargetNode(acpClient, cloneHostNameProp.valueOptions.possibleValues); this.log.Info($"The preferred server is {preferred}. Will use it"); this.snapSession.CloneHostName = preferred; } else { log.Error($"Error cloning Db {snapSession.DbName} for application {version.ApplicationAlias}: The Clone Host Name property is not configured"); return; } this.log.Info($"CloneHostName set to {this.snapSession.CloneHostName}."); var policyProp = socprops.items.First(p => p.name == CustomProperties.SnapPolicy); if (policyProp != null && policyProp.valueOptions.defaultValues != null && policyProp.valueOptions.defaultValues.Count > 0) { this.snapSession.Policy = policyProp.valueOptions.defaultValues[0]; } var snapScriptProp = socprops.items.First(p => p.name == CustomProperties.SnapMountScript); if (snapScriptProp != null && snapScriptProp.valueOptions.defaultValues != null && snapScriptProp.valueOptions.defaultValues.Count > 0) { this.snapSession.MountScript = snapScriptProp.valueOptions.defaultValues[0]; } var snapDataLeafProp = socprops.items.First(p => p.name == CustomProperties.SnapDataLeafIP); if (snapDataLeafProp != null && snapDataLeafProp.valueOptions.defaultValues != null && snapDataLeafProp.valueOptions.defaultValues.Count > 0) { this.snapSession.LeafIP = snapDataLeafProp.valueOptions.defaultValues[0]; } var snapMountPathProp = socprops.items.First(p => p.name == CustomProperties.SnapMountPath); if (snapMountPathProp != null && snapMountPathProp.valueOptions.defaultValues != null && snapMountPathProp.valueOptions.defaultValues.Count > 0) { this.snapSession.MountPath = snapMountPathProp.valueOptions.defaultValues[0]; } } } else { this.log.Info($"Cannot load SOC properties. Will try to use configs"); this.snapSession.Plugin = Settings.Default.SnapPlugin; this.snapSession.Url = Settings.Default.SnapCenterUrl; this.snapSession.Admin = Settings.Default.SnapCenterAdmin; this.snapSession.Pass = Settings.Default.SnapCenterPassword; this.snapSession.DbName = Settings.Default.SnapDBName; this.snapSession.HostName = Settings.Default.SnapDBHost; this.snapSession.CloneHostName = Settings.Default.SnapDBCloneHost; this.snapSession.Policy = Settings.Default.SnapPolicy; this.snapSession.MountPath = Settings.Default.SnapMountPath; this.snapSession.MountScript = Settings.Default.SnapMountScript; this.snapSession.LeafIP = Settings.Default.SnapDataLeafIP; } this.log.Info($"Snap session: {this.snapSession.toString()}"); if (this.snapSession.isValid()) { //check the type of cloning requested switch (this.snapSession.CloneType) { case DBCloneTypes.CloneOriginal: CloneOriginal(snapSession); break; case DBCloneTypes.RestoreClone: RestoreClone(snapSession); break; default: { BackUp b = FindSnapshot(snapSession); if (b == null) //if clones do not exist, clone the original { this.log.Info($"Clone not found. Performing cloning of the original"); CloneOriginal(snapSession); } else { this.log.Info($"Clone found. Do nothing. Will use existing copy"); //do nothing is the app needs to conect to the existing clone } } break; } } else { this.log.Info($"Snap data incomplete. Aborting..."); } } catch (Exception ex) { log.Error($"Error cloning Db {snapSession.DbName} for application {version.ApplicationAlias}: {ex}"); } }).GetAwaiter().GetResult(); }
public static bool KeyboardInput_HookProc(ref IntPtr __result, IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam, IntPtr ___prevWndProc, ref IntPtr ___hIMC) { //ModEntry.monitor.Log("MSG:" + msg, StardewModdingAPI.LogLevel.Trace); if (___hIMC != (IntPtr)0) { ImmReleaseContext(___prevWndProc, ___hIMC); ___hIMC = (IntPtr)0; ModEntry.monitor.Log("Released IMM Context", StardewModdingAPI.LogLevel.Trace); } try { switch (msg) { //Key event case WM_CHAR: if (Game1.keyboardDispatcher.Subscriber != null) { var sub = Game1.keyboardDispatcher.Subscriber; char ch = (char)wParam; if (!char.IsControl(ch)) { if (ModEntry.textbox_h._enable) { ACP acp = new ACP(); acp.acpEnd = ModEntry.textbox_h.ACP_End; acp.acpStart = ModEntry.textbox_h.ACP_Start; if (acp.acpEnd == acp.acpStart) { acp.acpEnd++; } IntPtr pacp = Marshal.AllocHGlobal(8); Marshal.StructureToPtr(acp, pacp, false); SendMessage(Game1.game1.Window.Handle, TF_QUERYINSERT, (int)pacp, 1); acp = (ACP)Marshal.PtrToStructure(pacp, typeof(ACP)); Marshal.FreeHGlobal(pacp); if (acp.acpEnd != acp.acpStart) { ModEntry.textbox_h.ACP_End = acp.acpEnd; ModEntry.textbox_h.ACP_Start = acp.acpStart; notify = false; ReplaceSel(ch.ToString()); notify = true; ModEntry.tsf.onTextChange(); ModEntry.textbox_h.ACP_Start = ModEntry.textbox_h.ACP_End; ModEntry.tsf.onSelChange(); } } else { sub.RecieveTextInput(ch); } } else if (ch == '\u0016') //paste { if (System.Windows.Forms.Clipboard.ContainsText()) { if (ModEntry.textbox_h._enable) { var text = System.Windows.Forms.Clipboard.GetText(); ACP acp = new ACP(); acp.acpEnd = ModEntry.textbox_h.ACP_End; acp.acpStart = ModEntry.textbox_h.ACP_Start; if (acp.acpEnd == acp.acpStart) { acp.acpEnd += text.Length; } IntPtr pacp = Marshal.AllocHGlobal(8); Marshal.StructureToPtr(acp, pacp, false); SendMessage(Game1.game1.Window.Handle, TF_QUERYINSERT, (int)pacp, 1); acp = (ACP)Marshal.PtrToStructure(pacp, typeof(ACP)); Marshal.FreeHGlobal(pacp); if (acp.acpEnd != acp.acpStart) { ModEntry.textbox_h.ACP_End = acp.acpEnd; ModEntry.textbox_h.ACP_Start = acp.acpStart; notify = false; ReplaceSel(text); notify = true; ModEntry.tsf.onTextChange(); ModEntry.textbox_h.ACP_Start = ModEntry.textbox_h.ACP_End; ModEntry.tsf.onSelChange(); } } else { sub.RecieveTextInput(System.Windows.Forms.Clipboard.GetText()); } } } else { if (ModEntry.textbox_h._enable && ch == '\b') { if (ModEntry.textbox_h.ACP_End == ModEntry.textbox_h.ACP_Start && ModEntry.textbox_h.ACP_End != 0) { ModEntry.textbox_h.ACP_End--; } if (ModEntry.textbox_h.ACP_End != ModEntry.textbox_h.ACP_Start) { notify = false; ReplaceSel(""); notify = true; ModEntry.tsf.onTextChange(); ModEntry.tsf.onSelChange(); } } else { sub.RecieveCommandInput(ch); } } } goto Handled; case WM_KEYDOWN: if (Game1.keyboardDispatcher.Subscriber != null) { var sub = Game1.keyboardDispatcher.Subscriber; Keys key = (Keys)wParam; if (key == Keys.Left && Math.Max(ModEntry.textbox_h.ACP_End, ModEntry.textbox_h.ACP_Start) > 0) { ModEntry.textbox_h.ACP_Start = ModEntry.textbox_h.ACP_End = Math.Max(0, ModEntry.textbox_h.ACP_End != ModEntry.textbox_h.ACP_Start ? Math.Min(ModEntry.textbox_h.ACP_End, ModEntry.textbox_h.ACP_Start) : ModEntry.textbox_h.ACP_End - 1); ModEntry.tsf.onSelChange(); goto Handled; } if (key == Keys.Right) { ModEntry.textbox_h.ACP_Start = ModEntry.textbox_h.ACP_End = Math.Min(ModEntry.textbox_h.getTextLen(), ModEntry.textbox_h.ACP_End != ModEntry.textbox_h.ACP_Start ? Math.Max(ModEntry.textbox_h.ACP_End, ModEntry.textbox_h.ACP_Start) : ModEntry.textbox_h.ACP_End + 1); ModEntry.tsf.onSelChange(); goto Handled; } notify = false; sub.RecieveSpecialInput(key); notify = true; } goto Handled; case WM_KEYUP: break; //EM case EM_GETSEL: Marshal.WriteInt32(lParam, ModEntry.textbox_h.ACP_End); Marshal.WriteInt32(wParam, ModEntry.textbox_h.ACP_Start); ModEntry.monitor.Log("GETSEL ACP_Start:" + ModEntry.textbox_h.ACP_Start + "ACP_End:" + ModEntry.textbox_h.ACP_End, StardewModdingAPI.LogLevel.Trace); goto Handled; case EM_SETSEL: ModEntry.textbox_h.ACP_End = (int)lParam; ModEntry.textbox_h.ACP_Start = (int)wParam; if (ModEntry.textbox_h.ACP_Start > ModEntry.textbox_h.getTextLen()) { ModEntry.textbox_h.resetAcp(); } ModEntry.monitor.Log("SETSEL ACP_Start:" + ModEntry.textbox_h.ACP_Start + "ACP_End:" + ModEntry.textbox_h.ACP_End, StardewModdingAPI.LogLevel.Trace); goto Handled; case EM_REPLACESEL: notify = false; ReplaceSel(Marshal.PtrToStringAuto(lParam)); notify = true; goto Handled; //TF case TF_GETTEXTLENGTH: if (ModEntry.textbox_h.current != null) { __result = (IntPtr)ModEntry.textbox_h.getTextLen(); } goto Handled; case TF_GETTEXT: if (ModEntry.textbox_h.current != null) { var text = ModEntry.textbox_h.getText(); Marshal.Copy(text.ToCharArray(), 0, wParam, Math.Min(text.Length, (int)lParam)); } goto Handled; case TF_CLEARTEXT: ModEntry.textbox_h.ACP_End = 0; ModEntry.textbox_h.ACP_Start = 0; goto Handled; case TF_GETTEXTEXT: if (ModEntry.textbox_h.current != null) { RECT prc = new RECT(); ACP acp = (ACP)Marshal.PtrToStructure(lParam, typeof(ACP)); prc.left = ModEntry.textbox_h.X + 18; if (ModEntry.textbox_h.current is ChatTextBox) { prc.left -= 2; int index = 0; foreach (ChatSnippet item in ((ChatTextBox)ModEntry.textbox_h.current).finalText) { index += item.emojiIndex != -1 ? 1 : item.message.Length; if (index >= acp.acpStart) { if (item.emojiIndex != -1) { prc.left += (int)item.myLength; } else { prc.left += (int)ModEntry.textbox_h.font.MeasureString(item.message.Substring(0, acp.acpStart - (index - item.message.Length))).X; } break; } prc.left += (int)item.myLength; } } else { string text = ModEntry.textbox_h.getText(); prc.left += (int)ModEntry.textbox_h.font.MeasureString(text.Substring(0, acp.acpStart)).X; } prc.top = ModEntry.textbox_h.current.Y; prc.right = prc.left + (int)ModEntry.textbox_h.font.MeasureString(" ").X *(acp.acpEnd - acp.acpStart); prc.bottom = prc.top + (int)ModEntry.textbox_h.font.MeasureString(" ").Y + 8; MapWindowPoints(Game1.game1.Window.Handle, (IntPtr)0, ref prc, 2); Marshal.StructureToPtr(prc, wParam, false); //text ext __result = (IntPtr)0; //clipped } goto Handled; case TF_QUERYINSERT: if (ModEntry.textbox_h.current != null && ModEntry.textbox_h.current.textLimit != -1) { var limit = ModEntry.textbox_h.current.textLimit - ModEntry.textbox_h.getTextLen(); ACP acp = (ACP)Marshal.PtrToStructure(wParam, typeof(ACP)); uint cch = (uint)lParam; string str = String.Format("ACPTestStart:{0} ACPTestEnd:{1} cch:{2}", acp.acpStart, acp.acpStart, cch); ModEntry.monitor.Log(str, StardewModdingAPI.LogLevel.Trace); acp.acpStart = Math.Min(acp.acpStart, limit); acp.acpEnd = Math.Min(acp.acpEnd, limit); Marshal.StructureToPtr(acp, wParam, false); string str_result = String.Format("ACPTestStart:{0} ACPTestEnd:{1}", acp.acpStart, acp.acpStart); ModEntry.monitor.Log(str_result, StardewModdingAPI.LogLevel.Trace); } goto Handled; //TerminateComposition case WM_TerminateComposition: ModEntry.tsf.TerminateComposition(); goto Handled; //SetTextBox case WM_SETTEXTBOX: if (Game1.keyboardDispatcher.Subscriber != null && Game1.keyboardDispatcher.Subscriber is TextBox) { ModEntry.monitor.Log("Set Enable", StardewModdingAPI.LogLevel.Trace); ModEntry.textbox_h.enableInput(true); ModEntry.monitor.Log("Set TextBox", StardewModdingAPI.LogLevel.Trace); ModEntry.textbox_h.SetTextBox((TextBox)Game1.keyboardDispatcher.Subscriber); } goto Handled; //KillFocus case WM_KILLFOCUS: ModEntry.tsf.TerminateComposition(); break; //IMEs case WM_IME_STARTCOMPOSITION: ModEntry.monitor.Log("StartComposition", StardewModdingAPI.LogLevel.Trace); goto Handled; case WM_IME_COMPOSITION: ModEntry.monitor.Log("Composition", StardewModdingAPI.LogLevel.Trace); goto Handled; case WM_IME_ENDCOMPOSITION: ModEntry.monitor.Log("EndComposition", StardewModdingAPI.LogLevel.Trace); goto Handled; case WM_IME_SETCONTEXT: case WM_INPUTLANGCHANGE: goto Handled; } } catch (Exception e) { if (ModEntry.textbox_h.current != null) { ModEntry.textbox_h.resetAcp(); } else { ModEntry.textbox_h.ACP_Start = ModEntry.textbox_h.ACP_End = 0; } PostMessage(Game1.game1.Window.Handle, WM_TerminateComposition, 0, 0); ModEntry.textbox_h.enableInput(false); ModEntry.monitor.Log(e.Message, StardewModdingAPI.LogLevel.Error); } return(true); Handled: return(false); }