Creation of new Iteration/Area Path from API doesn't take effect immediately.

คำตอบที่เสนอ Creation of new Iteration/Area Path from API doesn't take effect immediately.

  • Tuesday, February 12, 2013 7:11 AM
     
     

    Hi,

    I'm using TFS JAVA API for creating work items. I also have a logic to check and create Area/Iteration Paths if they don't exist.

    Issue I am facing is in creating new work item immediately after creation of Iteration/Area Path. It gives invalid path error even though paths are created in TFS. On second run of same program, it finds those path valid and creates work item.

    I don't want them to fail at first instance. I have debugged and verified that path were created before the call of WorkItem.save() method.

    From my side I have tried follow things, but they were not helpful

    1. Added delay of 10 seconds after creation on path before creating new workitem 

    2. Used different instance of TFSTeamProjectCollection, for creation of Iteration/Area Path and Workitem

    3. Added call to CommonStructureClient.getNode(String) before creating workitem to make sure newly created node is added

    In case I'm missing out something then do tell me.

    Thanks


    -- Manthan Shah

All Replies

  • Tuesday, February 12, 2013 9:00 PM
     
     

    Hi Manthan,

    After you create the new area node, you need to refresh the workitem cache by calling WorkItemClient.refreshCache();

    Please let me know if this does not fix your problem.

    Thanks

    Mireille

  • Wednesday, February 13, 2013 5:11 AM
     
      Has Code

    Hi Mireille,

    I did refresh cache as you directed, but no success. 

    I have done following calls after creating node.

    workItemClient.refreshCache();
    
    WorkItem workItem = workItemClient.newWorkItem(workItemType);
    
    //Set value for iteration and area path in workitem fiels
    
    String errorMessage="";
     for  (Field field :  workItem.getFields()) {
    	 if(field.getStatus()!=FieldStatus.VALID){
    		 errorMessage = errorMessage +field.getStatus().getInvalidMessage(field);
    	}
    }

    Error message gives me this message

    "The selected path for field 'Iteration Path' is invalid.The selected path for field 'Area Path' is invalid."

    Thanks



    -- Manthan Shah

  • Wednesday, February 13, 2013 8:04 PM
     
      Has Code

    Hi,

    Since I don't see the full source code, there might be two problems. First, you need to check that the workitem cache object that you refresh is the same one that you use to create the new work item. Second, you need to compute the new area path. here is a sample code for that:

     
                  WorkItemClient client = tpc.getWorkItemClient();
    
            // create a new area path
            String areaUri = tpc.getCommonStructureClient().createNode("AreaName", "parentURI");
    
            // refresh wit cache
            client.refreshCache();
    
            // Determine new node path
            Project project = client.getProjects().get(SnippetSettings.PROJECT_NAME);
            String itemPath = null;
            getNode(project.getAreaRootNodes().getNodes(), itemPath, 1, areaUri);
    
            // Create a new work item
            WorkItemType bugWorkItemType = project.getWorkItemTypes().get("Bug");
            WorkItem newWorkItem = client.newWorkItem(bugWorkItemType);
    
            // Set the title on the work item.
            newWorkItem.setTitle("Example Work Item");
    
            // Set the area path
            if (itemPath != null)
            {
                newWorkItem.getFields().getField(CoreFieldReferenceNames.AREA_PATH).setValue(itemPath);
            }
    
            // Save the new work item to the server.
            newWorkItem.save();
    
        }
    
        public static void getNode(Node[] nodes, String itemPath,
    
        final int depth, String uri)
        {
            Check.notNull(nodes, "nodes");
    
            if (itemPath != null)
            {
                return;
            }
    
            for (int i = 0; i < nodes.length; i++)
            {
    
                if (nodes[i].getURI().equals(uri))
                {
                    itemPath = nodes[i].getPath().toString();
    
                    return;
                }
    
                /* Depth first recursion */
                final Node[] children = nodes[i].getChildNodes().getNodes();
    
                if (children != null && children.length > 0)
                {
                    getNode(children, itemPath, depth + 1, uri);
                }
            }
    
        }

    Please let me know if this does not work for you.

    Thanks

    Mireille

  • Tuesday, February 19, 2013 12:21 PM
     
      Has Code

    Hi Mireille,

    I tried what you have mentioned. Still no success.

    Below is a main program that I have tried.

    import java.net.URLEncoder;
    
    import com.microsoft.tfs.core.TFSTeamProjectCollection;
    import com.microsoft.tfs.core.clients.commonstructure.CommonStructureClient;
    import com.microsoft.tfs.core.clients.commonstructure.NodeInfo;
    import com.microsoft.tfs.core.clients.workitem.CoreFieldReferenceNames;
    import com.microsoft.tfs.core.clients.workitem.WorkItem;
    import com.microsoft.tfs.core.clients.workitem.WorkItemClient;
    import com.microsoft.tfs.core.clients.workitem.fields.Field;
    import com.microsoft.tfs.core.clients.workitem.fields.FieldStatus;
    import com.microsoft.tfs.core.clients.workitem.project.Project;
    import com.microsoft.tfs.core.clients.workitem.wittype.WorkItemType;
    import com.microsoft.tfs.core.exceptions.TECoreException;
    
    
    public class TFS {
    	
    	private TFSTeamProjectCollection tpc;
    	private WorkItemClient workItemClient;
    
    	public void init (String tfsUrl,String collectionName,String userName,String userDomain,String userPassword) throws Exception
    	{
    		String tfsCollectionURL = tfsUrl + "/" + URLEncoder.encode(collectionName, "UTF-8");
    		tpc = new TFSTeamProjectCollection(tfsCollectionURL,userName,userDomain,userPassword);
    		workItemClient = tpc.getWorkItemClient();
    	}
    
    	private void createRandomWorkitem(String projectName,String path) throws Exception {
    		Project project = tpc.getWorkItemClient().getProjects().get(projectName);
    		WorkItemType workItemType = project.getWorkItemTypes().get("Bug");
    	
    		workItemClient.refreshCache();
    		
    		WorkItem workItem = workItemClient.newWorkItem(workItemType);
    		
    		workItem.getFields().getField(CoreFieldReferenceNames.TITLE).setValue("Randomly Created Bug");
    		workItem.getFields().getField(CoreFieldReferenceNames.WORK_ITEM_TYPE).setValue("Bug");
    		
    		Field areaPath = workItem.getFields().getField(CoreFieldReferenceNames.AREA_PATH);
    		areaPath.setValue(path);
    	
    		// This gets satisfied for first entity after area path creation
    		if(areaPath.getStatus()!=FieldStatus.VALID)
    			throw new Exception(areaPath.getStatus().getInvalidMessage(areaPath));
    		
    		workItem.save();
    		System.out.println("Saved: "+workItem.getID());
    		
    	}
    	
    	public void checkAndCreatePath(String projectName, String path) throws Exception {
    		
    		CommonStructureClient csc = tpc.getCommonStructureClient();
    		
    		String justPathName=path;
    		if(path.equals(projectName+"\\Area") ||path.equals(projectName) )
    			return;
    		if(path.startsWith(projectName+"\\")){
    			justPathName = path.substring(path.indexOf("\\")+1);
    			if(justPathName.startsWith("Area\\")){
    				justPathName = justPathName.substring(justPathName.indexOf("\\")+1);
    			}
    		}
    		String fullNodePath = projectName+"\\Area\\"+justPathName;
    		try{
    			csc.getNodeFrom(fullNodePath);
    		}catch(TECoreException e){
    			if(e.getMessage().contains("The following node does not exist:")){
    				String parentNode = fullNodePath.substring(0, fullNodePath.lastIndexOf("\\"));
    				String area = fullNodePath.substring(fullNodePath.lastIndexOf("\\")+1);	
    				NodeInfo parentNodeInfo = csc.getNodeFrom(parentNode);
    				csc.createNode(area, parentNodeInfo.getURI());
    				System.out.println("Node Created");
    			}
    			else
    				throw e;
    		}
    		
    		
    	}
    	
    	public static void main(String[] args) throws Exception {
    		TFS tfs = new TFS();
    		tfs.init("http://10.13.28.2:8080/tfs", "DefaultCollection", "tfs", null, "tfs");
    		String project = "Sample Project";
    	
    		String path = "Sample Project\\Path4"; //give new value for path over here
    		tfs.checkAndCreatePath(project,path);
    		tfs.createRandomWorkitem(project, path);
    	}
    
    	
    }
    

    To create correct workitem I need to run above program twice. It would be great if I get this thing working. 

    You can try executing this code, just change some values in main function.

    Thanks


    -- Manthan Shah

  • Tuesday, February 19, 2013 3:45 PM
     
     Proposed

    Hi Manthan,

    I tried your code and it is working for me fine, I needed to change only one line, when creating the new

    TFSTeamProjectCollection object, the current interface does not take a username, domain and password but instead it takes Credentials object. This makes me think that you are using an old version of the SDK. Could you please try the latest version of the SDK, you can download it from here:

    TFS JAVA SDK 2012

    Please let me know if this does not still work for you.

    Thanks

    Mireille

    

  • Monday, March 18, 2013 6:02 AM
     
     

    Hi Mireille,

    Sorry for really late reply. But using updated API also didn't work for me.

    The program is same as above and I changed only authentication. As you said it worked on your side, I'm very eager what I'm doing wrong.

    Also I would like to mention that on some of the others machines in my network, it worked as expected.

    Thank


    -- Manthan Shah

  • Monday, March 18, 2013 5:50 PM
     
     

    Hi Manthan,

    Since the same code runs and gives the expected results on some machines, may be it is a permissions issue, may be you need to run as root to have permissions to the location where we cache the data. If this is not the case, then I would recommend opening a support issue.

    Please let me know if you have other questions/issues.

    Thanks

    Mireille