NIFI-250:
- Adding endpoints for obtaining [processor|controller service|reporting task] 
property descriptors.

Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/e0e2d161
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/e0e2d161
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/e0e2d161

Branch: refs/heads/NIFI-250
Commit: e0e2d161b5f577b2d3c012843c6fde2123cb3411
Parents: 02afcfb
Author: Matt Gilman <[email protected]>
Authored: Fri Mar 20 15:33:36 2015 -0400
Committer: Matt Gilman <[email protected]>
Committed: Fri Mar 20 15:33:36 2015 -0400

----------------------------------------------------------------------
 .../org/apache/nifi/web/NiFiServiceFacade.java  | 29 ++++++++
 .../nifi/web/StandardNiFiServiceFacade.java     | 42 ++++++++++++
 .../nifi/web/api/ControllerServiceResource.java | 70 +++++++++++++++++---
 .../apache/nifi/web/api/ProcessorResource.java  | 47 +++++++++++++
 .../nifi/web/api/ReportingTaskResource.java     | 66 ++++++++++++++++--
 .../org/apache/nifi/web/api/dto/DtoFactory.java |  2 +-
 6 files changed, 239 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
index f80545e..4166653 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
@@ -43,6 +43,7 @@ import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.ProcessorDTO;
 import org.apache.nifi.web.api.dto.ComponentHistoryDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
 import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
@@ -380,6 +381,16 @@ public interface NiFiServiceFacade {
     StatusHistoryDTO getProcessorStatusHistory(String groupId, String id);
 
     /**
+     * Get the descriptor for the specified property of the specified 
processor.
+     * 
+     * @param groupId
+     * @param id
+     * @param property
+     * @return 
+     */
+    PropertyDescriptorDTO getProcessorPropertyDescriptor(String groupId, 
String id, String property);
+    
+    /**
      * Gets all the Processor transfer objects for this controller.
      *
      * @param groupId
@@ -972,6 +983,15 @@ public interface NiFiServiceFacade {
     ControllerServiceDTO getControllerService(String controllerServiceId);
     
     /**
+     * Get the descriptor for the specified property of the specified 
controller service.
+     * 
+     * @param id
+     * @param property
+     * @return 
+     */
+    PropertyDescriptorDTO getControllerServicePropertyDescriptor(String id, 
String property);
+    
+    /**
      * Gets the references for specified controller service.
      * 
      * @param controllerServiceId
@@ -1060,6 +1080,15 @@ public interface NiFiServiceFacade {
     ReportingTaskDTO getReportingTask(String reportingTaskId);
     
     /**
+     * Get the descriptor for the specified property of the specified 
reporting task.
+     * 
+     * @param id
+     * @param property
+     * @return 
+     */
+    PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, String 
property);
+    
+    /**
      * Updates the specified reporting task.
      *
      * @param revision Revision to compare with current base revision

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index c75e123..c089d51 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -153,6 +153,8 @@ import org.apache.nifi.web.util.SnippetUtils;
 
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.Validator;
 import org.apache.nifi.controller.ReportingTaskNode;
 import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.service.ControllerServiceNode;
@@ -160,6 +162,7 @@ import 
org.apache.nifi.controller.service.ControllerServiceReference;
 import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
 import org.apache.nifi.web.dao.ControllerServiceDAO;
 import org.apache.nifi.web.dao.ReportingTaskDAO;
@@ -1733,6 +1736,19 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
+    public PropertyDescriptorDTO getProcessorPropertyDescriptor(String 
groupId, String id, String property) {
+        final ProcessorNode processor = processorDAO.getProcessor(groupId, id);
+        PropertyDescriptor descriptor = 
processor.getPropertyDescriptor(property);
+        
+        // return an invalid descriptor if the processor doesn't suppor this 
property
+        if (descriptor == null) {
+            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
+        }
+        
+        return dtoFactory.createPropertyDescriptorDto(descriptor);
+    }
+
+    @Override
     public StatusHistoryDTO getProcessorStatusHistory(String groupId, String 
id) {
         return controllerFacade.getProcessorStatusHistory(groupId, id);
     }
@@ -2039,6 +2055,19 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
+    public PropertyDescriptorDTO getControllerServicePropertyDescriptor(String 
id, String property) {
+        final ControllerServiceNode controllerService = 
controllerServiceDAO.getControllerService(id);
+        PropertyDescriptor descriptor = 
controllerService.getControllerServiceImplementation().getPropertyDescriptor(property);
+        
+        // return an invalid descriptor if the controller service doesn't 
support this property
+        if (descriptor == null) {
+            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
+        }
+        
+        return dtoFactory.createPropertyDescriptorDto(descriptor);
+    }
+    
+    @Override
     public Set<ControllerServiceReferencingComponentDTO> 
getControllerServiceReferencingComponents(String controllerServiceId) {
         final ControllerServiceNode service = 
controllerServiceDAO.getControllerService(controllerServiceId);
         return 
dtoFactory.createControllerServiceReferencingComponentsDto(service.getReferences());
@@ -2059,6 +2088,19 @@ public class StandardNiFiServiceFacade implements 
NiFiServiceFacade {
     }
 
     @Override
+    public PropertyDescriptorDTO getReportingTaskPropertyDescriptor(String id, 
String property) {
+        final ReportingTaskNode reportingTask = 
reportingTaskDAO.getReportingTask(id);
+        PropertyDescriptor descriptor = 
reportingTask.getReportingTask().getPropertyDescriptor(property);
+        
+        // return an invalid descriptor if the reporting task doesn't support 
this property
+        if (descriptor == null) {
+            descriptor = new 
PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build();
+        }
+        
+        return dtoFactory.createPropertyDescriptorDto(descriptor);
+    }
+    
+    @Override
     public StatusHistoryDTO getProcessGroupStatusHistory(String groupId) {
         return controllerFacade.getProcessGroupStatusHistory(groupId);
     }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index 0885ba8..85b2ea1 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -57,11 +57,14 @@ import 
org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.ui.extension.UiExtension;
 import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.UiExtensionType;
+import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
 import org.apache.nifi.web.api.dto.ControllerServiceDTO;
 import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.entity.ControllerServiceEntity;
 import 
org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
 import org.apache.nifi.web.api.entity.ControllerServicesEntity;
+import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
 import org.apache.nifi.web.util.Availability;
 import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.slf4j.Logger;
@@ -152,7 +155,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
      */
     @GET
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ControllerServicesEntity.class)
     public Response getControllerServices(@QueryParam(CLIENT_ID) 
@DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId, 
@PathParam("availability") String availability) {
@@ -196,7 +199,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ControllerServiceEntity.class)
     public Response createControllerService(
@@ -237,7 +240,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
     @POST
     @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ControllerServiceEntity.class)
     public Response createControllerService(
@@ -324,7 +327,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
      */
     @GET
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ControllerServiceEntity.class)
     public Response getControllerService(@QueryParam(CLIENT_ID) 
@DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId, 
@@ -353,6 +356,55 @@ public class ControllerServiceResource extends 
ApplicationResource {
     }
     
     /**
+     * Returns the descriptor for the specified property.
+     * 
+     * @param clientId Optional client id. If the client id is not specified, a
+     * new one will be generated. This value (whether specified or generated) 
is
+     * included in the response.
+     * @param availability
+     * @param id The id of the controller service.
+     * @param propertyName The property
+     * @return a propertyDescriptorEntity
+     */
+    @GET
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{availability}/{id}/descriptors")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @TypeHint(PropertyDescriptorEntity.class)
+    public Response getPropertyDescriptor(
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) 
ClientIdParameter clientId, 
+            @PathParam("availability") String availability, @PathParam("id") 
String id, 
+            @QueryParam("propertyName") String propertyName) {
+        
+        final Availability avail = parseAvailability(availability);
+        
+        // ensure the property name is specified
+        if (propertyName == null) {
+            throw new IllegalArgumentException("The property name must be 
specified.");
+        }
+        
+        // replicate if cluster manager and service is on node
+        if (properties.isClusterManager() && Availability.NODE.equals(avail)) {
+            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+        
+        // get the property descriptor
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getControllerServicePropertyDescriptor(id, propertyName);
+        
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+        
+        // generate the response entity
+        final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
+        entity.setRevision(revision);
+        entity.setPropertyDescriptor(descriptor);
+        
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+    
+    /**
      * Retrieves the references of the specified controller service.
      *
      * @param clientId Optional client id. If the client id is not specified, a
@@ -365,7 +417,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
      */
     @GET
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}/references")
+    @Path("/{availability}/{id}/references")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ControllerServiceEntity.class)
     public Response getControllerServiceReferences(
@@ -414,7 +466,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
     @PUT
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}/references")
+    @Path("/{availability}/{id}/references")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ControllerServiceEntity.class)
     public Response updateControllerServiceReferences(
@@ -529,7 +581,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
     @PUT
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ControllerServiceEntity.class)
     public Response updateControllerService(
@@ -607,7 +659,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
     @PUT
     @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ControllerServiceEntity.class)
     public Response updateControllerService(
@@ -687,7 +739,7 @@ public class ControllerServiceResource extends 
ApplicationResource {
      */
     @DELETE
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ControllerServiceEntity.class)
     public Response removeControllerService(

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index 6fa6f21..eede48b 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -73,6 +73,8 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.ui.extension.UiExtension;
 import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.UiExtensionType;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
+import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
 import org.codehaus.enunciate.jaxrs.TypeHint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -388,6 +390,51 @@ public class ProcessorResource extends ApplicationResource 
{
         // generate the response
         return clusterContext(generateOkResponse(entity)).build();
     }
+    
+    /**
+     * Returns the descriptor for the specified property.
+     * 
+     * @param clientId Optional client id. If the client id is not specified, a
+     * new one will be generated. This value (whether specified or generated) 
is
+     * included in the response.
+     * @param id The id of the processor
+     * @param propertyName The property
+     * @return a propertyDescriptorEntity
+     */
+    @GET
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{id}/descriptors")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @TypeHint(PropertyDescriptorEntity.class)
+    public Response getPropertyDescriptor(
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) 
ClientIdParameter clientId, 
+            @PathParam("id") String id, @QueryParam("propertyName") String 
propertyName) {
+        
+        // ensure the property name is specified
+        if (propertyName == null) {
+            throw new IllegalArgumentException("The property name must be 
specified.");
+        }
+        
+        // replicate if cluster manager
+        if (properties.isClusterManager()) {
+            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+        
+        // get the property descriptor
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getProcessorPropertyDescriptor(groupId, id, propertyName);
+        
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+        
+        // generate the response entity
+        final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
+        entity.setRevision(revision);
+        entity.setPropertyDescriptor(descriptor);
+        
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
 
     /**
      * Updates the specified processor with the specified values.

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
index d29f0ed..be06e7b 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ReportingTaskResource.java
@@ -55,7 +55,10 @@ import org.apache.commons.lang3.StringUtils;
 import org.apache.nifi.ui.extension.UiExtension;
 import org.apache.nifi.ui.extension.UiExtensionMapping;
 import org.apache.nifi.web.UiExtensionType;
+import static org.apache.nifi.web.api.ApplicationResource.CLIENT_ID;
+import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
 import org.apache.nifi.web.api.dto.ReportingTaskDTO;
+import org.apache.nifi.web.api.entity.PropertyDescriptorEntity;
 import org.apache.nifi.web.api.entity.ReportingTaskEntity;
 import org.apache.nifi.web.api.entity.ReportingTasksEntity;
 import org.apache.nifi.web.util.Availability;
@@ -148,7 +151,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
      */
     @GET
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ReportingTasksEntity.class)
     public Response getReportingTasks(@QueryParam(CLIENT_ID) 
@DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId, 
@PathParam("availability") String availability) {
@@ -192,7 +195,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
     @POST
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ReportingTaskEntity.class)
     public Response createReportingTask(
@@ -233,7 +236,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
     @POST
     @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}")
+    @Path("/{availability}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ReportingTaskEntity.class)
     public Response createReportingTask(
@@ -320,7 +323,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
      */
     @GET
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
     @TypeHint(ReportingTaskEntity.class)
     public Response getReportingTask(@QueryParam(CLIENT_ID) 
@DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId, 
@@ -349,6 +352,55 @@ public class ReportingTaskResource extends 
ApplicationResource {
     }
     
     /**
+     * Returns the descriptor for the specified property.
+     * 
+     * @param clientId Optional client id. If the client id is not specified, a
+     * new one will be generated. This value (whether specified or generated) 
is
+     * included in the response.
+     * @param availability
+     * @param id The id of the reporting task.
+     * @param propertyName The property
+     * @return a propertyDescriptorEntity
+     */
+    @GET
+    @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
+    @Path("/{availability}/{id}/descriptors")
+    @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
+    @TypeHint(PropertyDescriptorEntity.class)
+    public Response getPropertyDescriptor(
+            @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) 
ClientIdParameter clientId, 
+            @PathParam("availability") String availability, @PathParam("id") 
String id, 
+            @QueryParam("propertyName") String propertyName) {
+        
+        final Availability avail = parseAvailability(availability);
+        
+        // ensure the property name is specified
+        if (propertyName == null) {
+            throw new IllegalArgumentException("The property name must be 
specified.");
+        }
+        
+        // replicate if cluster manager and task is on node
+        if (properties.isClusterManager() && Availability.NODE.equals(avail)) {
+            return clusterManager.applyRequest(HttpMethod.GET, 
getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
+        }
+        
+        // get the property descriptor
+        final PropertyDescriptorDTO descriptor = 
serviceFacade.getReportingTaskPropertyDescriptor(id, propertyName);
+        
+        // create the revision
+        final RevisionDTO revision = new RevisionDTO();
+        revision.setClientId(clientId.getClientId());
+        
+        // generate the response entity
+        final PropertyDescriptorEntity entity = new PropertyDescriptorEntity();
+        entity.setRevision(revision);
+        entity.setPropertyDescriptor(descriptor);
+        
+        // generate the response
+        return clusterContext(generateOkResponse(entity)).build();
+    }
+    
+    /**
      * Updates the specified reporting task.
      *
      * @param httpServletRequest
@@ -385,7 +437,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
     @PUT
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ReportingTaskEntity.class)
     public Response updateReportingTask(
@@ -464,7 +516,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
     @PUT
     @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ReportingTaskEntity.class)
     public Response updateReportingTask(
@@ -544,7 +596,7 @@ public class ReportingTaskResource extends 
ApplicationResource {
      */
     @DELETE
     @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
-    @Path("{availability}/{id}")
+    @Path("/{availability}/{id}")
     @PreAuthorize("hasRole('ROLE_DFM')")
     @TypeHint(ReportingTaskEntity.class)
     public Response removeReportingTask(

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/e0e2d161/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --git 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 7286c83..f9bda23 100644
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@ -1899,7 +1899,7 @@ public final class DtoFactory {
      * @param propertyDescriptor
      * @return
      */
-    private PropertyDescriptorDTO createPropertyDescriptorDto(final 
PropertyDescriptor propertyDescriptor) {
+    public PropertyDescriptorDTO createPropertyDescriptorDto(final 
PropertyDescriptor propertyDescriptor) {
         if (propertyDescriptor == null) {
             return null;
         }

Reply via email to