PipelineMetadataService implements ApiRoutable { @GET @TreeResponse public ExportedToolDescriptor[] doToolMetadata() { List<ExportedToolDescriptor> models = new ArrayList<>(); for (ToolDescriptor<? extends ToolInstallation> d : ToolInstallation.all()) { ExportedToolDescriptor descriptor = new ExportedToolDescriptor(d.getDisplayName(), symbolForObject(d), d.getClass()); models.add(descriptor); for (ToolInstallation installation : d.getInstallations()) { descriptor.addInstallation(new ExportedToolDescriptor.ExportedToolInstallation(installation.getName(), installation.getClass())); } } return models.toArray(new ExportedToolDescriptor[models.size()]); }  @Override String getUrlName(); @GET String doCrumbInfo(); @GET @TreeResponse ExportedDescribableModel[] doAgentMetadata(); @GET @TreeResponse ExportedToolDescriptor[] doToolMetadata(); @GET @TreeResponse ExportedBuildCondition[] doBuildConditions(); @GET @TreeResponse ExportedPipelineStep[] doWrapperMetadata(); @GET @TreeResponse ExportedPipelineFunction[] doPipelineStepMetadata();  }
@Test public void toolMetadata() throws Exception { PipelineMetadataService svc = new PipelineMetadataService(); List<ExportedToolDescriptor> tools = new ArrayList<>(); tools.addAll(Arrays.asList(svc.doToolMetadata())); assertFalse(tools.isEmpty()); ExportedToolDescriptor t = null; for (ExportedToolDescriptor a : tools) { if (a.getType().equals(JDK.DescriptorImpl.class.getName())) { t = a; } } assertNotNull(t); assertEquals("jdk", t.getSymbol()); }