//------------------------------------------------------------------------------------ /// <summary> /// Given a treeID for this product's feature tree, returns the full path for that /// tree node. /// </summary> //------------------------------------------------------------------------------------ public virtual string GetTreePath(int treeID, ProductTreeFormat treeFormat) { DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList != null) { ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct; ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(treeType); ProductStudio.Node currNode = rootNode.FindNodeInSubtree(treeID); List <string> nodeNames = new List <string>(); while (currNode != null && currNode.ID > 1) { nodeNames.Insert(0, currNode.Name); currNode = currNode.Parent; } string fullPath = treeFormat == ProductTreeFormat.IncludeProduct ? StoreID.Name : ""; foreach (string name in nodeNames) { fullPath += "\\" + name; } return(fullPath); } return(null); }
/// <summary> /// Get changed BUGs from last modified time /// </summary> /// <param name="LastModifiedTime"></param> /// <returns></returns> public DatastoreItems GetBugListStartingFrom(DateTime LastModifiedTime) { string psQueryXml = "<Query>"; psQueryXml += "<Group GroupOperator='And'>"; psQueryXml += "<Expression Column='Changed Date' Operator='equalsGreater'><DateTime>" + LastModifiedTime.ToUniversalTime().ToString() + "</DateTime></Expression>"; //psQueryXml += "<Expression Column='Status' Operator='notequals'><String>Closed</String></Expression>"; psQueryXml += "</Group>"; psQueryXml += "</Query>"; DatastoreItemList psDataList = null; try { Query psQuery = new Query(); psQuery.CountOnly = false; psQuery.SelectionCriteria = psQueryXml; psDataList = new DatastoreItemList(); psDataList.Query = psQuery; psDataList.Datastore = this.psDataStore; psDataList.Execute(); } catch (Exception e) { throw new Exception(String.Format("Failed to Query bugs."), e); } return(psDataList.DatastoreItems); }
//------------------------------------------------------------------------------------ /// <summary> /// Create a new blank bug - the fields can be filled out, and then saved back to PS. /// </summary> //------------------------------------------------------------------------------------ public DatastoreItem CreateDSItem() { DatastoreItemList storeItemList = GetStoreItemList(); storeItemList.CreateBlank(ProductStudio.PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs); return(storeItemList.DatastoreItems.Add(null, ProductStudio.PsApplyRulesMask.psApplyRulesAll)); }
//------------------------------------------------------------------------------------ /// <summary> /// Returns the root node of the Product Tree for this product. /// </summary> //------------------------------------------------------------------------------------ public Node GetProductTreeRootNode() { DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList != null) { ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct; return(storeItemList.Datastore.get_RootNodeEx(treeType)); } return(null); }
//------------------------------------------------------------------------------------ /// <summary> /// Returns the complete product tree for the current product. The root will have /// parent id = -200. The returned tree is a depth-first representation of the product /// hierarchy. /// </summary> //------------------------------------------------------------------------------------ public virtual void PopulateTree(TreeView treeView, int startingTreeID) { DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList != null) { ProductStudio.PsCoreTreeTypeEnum treeType = ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct; ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(treeType); ProductAreaTree tree = new ProductAreaTree(rootNode); tree.PopulateTree(treeView, startingTreeID); } }
private DatastoreItemList GetStoreItemList(bool cacheStoreItemList = true) { try { if (m_storeItemList == null || ConnectionTime.Elapsed.Minutes > MaxConnectionMinutes) { ConnectionTime.Reset(); ProductStudio.Directory psDir = new ProductStudio.Directory(); psDir.Connect(); ProductStudio.Product psProduct = psDir.GetProductByName(StoreID.Name); DatastoreItemList storeItemList = new DatastoreItemList(); storeItemList.Datastore = psProduct.Connect(); // Simulate outdated Product Studio error //if (storeItemList.Datastore == null || storeItemList.Datastore != null) //{ // throw new Exception("[Product Studio] 80044005. Access to this product requires updated client components."); //} ConnectionTime.Start(); FieldDefs = storeItemList.Datastore.FieldDefinitions; if (cacheStoreItemList) { m_storeItemList = storeItemList; } else { return(storeItemList); } } return(m_storeItemList); } catch (Exception exception) { StringBuilder sb = new StringBuilder(); sb.AppendLine("Unable to connect to " + StoreID.Name); sb.AppendLine(); sb.AppendLine(exception.Message); sb.AppendLine(); Planner.Instance.WriteToEventLog(sb.ToString()); throw new Exception(sb.ToString()); } }
public List <int> GetTreeIDChildNodes(int treeID) { List <int> nodes = new List <int>(); nodes.Add(treeID); DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList != null) { ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct); Node startingNode = rootNode.FindNodeInSubtree(treeID); if (startingNode != null) { AddTreeIDChildNode(startingNode, nodes); } } return(nodes); }
public bool IsItemUnderTreeID(int treeID, int itemTreeID) { if (treeID == itemTreeID) { return(true); } DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList != null) { ProductStudio.Node rootNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct); Node startingNode = rootNode.FindNodeInSubtree(treeID); if (startingNode != null) { return(IsItemUnderTreeNode(startingNode, itemTreeID)); } } return(false); }
//------------------------------------------------------------------------------------ /// <summary> /// Given a path in this store's tree hierarchy, returns the treeID for that path. If /// the path isn't found, zero will be returned. /// </summary> //------------------------------------------------------------------------------------ public int GetTreePathID(string treePath) { if (treePath == null) { return(0); } DatastoreItemList storeItemList = GetStoreItemList(); if (storeItemList == null) { return(0); } char[] trim = { '\\' }; treePath = treePath.Trim(trim); ProductStudio.Node currentNode = storeItemList.Datastore.get_RootNodeEx(ProductStudio.PsCoreTreeTypeEnum.psCoreTreeTypeProduct); string[] pathNodes = treePath.Split('\\'); foreach (string pathNode in pathNodes) { bool foundNode = false; foreach (Node node in currentNode.Nodes) { if (node.Name == pathNode) { currentNode = node; foundNode = true; break; } } if (!foundNode) { return(0); } } return(currentNode.ID); }
//------------------------------------------------------------------------------------ /// <summary> /// Executes the given query against this data store. Returns false if a cancellation /// request is detected via the given taskWorker. /// </summary> //------------------------------------------------------------------------------------ public BackgroundTaskResult ExecuteQuery(IRepository repository, BaseQuery query, ShouldRefresh shouldRefresh, BackgroundTask taskWorker, bool deferItemCreation) { DatastoreItemList storeItemList = GetStoreItemList(); FieldDefinitions fieldDefs = storeItemList.Datastore.FieldDefinitions; // Set up a query, using QueryDefinition to define the query XML ProductStudio.Query psQuery = new ProductStudio.Query(); psQuery.CountOnly = false; psQuery.DatastoreItemType = PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs; psQuery.SelectionCriteria = query.QueryXml; psQuery.QueryFields.Clear(); psQuery.QuerySortFields.Clear(); psQuery.QuerySortFields.Add(fieldDefs["ID"], PsSortTypeEnum.psSortTypeDescending); // Execute the query try { storeItemList.Query = psQuery; storeItemList.Execute(); } catch (Exception e) { return(new BackgroundTaskResult { ResultType = ResultType.Failed, ResultMessage = e.Message }); } Planner.Instance.WriteToEventLog(StoreName + ": Query results count: " + storeItemList.DatastoreItems.Count.ToString()); repository.ReceiveDSItems(this, storeItemList.DatastoreItems, shouldRefresh, deferItemCreation); return(new BackgroundTaskResult { ResultType = ResultType.Completed }); }
public Int32 CreateNewBug(string psFieldDefXml) { bool hasInvalidField = false; // Create a new datastore instance DatastoreItemList psDataList = new DatastoreItemList(); psDataList.Datastore = this.psDataStore; // Craete a blank bug psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs); DatastoreItem psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll); // Set fields for the new bug Fields psFields = psDataItem.Fields; // New PS Bug Field Description XML file will look like // ======================================================= // <psfieldDef> // <Title> // Title (Ex. RFH: Hotfix for ...) // </Title> // <Tree Path> // Path (Ex. SCCM 2007 SP2) // </Tree Path> // <Issue type> // Issue Type (Ex. RFH / CDCR) // </Issue type> // <Get Help> // Get Help (Ex. Yes / No) // </Get Help> // <Priority> // Priority (Ex. 1, 2, 3, 4) // </Priority> // <Severity> // Severity (Ex. 1, 2, 3, 4) // </Severity> // <SMS Product> // SMS Product (Ex. x86 / x64) // </SMS Product> // <Component> // Component (Ex. component name) // </Component> // <FeatureArea> // Feature Area (Ex. feature area name) // </FeatureArea> // <Open Build> // Open Build (Ex. build version 6487.2000) // </Open Build> // <Language> // Language (Ex. ENU) // </Language> // <How found> // How Found (Ex. Internal) // </How found> // <Source> // Source (Ex. Ad Hoc) // </Source> // <Source ID> // Source ID (ex. Airforce) // </Source ID> // <PSS> // SR Number (ex. SR Number) // </PSS> // <KB Article> // KB Number (ex. KB Number 98765432) // </KB Article> // <Repro Steps> // Repro Steps (ex. Repro Steps) // </Repro Steps> // <Description> // Description (ex. Description) // </Description> // <Related Bugs> // SMS Sustained Engineering:5991 // </Related Bugs> // <QFE Status> // Core Review // </QFE Status> // </psfieldDef> XmlReader xmlReader = XmlReader.Create(new StringReader(psFieldDefXml)); while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "psfieldDef", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.Read(); // Read psfieldDef } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Tree Path", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <Tree Path> psFields["TreeID"].Value = this.GetTreeIDFromTreePath(this.psDataStore.RootNode, xmlReader.Value); xmlReader.Read(); xmlReader.ReadEndElement(); } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Related Bugs", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <RelatedBugs> string product = xmlReader.Value.Substring(0, xmlReader.Value.IndexOf(':')); Int32 bugId = 0; Int32.TryParse(xmlReader.Value.Substring(xmlReader.Value.IndexOf(':') + 1), out bugId); ((Bug)psDataItem).AddRelatedLink(bugId, product); xmlReader.Read(); xmlReader.ReadEndElement(); } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "File", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <File> ((Bug)psDataItem).Files.Add(xmlReader.Value); xmlReader.Read(); xmlReader.ReadEndElement(); } else { string fieldName = XmlConvert.DecodeName(xmlReader.Name); xmlReader.ReadStartElement(xmlReader.Name); // Read Start Element Ex. <Title> psFields[fieldName].Value = xmlReader.Value; xmlReader.Read(); xmlReader.ReadEndElement(); // Read End Element Ex. </Title> } } } // Let's make sure all fields are valid before saving foreach (Field psField in psDataItem.Fields) { if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid) { hasInvalidField = true; throw new Exception("Invalid Field (" + psField.Name + ") with Value (" + psField.Value + "). Counld not new bug!"); } } if (hasInvalidField) { throw (new ApplicationException("Invalid Field(s) were found. Could not create new bug.")); } else { psDataItem.Save(true); return(Convert.ToInt32(psFields["ID"].Value)); } }
/// <summary> /// Get changed BUGs from last modified time /// </summary> /// <param name="LastModifiedTime"></param> /// <returns></returns> public DatastoreItems GetBugListStartingFrom(DateTime LastModifiedTime) { string psQueryXml = "<Query>"; psQueryXml += "<Group GroupOperator='And'>"; psQueryXml += "<Expression Column='Changed Date' Operator='equalsGreater'><DateTime>" + LastModifiedTime.ToUniversalTime().ToString() + "</DateTime></Expression>"; //psQueryXml += "<Expression Column='Status' Operator='notequals'><String>Closed</String></Expression>"; psQueryXml += "</Group>"; psQueryXml += "</Query>"; DatastoreItemList psDataList = null; try { Query psQuery = new Query(); psQuery.CountOnly = false; psQuery.SelectionCriteria = psQueryXml; psDataList = new DatastoreItemList(); psDataList.Query = psQuery; psDataList.Datastore = this.psDataStore; psDataList.Execute(); } catch (Exception e) { throw new Exception(String.Format("Failed to Query bugs."), e); } return psDataList.DatastoreItems; }
public Int32 CreateNewBug(string psFieldDefXml) { bool hasInvalidField = false; // Create a new datastore instance DatastoreItemList psDataList = new DatastoreItemList(); psDataList.Datastore = this.psDataStore; // Craete a blank bug psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs); DatastoreItem psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll); // Set fields for the new bug Fields psFields = psDataItem.Fields; // New PS Bug Field Description XML file will look like // ======================================================= // <psfieldDef> // <Title> // Title (Ex. RFH: Hotfix for ...) // </Title> // <Tree Path> // Path (Ex. SCCM 2007 SP2) // </Tree Path> // <Issue type> // Issue Type (Ex. RFH / CDCR) // </Issue type> // <Get Help> // Get Help (Ex. Yes / No) // </Get Help> // <Priority> // Priority (Ex. 1, 2, 3, 4) // </Priority> // <Severity> // Severity (Ex. 1, 2, 3, 4) // </Severity> // <SMS Product> // SMS Product (Ex. x86 / x64) // </SMS Product> // <Component> // Component (Ex. component name) // </Component> // <FeatureArea> // Feature Area (Ex. feature area name) // </FeatureArea> // <Open Build> // Open Build (Ex. build version 6487.2000) // </Open Build> // <Language> // Language (Ex. ENU) // </Language> // <How found> // How Found (Ex. Internal) // </How found> // <Source> // Source (Ex. Ad Hoc) // </Source> // <Source ID> // Source ID (ex. Airforce) // </Source ID> // <PSS> // SR Number (ex. SR Number) // </PSS> // <KB Article> // KB Number (ex. KB Number 98765432) // </KB Article> // <Repro Steps> // Repro Steps (ex. Repro Steps) // </Repro Steps> // <Description> // Description (ex. Description) // </Description> // <Related Bugs> // SMS Sustained Engineering:5991 // </Related Bugs> // <QFE Status> // Core Review // </QFE Status> // </psfieldDef> XmlReader xmlReader = XmlReader.Create(new StringReader(psFieldDefXml)); while (xmlReader.Read()) { if (xmlReader.NodeType == XmlNodeType.Element) { if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "psfieldDef", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.Read(); // Read psfieldDef } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Tree Path", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <Tree Path> psFields["TreeID"].Value = this.GetTreeIDFromTreePath(this.psDataStore.RootNode, xmlReader.Value); xmlReader.Read(); xmlReader.ReadEndElement(); } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "Related Bugs", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <RelatedBugs> string product = xmlReader.Value.Substring(0, xmlReader.Value.IndexOf(':')); Int32 bugId = 0; Int32.TryParse(xmlReader.Value.Substring(xmlReader.Value.IndexOf(':') + 1), out bugId); ((Bug)psDataItem).AddRelatedLink(bugId, product); xmlReader.Read(); xmlReader.ReadEndElement(); } else if (string.Compare(XmlConvert.DecodeName(xmlReader.Name), "File", StringComparison.OrdinalIgnoreCase) == 0) { xmlReader.ReadStartElement(xmlReader.Name); // Read <File> ((Bug)psDataItem).Files.Add(xmlReader.Value); xmlReader.Read(); xmlReader.ReadEndElement(); } else { string fieldName = XmlConvert.DecodeName(xmlReader.Name); xmlReader.ReadStartElement(xmlReader.Name); // Read Start Element Ex. <Title> psFields[fieldName].Value = xmlReader.Value; xmlReader.Read(); xmlReader.ReadEndElement(); // Read End Element Ex. </Title> } } } // Let's make sure all fields are valid before saving foreach (Field psField in psDataItem.Fields) { if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid) { hasInvalidField = true; throw new Exception("Invalid Field (" + psField.Name + ") with Value (" + psField.Value + "). Counld not new bug!"); } } if (hasInvalidField) { throw (new ApplicationException("Invalid Field(s) were found. Could not create new bug.")); } else { psDataItem.Save(true); return Convert.ToInt32(psFields["ID"].Value); } }
//------------------------------------------------------------------------------------ /// <summary> /// Pulls the DatastoreItem with the given ID from the backing store. /// </summary> //------------------------------------------------------------------------------------ private DatastoreItem DSItemByID(int itemID) { DatastoreItemList storeItemList = GetStoreItemList(false); return(storeItemList.Datastore.GetDatastoreItem(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs, itemID)); }
//Details //http://bgit/applications/help/productstudiosdk/default.asp?URL=PSSDK_Main.htm public static int FileABug(string title, string reproSteps, string expectedResult, string actualResult, string attachmentFolder) { int bugID = 0; bool hasInvalidField = false; Directory psDirectory = null; Product psProduct = null; Datastore psDataStore = null; Fields psFields = null; DatastoreItemList psDataList = null; DatastoreItem psDataItem = null; Bug psBug = null; // Specify the product database to use and the domain in which // the database is located. string strProductName = "Office15"; string strDomain1 = "fareast.corp.microsoft.com"; string strDomain2 = "redmond.corp.microsoft.com"; string strDomain3 = "corp.microsoft.com"; try { // // Connect to the directory with your current domain under your credentials . // psDirectory = new Directory(); try { //first try with fareast psDirectory.Connect(strDomain1, "", ""); } catch (Exception e1) { Console.WriteLine("Fareast Connect Error: {0}", e1.Message); try { //if fareast fails, try redmond psDirectory.Connect(strDomain2, "", ""); } catch (Exception e2) { Console.WriteLine("Redmond Connect Error: {0}", e2.Message); //if both fareast & redmond fail, try global domain psDirectory.Connect(strDomain3, "", ""); } } psProduct = psDirectory.GetProductByName(strProductName); psDataStore = psProduct.Connect("", "", ""); // // Bind the query and Datastore to our DatastoreItemList. // psDataList = new DatastoreItemList(); psDataList.Datastore = psDataStore; // // Create a blank bug // psDataList.CreateBlank(PsDatastoreItemTypeEnum.psDatastoreItemTypeBugs); psDataItem = psDataList.DatastoreItems.Add(null, PsApplyRulesMask.psApplyRulesAll); psBug = psDataItem as Bug; // // Set fields for the new bug // psFields = psBug.Fields; psFields["Title"].Value = "[LWA]" + title; psFields["TreeID"].Value = TreeIDFromPath(psDataStore.RootNode, "Current\\Lync Client\\Lync Web App"); psFields["Assigned to"].Value = "Active"; psFields["Severity"].Value = 2; psFields["Priority"].Value = 2; psFields["Open Build"].Value = "5.0.0000.0000"; psFields["Ship Cycle"].Value = "O15 Main Wave"; psFields["Fix By"].Value = "Beta1Refresh"; psFields["Repro Steps"].Value = "Repro Steps:" + Environment.NewLine + "============" + Environment.NewLine + (string.IsNullOrEmpty(reproSteps) ? "1. Sign in as User A from LWA" : reproSteps) + Environment.NewLine + Environment.NewLine + "Actual Results:" + Environment.NewLine + "===============" + Environment.NewLine + (string.IsNullOrEmpty(actualResult) ? "1. " : actualResult) + Environment.NewLine + Environment.NewLine + "Expected Results:" + Environment.NewLine + "=================" + Environment.NewLine + (string.IsNullOrEmpty(expectedResult) ? "1. " : expectedResult) + Environment.NewLine; // // Let's make sure all fields are valid before saving // foreach (ProductStudio.Field psField in psBug.Fields) { if (psField.Validity != PsFieldStatusEnum.psFieldStatusValid) { hasInvalidField = true; Console.WriteLine("Invalid Field '{0}': {1}", psField.Name, psField.Validity.ToString()); Console.WriteLine("Current Value: '{0}'", psField.Value); Console.WriteLine(); } } if (hasInvalidField) { throw (new ApplicationException("Invalid Field(s) were found. Could not create.")); } else { if (!string.IsNullOrEmpty(attachmentFolder)) { string[] files = System.IO.Directory.GetFiles(attachmentFolder); foreach (string file in files) { psBug.Files.Add(file, false); } } psBug.Save(true); bugID = Convert.ToInt32(psFields["ID"].Value); Console.WriteLine("Bug #{0} Successfully Created.", bugID); } } catch (Exception e3) { Console.WriteLine("Error: {0}", e3.Message); } finally { if (null != psDirectory) { try { psDirectory.Disconnect(); } catch (Exception e4) { Console.WriteLine("Disconnect Error: {0}", e4.Message); } } } return(bugID); }