RouterWebServices implements RMWebServiceProtocol { @VisibleForTesting protected RequestInterceptorChainWrapper getInterceptorChain( final HttpServletRequest hsr) { String user = ""; if (hsr != null) { user = hsr.getRemoteUser(); } try { if (user == null || user.equals("")) { user = UserGroupInformation.getCurrentUser().getUserName(); } } catch (IOException e) { LOG.error("Cannot get user: {}", e.getMessage()); } RequestInterceptorChainWrapper chain = userPipelineMap.get(user); if (chain != null && chain.getRootInterceptor() != null) { return chain; } return initializePipeline(user); } @Inject  RouterWebServices(final Router router, Configuration conf); @GET @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ClusterInfo get(); @GET @Path(RMWSConsts.INFO) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ClusterInfo getClusterInfo(); @GET @Path(RMWSConsts.CLUSTER_USER_INFO) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ClusterUserInfo getClusterUserInfo(@Context HttpServletRequest hsr); @GET @Path(RMWSConsts.METRICS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ClusterMetricsInfo getClusterMetricsInfo(); @GET @Path(RMWSConsts.SCHEDULER) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override SchedulerTypeInfo getSchedulerInfo(); @POST @Path(RMWSConsts.SCHEDULER_LOGS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override String dumpSchedulerLogs(@FormParam(RMWSConsts.TIME) String time,
      @Context HttpServletRequest hsr); @GET @Path(RMWSConsts.NODES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override NodesInfo getNodes(@QueryParam(RMWSConsts.STATES) String states); @GET @Path(RMWSConsts.NODES_NODEID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override NodeInfo getNode(@PathParam(RMWSConsts.NODEID) String nodeId); @GET @Path(RMWSConsts.APPS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppsInfo getApps(@Context HttpServletRequest hsr,
      @QueryParam(RMWSConsts.STATE) String stateQuery,
      @QueryParam(RMWSConsts.STATES) Set<String> statesQuery,
      @QueryParam(RMWSConsts.FINAL_STATUS) String finalStatusQuery,
      @QueryParam(RMWSConsts.USER) String userQuery,
      @QueryParam(RMWSConsts.QUEUE) String queueQuery,
      @QueryParam(RMWSConsts.LIMIT) String count,
      @QueryParam(RMWSConsts.STARTED_TIME_BEGIN) String startedBegin,
      @QueryParam(RMWSConsts.STARTED_TIME_END) String startedEnd,
      @QueryParam(RMWSConsts.FINISHED_TIME_BEGIN) String finishBegin,
      @QueryParam(RMWSConsts.FINISHED_TIME_END) String finishEnd,
      @QueryParam(RMWSConsts.APPLICATION_TYPES) Set<String> applicationTypes,
      @QueryParam(RMWSConsts.APPLICATION_TAGS) Set<String> applicationTags,
      @QueryParam(RMWSConsts.DESELECTS) Set<String> unselectedFields); @GET @Path(RMWSConsts.SCHEDULER_ACTIVITIES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ActivitiesInfo getActivities(@Context HttpServletRequest hsr,
      @QueryParam(RMWSConsts.NODEID) String nodeId); @GET @Path(RMWSConsts.SCHEDULER_APP_ACTIVITIES) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppActivitiesInfo getAppActivities(@Context HttpServletRequest hsr,
      @QueryParam(RMWSConsts.APP_ID) String appId,
      @QueryParam(RMWSConsts.MAX_TIME) String time); @GET @Path(RMWSConsts.APP_STATISTICS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override ApplicationStatisticsInfo getAppStatistics(
      @Context HttpServletRequest hsr,
      @QueryParam(RMWSConsts.STATES) Set<String> stateQueries,
      @QueryParam(RMWSConsts.APPLICATION_TYPES) Set<String> typeQueries); @GET @Path(RMWSConsts.APPS_APPID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppInfo getApp(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId,
      @QueryParam(RMWSConsts.DESELECTS) Set<String> unselectedFields); @GET @Path(RMWSConsts.APPS_APPID_STATE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppState getAppState(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @PUT @Path(RMWSConsts.APPS_APPID_STATE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response updateAppState(AppState targetState,
      @Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @GET @Path(RMWSConsts.GET_NODE_TO_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override NodeToLabelsInfo getNodeToLabels(@Context HttpServletRequest hsr); @GET @Path(RMWSConsts.LABEL_MAPPINGS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override LabelsToNodesInfo getLabelsToNodes(
      @QueryParam(RMWSConsts.LABELS) Set<String> labels); @POST @Path(RMWSConsts.REPLACE_NODE_TO_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response replaceLabelsOnNodes(
      final NodeToLabelsEntryList newNodeToLabels,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.NODES_NODEID_REPLACE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response replaceLabelsOnNode(
      @QueryParam(RMWSConsts.LABELS) Set<String> newNodeLabelsName,
      @Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.NODEID) String nodeId); @GET @Path(RMWSConsts.GET_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override NodeLabelsInfo getClusterNodeLabels(@Context HttpServletRequest hsr); @POST @Path(RMWSConsts.ADD_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response addToClusterNodeLabels(NodeLabelsInfo newNodeLabels,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.REMOVE_NODE_LABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response removeFromCluserNodeLabels(
      @QueryParam(RMWSConsts.LABELS) Set<String> oldNodeLabels,
      @Context HttpServletRequest hsr); @GET @Path(RMWSConsts.NODES_NODEID_GETLABELS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override NodeLabelsInfo getLabelsOnNode(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.NODEID) String nodeId); @GET @Path(RMWSConsts.APPS_APPID_PRIORITY) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppPriority getAppPriority(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @PUT @Path(RMWSConsts.APPS_APPID_PRIORITY) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response updateApplicationPriority(AppPriority targetPriority,
      @Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @GET @Path(RMWSConsts.APPS_APPID_QUEUE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppQueue getAppQueue(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @PUT @Path(RMWSConsts.APPS_APPID_QUEUE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response updateAppQueue(AppQueue targetQueue,
      @Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @POST @Path(RMWSConsts.APPS_NEW_APPLICATION) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response createNewApplication(@Context HttpServletRequest hsr); @POST @Path(RMWSConsts.APPS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response submitApplication(ApplicationSubmissionContextInfo newApp,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.DELEGATION_TOKEN) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response postDelegationToken(DelegationToken tokenData,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.DELEGATION_TOKEN_EXPIRATION) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response postDelegationTokenExpiration(@Context HttpServletRequest hsr); @DELETE @Path(RMWSConsts.DELEGATION_TOKEN) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response cancelDelegationToken(@Context HttpServletRequest hsr); @POST @Path(RMWSConsts.RESERVATION_NEW) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response createNewReservation(@Context HttpServletRequest hsr); @POST @Path(RMWSConsts.RESERVATION_SUBMIT) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response submitReservation(ReservationSubmissionRequestInfo resContext,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.RESERVATION_UPDATE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response updateReservation(ReservationUpdateRequestInfo resContext,
      @Context HttpServletRequest hsr); @POST @Path(RMWSConsts.RESERVATION_DELETE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response deleteReservation(ReservationDeleteRequestInfo resContext,
      @Context HttpServletRequest hsr); @GET @Path(RMWSConsts.RESERVATION_LIST) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response listReservation(
      @QueryParam(RMWSConsts.QUEUE) @DefaultValue(DEFAULT_QUEUE) String queue,
      @QueryParam(RMWSConsts.RESERVATION_ID) @DefaultValue(DEFAULT_RESERVATION_ID) String reservationId,
      @QueryParam(RMWSConsts.START_TIME) @DefaultValue(DEFAULT_START_TIME) long startTime,
      @QueryParam(RMWSConsts.END_TIME) @DefaultValue(DEFAULT_END_TIME) long endTime,
      @QueryParam(RMWSConsts.INCLUDE_RESOURCE) @DefaultValue(DEFAULT_INCLUDE_RESOURCE) boolean includeResourceAllocations,
      @Context HttpServletRequest hsr); @GET @Path(RMWSConsts.APPS_TIMEOUTS_TYPE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppTimeoutInfo getAppTimeout(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId,
      @PathParam(RMWSConsts.TYPE) String type); @GET @Path(RMWSConsts.APPS_TIMEOUTS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppTimeoutsInfo getAppTimeouts(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @PUT @Path(RMWSConsts.APPS_TIMEOUT) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override Response updateApplicationTimeout(AppTimeoutInfo appTimeout,
      @Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @GET @Path(RMWSConsts.APPS_APPID_APPATTEMPTS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override AppAttemptsInfo getAppAttempts(@Context HttpServletRequest hsr,
      @PathParam(RMWSConsts.APPID) String appId); @GET @Path(RMWSConsts.CHECK_USER_ACCESS_TO_QUEUE) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) @Override RMQueueAclInfo checkUserAccessToQueue(
      @PathParam(RMWSConsts.QUEUE) String queue,
      @QueryParam(RMWSConsts.USER) String username,
      @QueryParam(RMWSConsts.QUEUE_ACL_TYPE)
      @DefaultValue("SUBMIT_APPLICATIONS") String queueAclType,
      @Context HttpServletRequest hsr); @GET @Path(RMWSConsts.APPS_APPID_APPATTEMPTS_APPATTEMPTID) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) org.apache.hadoop.yarn.server.webapp.dao.AppAttemptInfo getAppAttempt(
      @Context HttpServletRequest req, @Context HttpServletResponse res,
      @PathParam(RMWSConsts.APPID) String appId,
      @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId); @GET @Path(RMWSConsts.APPS_APPID_APPATTEMPTS_APPATTEMPTID_CONTAINERS) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) ContainersInfo getContainers(@Context HttpServletRequest req,
      @Context HttpServletResponse res,
      @PathParam(RMWSConsts.APPID) String appId,
      @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId); @GET @Path(RMWSConsts.GET_CONTAINER) @Produces({ MediaType.APPLICATION_JSON + "; " + JettyUtils.UTF_8, MediaType.APPLICATION_XML + "; " + JettyUtils.UTF_8 }) ContainerInfo getContainer(@Context HttpServletRequest req,
      @Context HttpServletResponse res,
      @PathParam(RMWSConsts.APPID) String appId,
      @PathParam(RMWSConsts.APPATTEMPTID) String appAttemptId,
      @PathParam(RMWSConsts.CONTAINERID) String containerId); static final String DEFAULT_QUEUE; static final String DEFAULT_RESERVATION_ID; static final String DEFAULT_START_TIME; static final String DEFAULT_END_TIME; static final String DEFAULT_INCLUDE_RESOURCE; }
@Test public void testWebPipelineConcurrent() throws InterruptedException { final String user = "test1"; class ClientTestThread extends Thread { private RESTRequestInterceptor interceptor; @Override public void run() { try { interceptor = pipeline(); } catch (IOException | InterruptedException e) { e.printStackTrace(); } } private RESTRequestInterceptor pipeline() throws IOException, InterruptedException { return UserGroupInformation.createRemoteUser(user).doAs( new PrivilegedExceptionAction<RESTRequestInterceptor>() { @Override public RESTRequestInterceptor run() throws Exception { RequestInterceptorChainWrapper wrapper = getInterceptorChain(user); RESTRequestInterceptor interceptor = wrapper.getRootInterceptor(); Assert.assertNotNull(interceptor); LOG.info("init web interceptor success for user" + user); return interceptor; } }); } } ClientTestThread client1 = new ClientTestThread(); ClientTestThread client2 = new ClientTestThread(); client1.start(); client2.start(); client1.join(); client2.join(); Assert.assertNotNull(client1.interceptor); Assert.assertNotNull(client2.interceptor); Assert.assertTrue(client1.interceptor == client2.interceptor); }