技术问询:获取复制Rally模板至Features的Java示例代码及项目模板API
Got it, let's break this down step by step. Below is a complete Java example using the Rally Rest API to copy existing templates to Features, plus all the key API details for fetching templates under a specific project.
Prerequisites
First, you'll need to include the Rally Rest API Java client in your project. If you're using Maven, add this dependency to your pom.xml:
<dependency> <groupId>com.rallydev.rest</groupId> <artifactId>rally-rest-api</artifactId> <version>2.2.1</version> </dependency>
Java Code Example: Copy Templates to Features
This code will first fetch all Portfolio Item Templates (specifically for Features) under your target project, then create new Feature items by copying the template's key fields.
import com.rallydev.rest.RallyRestApi; import com.rallydev.rest.request.QueryRequest; import com.rallydev.rest.request.CreateRequest; import com.rallydev.rest.response.QueryResponse; import com.rallydev.rest.response.CreateResponse; import com.rallydev.rest.util.Fetch; import com.rallydev.rest.util.QueryFilter; import com.rallydev.rest.util.Ref; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; public class RallyTemplateToFeatureCopier { public static void main(String[] args) throws URISyntaxException, IOException { // Replace these with your actual Rally credentials and project details String rallyServerUrl = "https://rally1.rallydev.com"; String apiKey = "your-rally-api-key-here"; String projectName = "Your Target Project Name"; String workspaceRef = "/workspace/12345678901"; // Replace with your workspace ref ID // Initialize Rally Rest API client RallyRestApi restApi = new RallyRestApi(new URI(rallyServerUrl), apiKey); restApi.setApplicationName("Template-to-Feature Copier"); try { // Step 1: Fetch all Feature templates under the target project QueryRequest templateRequest = new QueryRequest("PortfolioItem/Template"); templateRequest.setFetch(new Fetch("Name", "Description", "Project", "CustomFields", "PortfolioItemType")); templateRequest.setQueryFilter(new QueryFilter("Project.Name", "=", projectName) .and(new QueryFilter("PortfolioItemType.Name", "=", "Feature"))); templateRequest.setWorkspace(workspaceRef); templateRequest.setLimit(20); // Adjust based on how many templates you have QueryResponse templateResponse = restApi.query(templateRequest); if (templateResponse.wasSuccessful()) { System.out.println("Fetched " + templateResponse.getTotalResultCount() + " Feature templates"); // Step 2: Copy each template to a new Feature for (int i = 0; i < templateResponse.getResults().size(); i++) { com.google.gson.JsonObject template = templateResponse.getResults().get(i).getAsJsonObject(); // Create new Feature object with copied fields com.google.gson.JsonObject newFeature = new com.google.gson.JsonObject(); newFeature.addProperty("Name", "[Copied from Template] " + template.get("Name").getAsString()); newFeature.addProperty("Description", template.get("Description").getAsString()); newFeature.addProperty("Project", template.get("Project").getAsJsonObject().get("_ref").getAsString()); // Copy custom fields if needed (adjust field names to match your Rally setup) if (template.has("CustomFields")) { com.google.gson.JsonObject customFields = template.get("CustomFields").getAsJsonObject(); if (customFields.has("YourCustomFieldName")) { newFeature.addProperty("YourCustomFieldName", customFields.get("YourCustomFieldName").getAsString()); } } // Send create request for the new Feature CreateRequest createRequest = new CreateRequest("PortfolioItem/Feature", newFeature); CreateResponse createResponse = restApi.create(createRequest); if (createResponse.wasSuccessful()) { System.out.println("Successfully created Feature: " + Ref.getRelativeRef(createResponse.getObject().get("_ref").getAsString())); } else { System.err.println("Failed to create Feature from template: " + template.get("Name").getAsString()); for (String error : createResponse.getErrors()) { System.err.println("Error: " + error); } } } } else { System.err.println("Failed to fetch templates"); for (String error : templateResponse.getErrors()) { System.err.println("Error: " + error); } } } finally { // Clean up the API client restApi.close(); } } }
Key API Details for Fetching Project Templates
Endpoint & Resource Type
Rally stores Portfolio Item templates under the PortfolioItem/Template resource type. The base API endpoint is:
https://rally1.rallydev.com/slm/webservice/v2.0/portfolioitem/template
Filtering Templates by Project
To narrow down templates to a specific project, use a query filter in your request. For example:
- Query string:
(Project.Name = "Your Project Name") - If you know the project's ref ID, use that instead for better performance:
(Project = "/project/12345678901")
Fetching Relevant Fields
Use the fetch parameter to specify which fields you want to retrieve from the templates. Common fields include:
Name: Template nameDescription: Template descriptionProject: The project the template belongs toPortfolioItemType: The type of Portfolio Item the template is for (e.g., Feature, Initiative)CustomFields: Any custom fields defined on the template
Pagination
If you have more than 20 templates (the default limit), use the pagesize parameter to increase the result count per page, and the start parameter to iterate through pages. For example:
?pagesize=50&start=21
Quick Notes
- Always use your Rally API key for authentication (it's more secure than username/password).
- Replace all placeholder values (API key, project name, workspace ref, custom field names) with your actual Rally environment details.
- Test with a small number of templates first to ensure the copy logic works as expected.
内容的提问来源于stack exchange,提问作者Learn Hadoop

