Line 1: using System; Line 2: using System.Web; Line 3: using System.Collections; Line 4: using System.Web.Services; Line 5: using System.Web.Services.Protocols; Line 6: using System.Web.Script.Services; Line 7: using System.Web.UI; Line 8: using SolarWinds.Orion.Web; Line 9: using System.IO; Line 10: using System.Collections.Generic; Line 11: using System.Reflection; Line 12: using SolarWinds.Orion.NPM.Web; Line 13: using SolarWinds.Orion.Web.UI; Line 14: using SolarWinds.Orion.Web.DAL; Line 15: using SolarWinds.Orion.Web.DisplayTypes; Line 16: using System.Text; Line 17: using System.Web.Script.Serialization; Line 18: using System.Data.SqlClient; Line 19: Line 20: /// <summary> Line 21: /// Summary description for NodeTree Line 22: /// </summary> Line 23: [WebService(Namespace = "http://tempuri.org/")] Line 24: [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] Line 25: [ScriptService] Line 26: public class NodeTree : System.Web.Services.WebService Line 27: { Line 28: private static SolarWinds.Logging.Log log = new SolarWinds.Logging.Log(); Line 29: Line 30: const int MaxNodesPerPage = 100; Line 31: Line 32: public NodeTree() Line 33: { Line 34: } Line 35: Line 36: [WebMethod] Line 37: public string GetTreeSection(int resourceId, string rootId, object[] keys, int startIndex) Line 38: { Line 39: log.DebugFormat("GetTreeSection({1}, {2}, {3}, {4}) from user {0}", Line 40: Context.User.Identity.Name, resourceId, rootId, FormatArray(keys), startIndex); Line 41: Line 42: ResourceInfo resource = ResourceManager.GetResourceByID(resourceId); Line 43: Context.Items[typeof(ViewInfo).Name] = resource.View; Line 44: Line 45: string filter = GetFilterClause(resource); Line 46: Line 47: try Line 48: { Line 49: StringWriter stringWriter = new StringWriter(); Line 50: HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); Line 51: Line 52: BuildTreeLevel(htmlWriter, resource, rootId, keys.Length + 1, keys, startIndex, filter); Line 53: Line 54: return stringWriter.ToString(); Line 55: } Line 56: catch (SqlException ex) Line 57: { Line 58: StringWriter stringWriter = new StringWriter(); Line 59: HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter); Line 60: Line 61: BuildTreeLevel(htmlWriter, resource, rootId, keys.Length + 1, keys, startIndex, string.Empty); Line 62: Line 63: // No exception when running without the filter. Inform the user. Line 64: Line 65: return string.Format("Bad filter '{0}' specified. {1}", filter, ex.Message); Line 66: } Line 67: } Line 68: Line 69: private string GetFilterClause(ResourceInfo resource) Line 70: { Line 71: string filter = resource.Properties["Filter"] ?? string.Empty; Line 72: return filter.Trim().Replace('*', '%').Replace('?', '_'); Line 73: } Line 74: Line 75: private string GetGroupingWhereClause(ResourceInfo resource, object[] keys, string filter) Line 76: { Line 77: List<string> clauses = new List<string>(); Line 78: Line 79: if (!string.IsNullOrEmpty(filter)) Line 80: clauses.Add(filter); Line 81: Line 82: for (int level = 0; level < Math.Min(keys.Length, 3); ++level) Line 83: { Line 84: string property = resource.Properties[string.Format("Grouping{0}", level+1)]; Line 85: if (string.IsNullOrEmpty(property)) Line 86: break; Line 87: clauses.Add(string.Format("{0}='{1}'", property, keys[level])); Line 88: } Line 89: Line 90: return string.Join(" AND ", clauses.ToArray()); Line 91: } Line 92: Line 93: private static string FormatArray(object[] values) Line 94: { Line 95: JavaScriptSerializer serializer = new JavaScriptSerializer(); Line 96: return serializer.Serialize(values); Line 97: } Line 98: Line 99: // returns the aggregated status of all the children (whose statuses may be based on their children) Line 100: private void BuildTreeLevel(HtmlTextWriter writer, ResourceInfo resource, string rootId, int treeLevel, object[] keys, int startIndex, string filter) Line 101: { Line 102: string whereClause = GetGroupingWhereClause(resource, keys, filter); Line 103: Line 104: string property = resource.Properties[string.Format("Grouping{0}", treeLevel)]; Line 105: Line 106: if (startIndex > 0) Line 107: { Line 108: BuildNodeList(writer, whereClause, rootId, resource, keys, startIndex); Line 109: } Line 110: else if (string.IsNullOrEmpty(property)) Line 111: { Line 112: writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "12px"); Line 113: writer.RenderBeginTag(HtmlTextWriterTag.Div); Line 114: Line 115: BuildNodeList(writer, whereClause, rootId, resource, keys, startIndex); Line 116: Line 117: writer.RenderEndTag(); Line 118: } Line 119: else Line 120: { Line 121: List<string> propertyValues = Node.GetPropertyValues(property, whereClause); Line 122: int index = 0; Line 123: foreach (string key in propertyValues) Line 124: { Line 125: string childId = string.Format("{0}-{1}", rootId, index++); Line 126: Line 127: string where; Line 128: if (!string.IsNullOrEmpty(whereClause)) Line 129: where = whereClause + " AND " + property + " = '" + Server.HtmlEncode(key) + "'"; Line 130: else Line 131: where = property + " = '" + Server.HtmlEncode(key) + "'"; Line 132: Line 133: string displayKey = key == null ? string.Empty : key.Trim(); Line 134: if (displayKey.Length == 0) Line 135: displayKey = "Unknown"; Line 136: Line 137: RenderGroup(writer, resource, childId, treeLevel, property, displayKey, ArrayAppend(keys, key), filter); Line 138: } Line 139: } Line 140: } Line 141: Line 142: private object[] ArrayAppend(object[] array, object toAppend) Line 143: { Line 144: object[] newArray = new object[array.Length + 1]; Line 145: array.CopyTo(newArray, 0); Line 146: newArray[array.Length] = toAppend; Line 147: return newArray; Line 148: } Line 149: Line 150: private void RenderGroup(HtmlTextWriter writer, ResourceInfo resource, string rootId, int treeLevel, string property, string key, object[] keys, string filter) Line 151: { Line 152: string toggleId = rootId + "-toggle"; Line 153: string contentsId = rootId + "-contents"; Line 154: Line 155: string where = GetGroupingWhereClause(resource, keys, filter); Line 156: Line 157: writer.BeginRender(); Line 158: Line 159: writer.AddAttribute(HtmlTextWriterAttribute.Onclick, Line 160: string.Format("FastNodeTree_Click('{0}', {1}, {2}); return false;", rootId, resource.ID, FormatArray(keys))); Line 161: writer.AddAttribute(HtmlTextWriterAttribute.Href, "#"); Line 162: writer.RenderBeginTag(HtmlTextWriterTag.A); Line 163: Line 164: writer.AddAttribute(HtmlTextWriterAttribute.Src, "/Orion/images/Button.Expand.gif"); Line 165: writer.AddAttribute(HtmlTextWriterAttribute.Id, toggleId); Line 166: writer.AddAttribute(HtmlTextWriterAttribute.Class, "Toggle"); Line 167: writer.RenderBeginTag(HtmlTextWriterTag.Img); Line 168: writer.RenderEndTag(); Line 169: Line 170: RenderGroupStatus(writer, Status.Summarize(Node.GetGroupStatus(where))); Line 171: Line 172: string text; Line 173: if (property == "Status") Line 174: text = ((Status)Convert.ToInt32(key)).ToString(); Line 175: else Line 176: text = key; Line 177: Line 178: writer.Write(text); // users expect that HTML in the group name will be rendered, not quoted. see Orion TT#2745. Line 179: //writer.WriteEncodedText(text); Line 180: writer.RenderEndTag(); Line 181: Line 182: writer.WriteBreak(); Line 183: Line 184: writer.AddAttribute(HtmlTextWriterAttribute.Id, contentsId); Line 185: writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none"); Line 186: writer.AddStyleAttribute(HtmlTextWriterStyle.PaddingLeft, "12px"); Line 187: writer.RenderBeginTag(HtmlTextWriterTag.Div); Line 188: writer.RenderEndTag(); Line 189: Line 190: writer.EndRender(); Line 191: } Line 192: Line 193: private void BuildNodeList(HtmlTextWriter writer, string whereClause, string childId, ResourceInfo resource, object[] newKeys, int startIndex) Line 194: { Line 195: List<Node> nodes = new List<Node>(); Line 196: if (!string.IsNullOrEmpty(whereClause)) Line 197: { Line 198: foreach (Node n in Node.GetFilteredNodes(whereClause)) Line 199: nodes.Add(n); Line 200: } Line 201: else Line 202: { Line 203: foreach (Node n in Node.GetAllObjects()) Line 204: nodes.Add(n); Line 205: } Line 206: nodes.Sort(delegate(Node x, Node y) Line 207: { Line 208: return string.Compare(x.Name, y.Name, true); Line 209: }); Line 210: Line 211: for (int nodeIndex = 0; nodeIndex < nodes.Count; ++nodeIndex) Line 212: { Line 213: if (nodeIndex < startIndex) Line 214: continue; Line 215: Line 216: if (nodeIndex - startIndex > MaxNodesPerPage) Line 217: { Line 218: string getMoreId = string.Format("{0}-startFrom-{1}", childId, nodeIndex); Line 219: writer.AddAttribute(HtmlTextWriterAttribute.Id, getMoreId); Line 220: writer.RenderBeginTag(HtmlTextWriterTag.Div); Line 221: Line 222: writer.AddAttribute(HtmlTextWriterAttribute.Onclick, string.Format("FastNodeTree_GetMore_Click('{0}', {1}, {2}, {3}); return false;", Line 223: getMoreId, resource.ID, FormatArray(newKeys), nodeIndex)); Line 224: writer.AddAttribute(HtmlTextWriterAttribute.Href, "#"); Line 225: writer.RenderBeginTag(HtmlTextWriterTag.A); Line 226: writer.WriteEncodedText(string.Format("Get next {0} nodes", MaxNodesPerPage)); Line 227: writer.RenderEndTag(); Line 228: Line 229: writer.RenderEndTag(); Line 230: Line 231: break; Line 232: } Line 233: Line 234: RenderNode(writer, nodes[nodeIndex]); Line 235: writer.WriteBreak(); Line 236: } Line 237: } Line 238: Line 239: private void RenderNode(HtmlTextWriter writer, Node node) Line 240: { Line 241: writer.BeginRender(); Line 242: Line 243: writer.AddAttribute(HtmlTextWriterAttribute.Href, BaseResourceControl.GetViewLink(node)); Line 244: Line 245: if (((ProfileCommon)Context.Profile).ToolsetIntegration) Line 246: { Line 247: writer.AddAttribute("IP", node.IPAddress.ToString()); Line 248: writer.AddAttribute("NodeHostname", node.Hostname); Line 249: Line 250: if (RegistrySettings.AllowSecureDataOnWeb()) Line 251: { Line 252: writer.AddAttribute("Community", node.CommunityString); Line 253: } Line 254: else Line 255: { Line 256: string attrValue = string.Format("GUID{{{0}}}", WebCommunityStringsDAL.GetCommunityStringGuid(node.CommunityString)); Line 257: writer.AddAttribute("Community", attrValue); Line 258: } Line 259: } Line 260: Line 261: writer.RenderBeginTag(HtmlTextWriterTag.A); Line 262: RenderNodeStatus(writer, node.Status); Line 263: writer.WriteEncodedText(node.Name); Line 264: writer.RenderEndTag(); Line 265: Line 266: writer.EndRender(); Line 267: } Line 268: Line 269: private void RenderGroupStatus(HtmlTextWriter writer, Status status) Line 270: { Line 271: RenderStatus(writer, status.ToString("smallimgpath", null), status.ToString()); Line 272: } Line 273: Line 274: private void RenderNodeStatus(HtmlTextWriter writer, CompoundStatus status) Line 275: { Line 276: string alt; Line 277: if (status.ChildStatus.Value == OBJECT_STATUS.Up) Line 278: alt = string.Format("Node status is {0}.", status.ParentStatus); Line 279: else Line 280: alt = string.Format("Node status is {0}, and one or more interfaces have a status of {1}.", Line 281: status.ParentStatus, status.ChildStatus); Line 282: Line 283: RenderStatus(writer, status.ToString("smallimgpath", null), alt); Line 284: } Line 285: Line 286: private void RenderStatus(HtmlTextWriter writer, string iconPath, string alt) Line 287: { Line 288: writer.BeginRender(); Line 289: Line 290: writer.AddAttribute(HtmlTextWriterAttribute.Class, "StatusIcon"); Line 291: Line 292: writer.AddAttribute(HtmlTextWriterAttribute.Alt, alt); Line 293: writer.AddAttribute(HtmlTextWriterAttribute.Src, iconPath); Line 294: writer.RenderBeginTag(HtmlTextWriterTag.Img); Line 295: writer.RenderEndTag(); Line 296: Line 297: writer.EndRender(); Line 298: } Line 299: } Line 300: |