2013-03-27 193 views
3

我正在尝试进入修订历史记录,但我不确定如何实现。无论我做什么,它都会返回null。相关代码如下:修订历史和修订

 string objectType = "HierarchicalRequirement"; 
     string orderString = ""; 
     bool fetchFullObjects = true; 
     long start = 1; 
     long pageSize = 200; 
     QueryResult queryResult = Global.service.query(Global.workspace, objectType, queryString, orderString, fetchFullObjects, start, pageSize); 
     int cnt = 0; 
     for (int i = 0; i < queryResult.Results.Length; i++) 
     { 
      // Results array is of type "DomainObject" 
      DomainObject rallyobject = queryResult.Results[i]; 
      HierarchicalRequirement story = (HierarchicalRequirement)rallyobject; 
      var rev = story.RevisionHistory; 

      if (rev.Revisions != null) 
      { 
        // traverse revisions for info, never gets here 
      } 

      dataGridView3.Rows.Add(new object[] { story.FormattedID, story.Description, story.InProgressDate, story.AcceptedDate, story.PlanEstimate}); 

     } 

     // Return the avereage days from inprogress to accepted 
     return; 
    } 

在调试,转速总是回来空..

也许我错误地铸造查询结果?

回答

3

要关闭循环,下面是一个演示如何执行Kyle提到的service.read()的示例。 Mark建议使用LBAPI将是一种更稳健的方式来跟踪工件快照,但您必须自行构建REST查询URL到LBAPI,Rally没有用于LBAPI的C#SDK(尚未) 。

只是单挑,特别是如果您刚开始构建集成,我强烈建议使用Rally的.NET REST SDK而不是SOAP之一。

REST更健壮,性能更高,Webservices API 1.4x(x尚未确定)将成为支持SOAP的最终API版本。 Webservices 2。x将仅用于REST,因此使用REST对于任何希望新的Web服务功能向前发展的人都是必不可少的。

namespace SOAP_QueryStoryRevisions 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 

      // create a service object 
      RallyServiceService service = new RallyServiceService(); 

      // Credentials 
      string rallyUser = "[email protected]"; 
      string rallyPassword = "topsecret"; 

      // set the service URL 
      service.Url = "https://rally1.rallydev.com/slm/webservice/1.37/RallyService"; 

      // login to service using HTTP Basic auth 
      System.Net.NetworkCredential credential = 
       new System.Net.NetworkCredential(rallyUser, rallyPassword); 

      Uri uri = new Uri(service.Url); 
      System.Net.ICredentials credentials = credential.GetCredential(uri, "Basic"); 
      service.Credentials = credentials; 
      service.PreAuthenticate = true; 

      // Configure the service to maintain an HTTP session cookie 
      service.CookieContainer = new System.Net.CookieContainer(); 

      // Get current user 
      User user = (User)service.getCurrentUser(); 

      // Get reference to UserProfile for current user 
      UserProfile profile = new UserProfile(); 
      [email protected] = [email protected]; 

      // Read will return a WSObject that you can then cast to a UserProfile 
      WSObject resultobj = service.read(profile); 
      UserProfile newprofile = (UserProfile)resultobj; 

      // Default workspace for current user 
      Console.WriteLine([email protected]); 

      // set workspace for query 
      Workspace workspace = new Workspace(); 
      [email protected] = [email protected]; 

      // Make the web service call 
      //--------------------------- 

      // Look for Stories 
      string objectType = "hierarchicalrequirement"; 

      // Find Stories 
      string queryString = "(FormattedID < US100)"; 

      // Order by FormattedID Ascending 
      string orderString = "FormattedID asc"; 

      // Fetch full objects, or return just object shells 
      // with the "@ref" attribute set. You can fetch the full version 
      // of a ref object later by calling service.read(). 
      bool fetchFullObjects = true; 

      // Paging information 
      long start = 0; 
      long pageSize = 200; 

      // Query for project 
      QueryResult projectQueryResult = service.query(workspace, "Project", "(Name = \"My Project\")", orderString, fetchFullObjects, start, pageSize); 

      // look at the object returned from query() 
      Console.WriteLine("Query returned " + projectQueryResult.TotalResultCount + " Projects"); 

      // Grab project 
      DomainObject myProjectObject = projectQueryResult.Results[0]; 
      Project myProject = (Project)myProjectObject; 

      // issue query 
      QueryResult queryResult = service.query(workspace, myProject, true, true, objectType, queryString, orderString, fetchFullObjects, start, pageSize); 

      // look at the object returned from query() 
      Console.WriteLine("Query returned " + queryResult.TotalResultCount + " objects"); 

      // loop through results returned 

      Console.WriteLine("There are " + queryResult.Results.Length + " objects on this page"); 
      for (int i = 0; i < queryResult.Results.Length; i++) 
      { 
       // Results array is of type "DomainObject" 
       DomainObject rallyobject = queryResult.Results[i]; 
       Console.WriteLine(" result[" + i + "] = " + rallyobject); 
       Console.WriteLine("   ref = " + [email protected]); 

       HierarchicalRequirement myStory = (HierarchicalRequirement)rallyobject; 

       Console.WriteLine("===>   FormattedID = " + myStory.FormattedID); 
       Console.WriteLine("===>   Story Name = " + myStory.Name); 

       RevisionHistory myStoryRevisionHistory = myStory.RevisionHistory; 

       // Perform service.read on RevisionHistory 
       RevisionHistory myRevisionHistoryHydrated = (RevisionHistory)service.read(myStoryRevisionHistory); 

       // Grab revisions 
       Revision[] myRevisions = myRevisionHistoryHydrated.Revisions; 

       // Loop through each Revision and read it, output summary 
       for (int j = 0; j < myRevisions.Length; j++) 
       { 
        Revision revisionHydrated = (Revision)service.read(myRevisions[j]); 
        Console.WriteLine("===>    Revision[" + j + "] = " + revisionHydrated.RevisionNumber); 
        Console.WriteLine("===>    Description: " + revisionHydrated.Description); 
       } 
      } 

      Console.ReadKey(); 
     } 

     // determine if the result had errors 
     static bool hasErrors(OperationResult result) 
     { 
      return (result.Errors.Length > 0); 
     } 

     // print warnings and errors to the console 
     static void printWarningsErrors(OperationResult result) 
     { 
      if (result.Warnings.Length > 0) 
      { 
       Console.WriteLine("Result has warnings:"); 
       for (int i = 0; i < result.Warnings.Length; i++) 
       { 
        Console.WriteLine(" warnings[" + i + "] = " + result.Warnings[i]); 
       } 
      } 
      if (result.Errors.Length > 0) 
      { 
       Console.WriteLine("Result has errors:"); 
       for (int i = 0; i < result.Errors.Length; i++) 
       { 
        Console.WriteLine(" errors[" + i + "] = " + result.Errors[i]); 
       } 
      } 
     } 
    } 
+0

感谢马克,这看起来像我在找什么,标记这是正确的答案,因为它确实回答了我如何解决这个问题。话虽如此,我将开始寻找REST API。 – user1537867 2013-03-29 18:37:44

+0

如何使用.NET的API?我的简单查询不会返回任何结果,但我甚至可以通过带有对象ID的url访问修订历史记录 {*要获取的字段*/ Fetch = new List Query = new Query(“ObjectID”,Query.Operator.Equals,_objectID。(){“CreationDate”,“Revisions”}, /*添加查询 - 查询美国ID等于'_formattedID'*/ Query = ToString()) }; – 2013-07-01 16:02:19

+0

真的很丑,但我不知道该怎么办......不想创建新的问题 – 2013-07-01 16:02:47

0

我不确定你可以使用SOAP做到这一点。 fetchFullObjects参数不会填充修订历史记录和修订版本等子对象字段。这些字段可通过WSAPI在一个请求中使用,但可通过在提取参数中指定它们。

在这种情况下,您可能需要执行service.read(rev)来填充修订版。

0

我不知道你想什么用的修订历史的事,但另一种选择,你可能想看看是新的回溯API:

https://rally1.rallydev.com/analytics/doc/

这给出了一个REST API具有更丰富和可解析的文物历史观。例如,要查找与对象ID 1234(或分项目)项目下的故事的完整历史,你可以这样做:

find={ _ProjectHierarchy: 1234, _TypeHierarchy: "HierarchicalRequirement" } 

对于分析团队,完整的URL将是:

https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/41529001/artifact/snapshot/query.js?find={_ProjectHierarchy:279050021,_TypeHierarchy:"HierarchicalRequirement"} 

其中41529001是工作区的ObjectID,279050021是项目OID。

https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/41529001/artifact/snapshot/query.js?find={_ProjectHierarchy:279050021,_TypeHierarchy:%22HierarchicalRequirement%22}&fields=true 

注意,表格=真被限制在200:

你,当你在开发模式是要弄清楚什么是可用字段添加参数,指定要回场,或字段=真但每页的结果,所以你应该指定你想要在生产中的字段的实际列表。例如,返回对象ID,故事名称和日期创建快照,它会成为:

https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/41529001/artifact/snapshot/query.js?find={_ProjectHierarchy:279050021,_TypeHierarchy:%22HierarchicalRequirement%22}&fields=[%22ObjectID%22,%20%22Name%22,%20%22_ValidFrom%22,%20%22_ValidTo%22] 

另一个特点可能是从这个快照模型兴趣是_PreviousValues领域,其持有的旧值在当前快照中更改的字段,因此您可以检测(并查询)工件状态中的更改。更多的信息在这里: https://rally1.rallydev.com/analytics/doc/Analytics2.0LookbackAPIUserManual.html?_debugResources=y&n=1364482493883#h.uv4o9mhshx4

希望这会有所帮助。

0

以下是使用REST获取和显示修订历史的方法。

import com.google.gson.JsonObject; 
import com.rallydev.rest.RallyRestApi; 
import com.rallydev.rest.request.QueryRequest; 
import com.rallydev.rest.response.QueryResponse; 
import com.rallydev.rest.util.Fetch; 
import com.rallydev.rest.util.QueryFilter; 

import java.io.IOException; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.util.Comparator; 
import java.util.HashMap; 
import java.util.TreeSet; 

public class revisions { 

    public static void main(String[] args) throws URISyntaxException, IOException { 

     // Configure RallyRestApi 
     final String rallyURL = "https://rally1.rallydev.com"; 
     final String wsapiVersion = "v2.0"; 
     final RallyRestApi restApi = new RallyRestApi(new URI(rallyURL), "RallyID", "password"); // TODO: update id/password 
     restApi.setWsapiVersion(wsapiVersion); 

     // Select and query project information 
     final String myProject = "A Project Name";      // TODO: update project name 
     QueryRequest projectRequest = new QueryRequest("Project"); 
     projectRequest.setFetch(new Fetch("Name", "Iterations")); 
     projectRequest.setQueryFilter(new QueryFilter("Name", "=", myProject)); 
     QueryResponse projectQueryResponse = restApi.query(projectRequest); 
     String iterationListRef = projectQueryResponse.getResults().get(0).getAsJsonObject().get("Iterations").getAsJsonObject().get("_ref").toString().replaceAll("\"", ""); 
     iterationListRef = iterationListRef.substring(iterationListRef.indexOf("Project")); 

     // Query and store iteration information 
     QueryRequest iterationRequest = new QueryRequest(iterationListRef); 
     QueryResponse iterationQueryResponse = restApi.query(iterationRequest); 

     HashMap<String, String> iterations = new HashMap<String, String>(); 
     String iterationName = "", iterationStartDate=""; 
     int irc = iterationQueryResponse.getTotalResultCount(); 
     for (int iter = 0; iter < irc; iter++) { 
      JsonObject iterationObj = iterationQueryResponse.getResults().get(iter).getAsJsonObject(); 

      iterationName = iterationObj.get("_refObjectName").toString(); 
      iterationName = iterationName.substring(1, iterationName.length()-1); 
      iterationStartDate = iterationObj.get("StartDate").toString().replaceAll("\"", "").substring(0, 10); 
      iterations.put(iterationName, iterationStartDate); 
     } 

     // Query and store story information 
     QueryRequest storyRequest = new QueryRequest("HierarchicalRequirement"); 
     String ir = iterationRequest.toUrl(); 
     storyRequest.setProject(ir.substring(0, ir.indexOf("/iterations"))); 
     QueryResponse storyQueryResponse = restApi.query(storyRequest); 

     TreeSet<StoryInfo> stories = new TreeSet<StoryInfo>(new StoryComp()); 
     String refIteration = "", storyID = "", storyName = "", revHistory = ""; 
     int src = storyQueryResponse.getTotalResultCount(); 
     for (int story = 0; story < src; story++) {   
      JsonObject storyOjb = storyQueryResponse.getResults().get(story).getAsJsonObject(); 

      refIteration = storyOjb.get("Iteration").toString(); 
      if (refIteration.contains("_refObjectName")) 
       refIteration = storyOjb.get("Iteration").getAsJsonObject().get("_refObjectName").toString().replaceAll("\"", ""); 

      storyID = storyOjb.get("FormattedID").toString(); 
      storyID = storyID.substring(1, storyID.length()-1); 

      storyName = storyOjb.get("_refObjectName").toString().replaceAll("\"", ""); 

     revHistory = storyOjb.get("RevisionHistory").getAsJsonObject().get("_ref").toString().replaceAll("\"", ""); 
     revHistory = revHistory.substring(revHistory.indexOf("revisionhistory"))+"/Revisions"; 

     stories.add(new StoryInfo(refIteration, ""+iterations.get(refIteration), storyID, storyName, revHistory)); 
     } 

     System.out.println("Project: "+myProject); 
     for (StoryInfo s:stories) { 
      // Print the story iteration, id, name and revisions! 
     System.out.println('\n'+s.iteration+" - "+s.id+" "+s.name); 
     QueryRequest historyRequest = new QueryRequest(s.revHist); 
     QueryResponse historyResponse = restApi.query(historyRequest); 
     final int hrc = historyResponse.getTotalResultCount(); 
     for (int rev = 1; rev < hrc; rev++) { 
      JsonObject historyObj = historyResponse.getResults().get(rev).getAsJsonObject(); 
//   System.out.println(historyObj);  // BINGO !!! 
      System.out.println(historyObj.get("RevisionNumber")+" "+historyObj.get("CreationDate")+" "+historyObj.get("Description")); 
     }     
     } 
     restApi.close(); 
    } 

    static class StoryComp implements Comparator<StoryInfo> { 
     public int compare(StoryInfo i1, StoryInfo i2) { 
      return (i1.startDate+i1.id).compareTo(i2.startDate+i2.id); 
     } 
    } 

    static class StoryInfo { 
     String iteration, startDate, id, name, revHist; 
     StoryInfo(String it, String sd, String i, String n, String rh) { 
      iteration = it; startDate = sd; id = i; name = n; revHist = rh; 
     } 
    } 

}