Saturday, April 2, 2016

Retrieve Repository Details from Git Hub API Using WSO2 GitHub Connector.



In this blog post I'm going to explain how to retrieve all the repository details for specified organization from Git Hub API using WSO2 GitHub Connector[1].

For this task following WSO2 GitHub Connector method can be used. 

       
<github.listOrganizationRepositories configKey="GH">
<org>wso2</org>
<type>public</type>
<page>1<page>
</github.listOrganizationRepositories>                     
       
 

Parameters :


org : Organization name
type : Type of the repository. Eg: public,private,forks etc. Default option is All
page : Page number 

But GitHub API uses pagination[2]. Therefore using the above method you can retrieve data only for the given page number . In other words there is no direct API call found to retrieve all the repository details for specified organization at once. To overcome this I successfully implemented the following ESB proxy service. Using this proxy service you can retrieve all the repository details for specified organization.
First you need to download WSO2 GitHub Connector [1] and add it to WSO2 ESB [4]. Then create a custom proxy service in ESB .

Proxy

 

       
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="Demo"
       transports="https,http"
       statistics="disable"
       trace="disable"
       startOnLoad="true">
   <target>
      <inSequence>
         <github.listOrganizationRepositories configKey="GH">
               <org>wso2</org>
         </github.listOrganizationRepositories>
         <property name="link"
                   expression="get-property('transport','Link')"
                   scope="default"
                   type="STRING"/>
         <script language="js">
                var link = mc.getProperty('link');
                var lastPage=1;
                var pageLink=link.split(",");
               
                for(var i in pageLink)
                {
                 if(pageLink[i].indexOf("last")!=-1){
                        
                         var result=pageLink[i].match(/page=(\d+)/);
                          lastPage=result[1];
                         break;
                 }
                }
                
                mc.setProperty("lastPage", lastPage);
                var pageNumberDataSet =new XML('<pages></pages>');
                var pageNumberChild;
                var num;
                
                for(var i=0 ;i < lastPage;i++)
                {
                      
                     num=i+1;
                     pageNumberChild= new XML('<pageNumber>' + num + '</pageNumber>');
                     pageNumberDataSet.prependChild(pageNumberChild);
                   
                }
              
                 mc.setProperty("pageNumberDataSet",pageNumberDataSet);
          </script>

         <property name="pageNumberDataSet"
                   expression="get-property('pageNumberDataSet')"
                   scope="default"
                   type="STRING"/>
         <payloadFactory media-type="xml">
            <format>
               <root xmlns="">$1</root>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('pageNumberDataSet')"/>
            </args>
         </payloadFactory>
         
         <iterate continueParent="true"
                  id="pageNumberIteratorInRepoList"
                  expression="//root/pages/pageNumber"
                  sequential="true">
            <target>
               <sequence>
                  <property name="pageNum"
                            expression="//pageNumber/text()"
                            scope="default"
                            type="STRING"/>
                  <github.listOrganizationRepositories configKey="GH">
                     <org>wso2</org>
                     <page>{$ctx:pageNum}</page>
                  </github.listOrganizationRepositories>
                  <log level="full"/>
               </sequence>
            </target>
         </iterate>
      </inSequence>
   </target>
   <description/>
</proxy>                      
       
 

Description 

 

       
<github.listOrganizationRepositories configKey="GH">
<org>wso2</org>
</github.listOrganizationRepositories>                     
       
 


From the above connector method I got the link for the next page and last page as shown below.

Link: <https://api.github.com/resource?page=2>; rel="next",
      <https://api.github.com/resource?page=5>; rel="last"

Then I assigned the link header to a property called 'link'. 
       
<property name="link"
expression="get-property('transport','Link')"
scope="default"
type="STRING"/>                    
       
 




Then I split the link header and got the last page number inside the  script mediator. And then create a XML payload using page numbers. XML payload format is as shown below.
       
<root>
<pages>
<pageNumber>1</pageNumber>
<pageNumber>2</pageNumber>
</pages>
</root>                   
       
 
Then I iterate through the above payload using Iterator mediator. To do this you need to use the XPath expression as //root/pages/pageNumber.

Then I used the following GitHub Connector method to retrieve the repository details inside the Iterator mediator. The following Connector method gives the repository details for the specified page number.
       
<github.listOrganizationRepositories configKey="GH">
<org>wso2</org>
<page>{$ctx:pageNum}</page>
</github.listOrganizationRepositories>                   
       
 
Here I used Local Entry called “GH” to store GitHub Init operation and then it used in proxy as the configKey.

You need to create a local entry with inline XML as shown below. You can use [5] to create local entry.
       
<github.init xmlns="http://ws.apache.org/ns/synapse">
<accessToken>xxxxxxxxxxxxxxxxxx</accessToken>
<apiUrl>https://api.github.com</apiUrl>
<mediaType>application/json</mediaType>
</github.init>                  
       
 

You can create an access token using your Git Hub account [3].




No comments:

Post a Comment