@@ -18,7 +18,11 @@ public class CxProjects
1818 {
1919 private static ILog _log = LogManager . GetLogger ( typeof ( CxProjects ) ) ;
2020
21- private static String URL_SUFFIX = "cxrestapi/projects" ;
21+ private static readonly String REST_URL_SUFFIX = "cxrestapi/projects" ;
22+
23+ private static readonly int ODATA_TOP = 25 ;
24+ private static readonly String ODATA_URL_SUFFIX = "cxwebinterface/odata/v1/Projects?$expand=CustomFields&$select=OwningTeamId,PresetId,Id,Name,IsPublic" +
25+ $ "&$orderby=Id asc&$top={ ODATA_TOP } ";
2226
2327 private static String _apiVersion = null ;
2428
@@ -41,29 +45,94 @@ private static String GetApiVersion(CxSASTRestContext ctx, CancellationToken tok
4145 private CxProjects ( )
4246 { }
4347
48+ #region DTOs
49+
4450 [ JsonObject ( MemberSerialization . OptIn ) ]
4551 public class ProjectCustomFields
4652 {
4753 [ JsonProperty ( PropertyName = "name" ) ]
4854 public String FieldName { get ; internal set ; }
55+
56+ [ JsonProperty ( PropertyName = "FieldName" ) ]
57+ private String odata_FieldName
58+ {
59+ get => FieldName ;
60+ set => FieldName = value ;
61+ }
62+
63+
4964 [ JsonProperty ( PropertyName = "value" ) ]
5065 public String FieldValue { get ; internal set ; }
66+
67+ [ JsonProperty ( PropertyName = "FieldValue" ) ]
68+ private String odata_FieldValue
69+ {
70+ get => FieldValue ;
71+ set => FieldValue = value ;
72+ }
73+
5174 }
5275
5376 [ JsonObject ( MemberSerialization . OptIn ) ]
5477 public class Project
5578 {
5679 [ JsonProperty ( PropertyName = "teamId" ) ]
5780 public String TeamId { get ; internal set ; }
81+ [ JsonProperty ( PropertyName = "OwningTeamId" ) ]
82+ private String odata_TeamId
83+ {
84+ get => TeamId ;
85+ set => TeamId = value ;
86+ }
87+
88+
89+
5890 public int PresetId { get ; internal set ; }
91+
92+
5993 [ JsonProperty ( PropertyName = "id" ) ]
6094 public int ProjectId { get ; internal set ; }
95+ [ JsonProperty ( PropertyName = "Id" ) ]
96+ private int odata_ProjectId
97+ {
98+ get => ProjectId ;
99+ set => ProjectId = value ;
100+ }
101+
102+
61103 [ JsonProperty ( PropertyName = "name" ) ]
62104 public String ProjectName { get ; internal set ; }
105+ [ JsonProperty ( PropertyName = "Name" ) ]
106+ private String odata_ProjectName
107+ {
108+ get => ProjectName ;
109+ set => ProjectName = value ;
110+ }
111+
112+
113+
114+
63115 [ JsonProperty ( PropertyName = "isPublic" ) ]
64116 public bool IsPublic { get ; internal set ; }
117+ [ JsonProperty ( PropertyName = "IsPublic" ) ]
118+ private bool odata_IsPublic
119+ {
120+ get => IsPublic ;
121+ set => IsPublic = value ;
122+ }
123+
124+
125+
65126 [ JsonProperty ( PropertyName = "customFields" ) ]
66127 public List < ProjectCustomFields > CustomFields { get ; internal set ; }
128+ [ JsonProperty ( PropertyName = "CustomFields" ) ]
129+ private List < ProjectCustomFields > odata_CustomFields
130+ {
131+ get => CustomFields ;
132+ set => CustomFields = value ;
133+ }
134+
135+
67136
68137 [ JsonProperty ( PropertyName = "isBranched" ) ]
69138 public bool IsBranched { get ; internal set ; }
@@ -78,6 +147,7 @@ public class Project
78147 public override string ToString ( ) =>
79148 $ "{ ProjectId } :{ ProjectName } [TeamId: { TeamId } Public: { IsPublic } CustomFields: { CustomFields . Count } ]";
80149 }
150+ #endregion
81151
82152 private class ProjectReader : IEnumerable < Project > , IEnumerator < Project > , IDisposable
83153 {
@@ -161,12 +231,57 @@ public void Reset()
161231 {
162232 throw new NotImplementedException ( ) ;
163233 }
234+ }
164235
236+ private static IEnumerable < Project > GetProjects_odata ( CxSASTRestContext ctx , CancellationToken token )
237+ {
238+ List < Project > returnedResults = new ( ) ;
239+
240+ var filter = new Dictionary < String , String > ( ) ;
241+ List < Project > fetchedPage = null ;
242+
243+ do
244+ {
245+ String requestUrl = UrlUtils . MakeUrl ( ctx . Sast . ApiUrl , ODATA_URL_SUFFIX , filter ) ;
165246
247+ using ( var projectReader = WebOperation . ExecuteGet < ProjectReader > (
248+ ctx . Sast . Json . CreateClient
249+ , ( response ) =>
250+ {
251+ using ( var sr = new StreamReader ( response . Content . ReadAsStreamAsync ( ) . Result ) )
252+ using ( var jtr = new JsonTextReader ( sr ) )
253+ {
254+ JToken jt = JToken . Load ( jtr ) ;
255+
256+ return new ProjectReader ( jt [ "value" ] , ctx , token ) ;
257+ }
258+ }
259+ , requestUrl
260+ , ctx . Sast
261+ , token ) )
262+ fetchedPage = new List < Project > ( projectReader ) ;
263+
264+ if ( fetchedPage != null )
265+ {
266+ returnedResults . AddRange ( fetchedPage ) ;
267+ filter [ "$filter" ] = $ "id gt { fetchedPage [ fetchedPage . Count - 1 ] . ProjectId } ";
268+ }
269+
270+
271+ } while ( fetchedPage != null && fetchedPage . Count == ODATA_TOP ) ;
272+
273+ return returnedResults ;
166274 }
167275
276+ public static IEnumerable < Project > GetProjects ( CxSASTRestContext ctx , CancellationToken token , bool useOData )
277+ {
278+ if ( useOData )
279+ return GetProjects_odata ( ctx , token ) ;
280+ else
281+ return GetProjects_rest ( ctx , token ) ;
282+ }
168283
169- public static IEnumerable < Project > GetProjects ( CxSASTRestContext ctx , CancellationToken token )
284+ private static IEnumerable < Project > GetProjects_rest ( CxSASTRestContext ctx , CancellationToken token )
170285 {
171286 using ( var projectReader = WebOperation . ExecuteGet < ProjectReader > (
172287 ctx . Sast . Json . CreateClient
@@ -180,7 +295,7 @@ public static IEnumerable<Project> GetProjects(CxSASTRestContext ctx, Cancellati
180295 return new ProjectReader ( jt , ctx , token ) ;
181296 }
182297 }
183- , UrlUtils . MakeUrl ( ctx . Sast . ApiUrl , URL_SUFFIX )
298+ , UrlUtils . MakeUrl ( ctx . Sast . ApiUrl , REST_URL_SUFFIX )
184299 , ctx . Sast
185300 , token , apiVersion : GetApiVersion ( ctx , token ) ) )
186301 return new List < Project > ( projectReader ) ;
0 commit comments