YARN-6777. Support for ApplicationMasterService processing chain of interceptors. (asuresh)
This commit is contained in:
parent
3556e36be3
commit
077fcf6a96
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.ams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a marker interface for a context object that is injected into
|
||||||
|
* the ApplicationMasterService processor. The processor implementation
|
||||||
|
* is free to type cast this based on the availability of the context's
|
||||||
|
* implementation in the classpath.
|
||||||
|
*/
|
||||||
|
public interface ApplicationMasterServiceContext {
|
||||||
|
|
||||||
|
}
|
|
@ -37,35 +37,45 @@ import java.io.IOException;
|
||||||
*/
|
*/
|
||||||
public interface ApplicationMasterServiceProcessor {
|
public interface ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize with and ApplicationMasterService Context as well as the
|
||||||
|
* next processor in the chain.
|
||||||
|
* @param amsContext AMSContext.
|
||||||
|
* @param nextProcessor next ApplicationMasterServiceProcessor
|
||||||
|
*/
|
||||||
|
void init(ApplicationMasterServiceContext amsContext,
|
||||||
|
ApplicationMasterServiceProcessor nextProcessor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register AM attempt.
|
* Register AM attempt.
|
||||||
* @param applicationAttemptId applicationAttemptId.
|
* @param applicationAttemptId applicationAttemptId.
|
||||||
* @param request Register Request.
|
* @param request Register Request.
|
||||||
* @return Register Response.
|
* @param response Register Response.
|
||||||
* @throws IOException IOException.
|
* @throws IOException IOException.
|
||||||
*/
|
*/
|
||||||
RegisterApplicationMasterResponse registerApplicationMaster(
|
void registerApplicationMaster(
|
||||||
ApplicationAttemptId applicationAttemptId,
|
ApplicationAttemptId applicationAttemptId,
|
||||||
RegisterApplicationMasterRequest request) throws IOException;
|
RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse response) throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate call.
|
* Allocate call.
|
||||||
* @param appAttemptId appAttemptId.
|
* @param appAttemptId appAttemptId.
|
||||||
* @param request Allocate Request.
|
* @param request Allocate Request.
|
||||||
* @return Allocate Response.
|
* @param response Allocate Response.
|
||||||
* @throws YarnException YarnException.
|
* @throws YarnException YarnException.
|
||||||
*/
|
*/
|
||||||
AllocateResponse allocate(ApplicationAttemptId appAttemptId,
|
void allocate(ApplicationAttemptId appAttemptId,
|
||||||
AllocateRequest request) throws YarnException;
|
AllocateRequest request, AllocateResponse response) throws YarnException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finish AM.
|
* Finish AM.
|
||||||
* @param applicationAttemptId applicationAttemptId.
|
* @param applicationAttemptId applicationAttemptId.
|
||||||
* @param request Finish AM Request.
|
* @param request Finish AM Request.
|
||||||
* @return Finish AM response.
|
* @param response Finish AM Response.
|
||||||
*/
|
*/
|
||||||
FinishApplicationMasterResponse finishApplicationMaster(
|
void finishApplicationMaster(
|
||||||
ApplicationAttemptId applicationAttemptId,
|
ApplicationAttemptId applicationAttemptId,
|
||||||
FinishApplicationMasterRequest request);
|
FinishApplicationMasterRequest request,
|
||||||
|
FinishApplicationMasterResponse response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,9 @@ public class YarnConfiguration extends Configuration {
|
||||||
public static final String DEFAULT_RM_ADDRESS =
|
public static final String DEFAULT_RM_ADDRESS =
|
||||||
"0.0.0.0:" + DEFAULT_RM_PORT;
|
"0.0.0.0:" + DEFAULT_RM_PORT;
|
||||||
|
|
||||||
|
public static final String RM_APPLICATION_MASTER_SERVICE_PROCESSORS =
|
||||||
|
RM_PREFIX + "application-master-service.processors";
|
||||||
|
|
||||||
/** The actual bind address for the RM.*/
|
/** The actual bind address for the RM.*/
|
||||||
public static final String RM_BIND_HOST =
|
public static final String RM_BIND_HOST =
|
||||||
RM_PREFIX + "bind-host";
|
RM_PREFIX + "bind-host";
|
||||||
|
|
|
@ -122,6 +122,16 @@
|
||||||
<value>50</value>
|
<value>50</value>
|
||||||
</property>
|
</property>
|
||||||
|
|
||||||
|
<property>
|
||||||
|
<description>
|
||||||
|
Comma separated class names of ApplicationMasterServiceProcessor
|
||||||
|
implementations. The processors will be applied in the order
|
||||||
|
they are specified.
|
||||||
|
</description>
|
||||||
|
<name>yarn.resourcemanager.application-master-service.processors</name>
|
||||||
|
<value></value>
|
||||||
|
</property>
|
||||||
|
|
||||||
<property>
|
<property>
|
||||||
<description>
|
<description>
|
||||||
This configures the HTTP endpoint for Yarn Daemons.The following
|
This configures the HTTP endpoint for Yarn Daemons.The following
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.yarn.server.resourcemanager;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceContext;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
||||||
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
|
import org.apache.hadoop.yarn.exceptions.YarnRuntimeException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This maintains a chain of {@link ApplicationMasterServiceProcessor}s.
|
||||||
|
*/
|
||||||
|
class AMSProcessingChain implements ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
|
private static final Log LOG = LogFactory.getLog(AMSProcessingChain.class);
|
||||||
|
|
||||||
|
private ApplicationMasterServiceProcessor head;
|
||||||
|
private RMContext rmContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This has to be initialized with at-least 1 Processor.
|
||||||
|
* @param rootProcessor Root processor.
|
||||||
|
*/
|
||||||
|
AMSProcessingChain(ApplicationMasterServiceProcessor rootProcessor) {
|
||||||
|
if (rootProcessor == null) {
|
||||||
|
throw new YarnRuntimeException("No root ApplicationMasterService" +
|
||||||
|
"Processor specified for the processing chain..");
|
||||||
|
}
|
||||||
|
this.head = rootProcessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ApplicationMasterServiceContext amsContext,
|
||||||
|
ApplicationMasterServiceProcessor nextProcessor) {
|
||||||
|
LOG.info("Initializing AMS Processing chain. Root Processor=["
|
||||||
|
+ this.head.getClass().getName() + "].");
|
||||||
|
this.rmContext = (RMContext)amsContext;
|
||||||
|
// The head is initialized with a null 'next' processor
|
||||||
|
this.head.init(amsContext, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an processor to the top of the chain.
|
||||||
|
* @param processor ApplicationMasterServiceProcessor
|
||||||
|
*/
|
||||||
|
public synchronized void addProcessor(
|
||||||
|
ApplicationMasterServiceProcessor processor) {
|
||||||
|
LOG.info("Adding [" + processor.getClass().getName() + "] tp top of" +
|
||||||
|
" AMS Processing chain. ");
|
||||||
|
processor.init(this.rmContext, this.head);
|
||||||
|
this.head = processor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerApplicationMaster(
|
||||||
|
ApplicationAttemptId applicationAttemptId,
|
||||||
|
RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse resp) throws IOException {
|
||||||
|
this.head.registerApplicationMaster(applicationAttemptId, request, resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allocate(ApplicationAttemptId appAttemptId,
|
||||||
|
AllocateRequest request, AllocateResponse response) throws YarnException {
|
||||||
|
this.head.allocate(appAttemptId, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishApplicationMaster(
|
||||||
|
ApplicationAttemptId applicationAttemptId,
|
||||||
|
FinishApplicationMasterRequest request,
|
||||||
|
FinishApplicationMasterResponse response) {
|
||||||
|
this.head.finishApplicationMaster(applicationAttemptId, request, response);
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
@ -88,7 +89,7 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
private final ConcurrentMap<ApplicationAttemptId, AllocateResponseLock> responseMap =
|
private final ConcurrentMap<ApplicationAttemptId, AllocateResponseLock> responseMap =
|
||||||
new ConcurrentHashMap<ApplicationAttemptId, AllocateResponseLock>();
|
new ConcurrentHashMap<ApplicationAttemptId, AllocateResponseLock>();
|
||||||
protected final RMContext rmContext;
|
protected final RMContext rmContext;
|
||||||
private final ApplicationMasterServiceProcessor amsProcessor;
|
private final AMSProcessingChain amsProcessingChain;
|
||||||
|
|
||||||
public ApplicationMasterService(RMContext rmContext,
|
public ApplicationMasterService(RMContext rmContext,
|
||||||
YarnScheduler scheduler) {
|
YarnScheduler scheduler) {
|
||||||
|
@ -101,11 +102,7 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
this.amLivelinessMonitor = rmContext.getAMLivelinessMonitor();
|
this.amLivelinessMonitor = rmContext.getAMLivelinessMonitor();
|
||||||
this.rScheduler = scheduler;
|
this.rScheduler = scheduler;
|
||||||
this.rmContext = rmContext;
|
this.rmContext = rmContext;
|
||||||
this.amsProcessor = createProcessor();
|
this.amsProcessingChain = new AMSProcessingChain(new DefaultAMSProcessor());
|
||||||
}
|
|
||||||
|
|
||||||
protected ApplicationMasterServiceProcessor createProcessor() {
|
|
||||||
return new DefaultAMSProcessor(rmContext, rScheduler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,6 +112,21 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
YarnConfiguration.RM_SCHEDULER_ADDRESS,
|
YarnConfiguration.RM_SCHEDULER_ADDRESS,
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_ADDRESS,
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_ADDRESS,
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT);
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_PORT);
|
||||||
|
amsProcessingChain.init(rmContext, null);
|
||||||
|
List<ApplicationMasterServiceProcessor> processors = getProcessorList(conf);
|
||||||
|
if (processors != null) {
|
||||||
|
Collections.reverse(processors);
|
||||||
|
for (ApplicationMasterServiceProcessor p : processors) {
|
||||||
|
this.amsProcessingChain.addProcessor(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<ApplicationMasterServiceProcessor> getProcessorList(
|
||||||
|
Configuration conf) {
|
||||||
|
return conf.getInstances(
|
||||||
|
YarnConfiguration.RM_APPLICATION_MASTER_SERVICE_PROCESSORS,
|
||||||
|
ApplicationMasterServiceProcessor.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -165,6 +177,10 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
YarnConfiguration.DEFAULT_RM_SCHEDULER_CLIENT_THREAD_COUNT));
|
YarnConfiguration.DEFAULT_RM_SCHEDULER_CLIENT_THREAD_COUNT));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected AMSProcessingChain getProcessingChain() {
|
||||||
|
return this.amsProcessingChain;
|
||||||
|
}
|
||||||
|
|
||||||
@Private
|
@Private
|
||||||
public InetSocketAddress getBindAddress() {
|
public InetSocketAddress getBindAddress() {
|
||||||
return this.masterServiceAddress;
|
return this.masterServiceAddress;
|
||||||
|
@ -214,8 +230,12 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
lastResponse.setResponseId(0);
|
lastResponse.setResponseId(0);
|
||||||
lock.setAllocateResponse(lastResponse);
|
lock.setAllocateResponse(lastResponse);
|
||||||
|
|
||||||
return this.amsProcessor.registerApplicationMaster(
|
RegisterApplicationMasterResponse response =
|
||||||
amrmTokenIdentifier.getApplicationAttemptId(), request);
|
recordFactory.newRecordInstance(
|
||||||
|
RegisterApplicationMasterResponse.class);
|
||||||
|
this.amsProcessingChain.registerApplicationMaster(
|
||||||
|
amrmTokenIdentifier.getApplicationAttemptId(), request, response);
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,8 +285,11 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
}
|
}
|
||||||
|
|
||||||
this.amLivelinessMonitor.receivedPing(applicationAttemptId);
|
this.amLivelinessMonitor.receivedPing(applicationAttemptId);
|
||||||
return this.amsProcessor.finishApplicationMaster(
|
FinishApplicationMasterResponse response =
|
||||||
applicationAttemptId, request);
|
FinishApplicationMasterResponse.newInstance(false);
|
||||||
|
this.amsProcessingChain.finishApplicationMaster(
|
||||||
|
applicationAttemptId, request, response);
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,8 +369,10 @@ public class ApplicationMasterService extends AbstractService implements
|
||||||
throw new InvalidApplicationMasterRequestException(message);
|
throw new InvalidApplicationMasterRequestException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
AllocateResponse response = this.amsProcessor.allocate(
|
AllocateResponse response =
|
||||||
amrmTokenIdentifier.getApplicationAttemptId(), request);
|
recordFactory.newRecordInstance(AllocateResponse.class);
|
||||||
|
this.amsProcessingChain.allocate(
|
||||||
|
amrmTokenIdentifier.getApplicationAttemptId(), request, response);
|
||||||
|
|
||||||
// update AMRMToken if the token is rolled-up
|
// update AMRMToken if the token is rolled-up
|
||||||
MasterKeyData nextMasterKey =
|
MasterKeyData nextMasterKey =
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.apache.hadoop.yarn.server.resourcemanager;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceContext;
|
||||||
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceUtils;
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceUtils;
|
||||||
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
|
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
|
||||||
|
@ -81,7 +82,11 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
/**
|
||||||
|
* This is the default Application Master Service processor. It has be the
|
||||||
|
* last processor in the @{@link AMSProcessingChain}.
|
||||||
|
*/
|
||||||
|
final class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(DefaultAMSProcessor.class);
|
private static final Log LOG = LogFactory.getLog(DefaultAMSProcessor.class);
|
||||||
|
|
||||||
|
@ -93,17 +98,19 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
private final RecordFactory recordFactory =
|
private final RecordFactory recordFactory =
|
||||||
RecordFactoryProvider.getRecordFactory(null);
|
RecordFactoryProvider.getRecordFactory(null);
|
||||||
|
|
||||||
private final RMContext rmContext;
|
private RMContext rmContext;
|
||||||
private final YarnScheduler scheduler;
|
|
||||||
|
|
||||||
DefaultAMSProcessor(RMContext rmContext, YarnScheduler scheduler) {
|
@Override
|
||||||
this.rmContext = rmContext;
|
public void init(ApplicationMasterServiceContext amsContext,
|
||||||
this.scheduler = scheduler;
|
ApplicationMasterServiceProcessor nextProcessor) {
|
||||||
|
this.rmContext = (RMContext)amsContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegisterApplicationMasterResponse registerApplicationMaster(
|
@Override
|
||||||
|
public void registerApplicationMaster(
|
||||||
ApplicationAttemptId applicationAttemptId,
|
ApplicationAttemptId applicationAttemptId,
|
||||||
RegisterApplicationMasterRequest request) throws IOException {
|
RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse response) throws IOException {
|
||||||
|
|
||||||
RMApp app = getRmContext().getRMApps().get(
|
RMApp app = getRmContext().getRMApps().get(
|
||||||
applicationAttemptId.getApplicationId());
|
applicationAttemptId.getApplicationId());
|
||||||
|
@ -116,8 +123,6 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
RMAuditLogger.AuditConstants.REGISTER_AM,
|
RMAuditLogger.AuditConstants.REGISTER_AM,
|
||||||
"ApplicationMasterService", app.getApplicationId(),
|
"ApplicationMasterService", app.getApplicationId(),
|
||||||
applicationAttemptId);
|
applicationAttemptId);
|
||||||
RegisterApplicationMasterResponse response = recordFactory
|
|
||||||
.newRecordInstance(RegisterApplicationMasterResponse.class);
|
|
||||||
response.setMaximumResourceCapability(getScheduler()
|
response.setMaximumResourceCapability(getScheduler()
|
||||||
.getMaximumResourceCapability(app.getQueue()));
|
.getMaximumResourceCapability(app.getQueue()));
|
||||||
response.setApplicationACLs(app.getRMAppAttempt(applicationAttemptId)
|
response.setApplicationACLs(app.getRMAppAttempt(applicationAttemptId)
|
||||||
|
@ -165,11 +170,11 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
response.setSchedulerResourceTypes(getScheduler()
|
response.setSchedulerResourceTypes(getScheduler()
|
||||||
.getSchedulingResourceTypes());
|
.getSchedulingResourceTypes());
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AllocateResponse allocate(ApplicationAttemptId appAttemptId,
|
@Override
|
||||||
AllocateRequest request) throws YarnException {
|
public void allocate(ApplicationAttemptId appAttemptId,
|
||||||
|
AllocateRequest request, AllocateResponse response) throws YarnException {
|
||||||
|
|
||||||
handleProgress(appAttemptId, request);
|
handleProgress(appAttemptId, request);
|
||||||
|
|
||||||
|
@ -259,50 +264,46 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
"blacklistRemovals: " + blacklistRemovals);
|
"blacklistRemovals: " + blacklistRemovals);
|
||||||
}
|
}
|
||||||
RMAppAttempt appAttempt = app.getRMAppAttempt(appAttemptId);
|
RMAppAttempt appAttempt = app.getRMAppAttempt(appAttemptId);
|
||||||
AllocateResponse allocateResponse =
|
|
||||||
recordFactory.newRecordInstance(AllocateResponse.class);
|
|
||||||
|
|
||||||
if (allocation.getNMTokens() != null &&
|
if (allocation.getNMTokens() != null &&
|
||||||
!allocation.getNMTokens().isEmpty()) {
|
!allocation.getNMTokens().isEmpty()) {
|
||||||
allocateResponse.setNMTokens(allocation.getNMTokens());
|
response.setNMTokens(allocation.getNMTokens());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify the AM of container update errors
|
// Notify the AM of container update errors
|
||||||
ApplicationMasterServiceUtils.addToUpdateContainerErrors(
|
ApplicationMasterServiceUtils.addToUpdateContainerErrors(
|
||||||
allocateResponse, updateErrors);
|
response, updateErrors);
|
||||||
|
|
||||||
// update the response with the deltas of node status changes
|
// update the response with the deltas of node status changes
|
||||||
handleNodeUpdates(app, allocateResponse);
|
handleNodeUpdates(app, response);
|
||||||
|
|
||||||
ApplicationMasterServiceUtils.addToAllocatedContainers(
|
ApplicationMasterServiceUtils.addToAllocatedContainers(
|
||||||
allocateResponse, allocation.getContainers());
|
response, allocation.getContainers());
|
||||||
|
|
||||||
allocateResponse.setCompletedContainersStatuses(appAttempt
|
response.setCompletedContainersStatuses(appAttempt
|
||||||
.pullJustFinishedContainers());
|
.pullJustFinishedContainers());
|
||||||
allocateResponse.setAvailableResources(allocation.getResourceLimit());
|
response.setAvailableResources(allocation.getResourceLimit());
|
||||||
|
|
||||||
addToContainerUpdates(allocateResponse, allocation,
|
addToContainerUpdates(response, allocation,
|
||||||
((AbstractYarnScheduler)getScheduler())
|
((AbstractYarnScheduler)getScheduler())
|
||||||
.getApplicationAttempt(appAttemptId).pullUpdateContainerErrors());
|
.getApplicationAttempt(appAttemptId).pullUpdateContainerErrors());
|
||||||
|
|
||||||
allocateResponse.setNumClusterNodes(getScheduler().getNumClusterNodes());
|
response.setNumClusterNodes(getScheduler().getNumClusterNodes());
|
||||||
|
|
||||||
// add collector address for this application
|
// add collector address for this application
|
||||||
if (YarnConfiguration.timelineServiceV2Enabled(
|
if (YarnConfiguration.timelineServiceV2Enabled(
|
||||||
getRmContext().getYarnConfiguration())) {
|
getRmContext().getYarnConfiguration())) {
|
||||||
allocateResponse.setCollectorAddr(
|
response.setCollectorAddr(
|
||||||
getRmContext().getRMApps().get(appAttemptId.getApplicationId())
|
getRmContext().getRMApps().get(appAttemptId.getApplicationId())
|
||||||
.getCollectorAddr());
|
.getCollectorAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add preemption to the allocateResponse message (if any)
|
// add preemption to the allocateResponse message (if any)
|
||||||
allocateResponse
|
response.setPreemptionMessage(generatePreemptionMessage(allocation));
|
||||||
.setPreemptionMessage(generatePreemptionMessage(allocation));
|
|
||||||
|
|
||||||
// Set application priority
|
// Set application priority
|
||||||
allocateResponse.setApplicationPriority(app
|
response.setApplicationPriority(app
|
||||||
.getApplicationPriority());
|
.getApplicationPriority());
|
||||||
return allocateResponse;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleNodeUpdates(RMApp app, AllocateResponse allocateResponse) {
|
private void handleNodeUpdates(RMApp app, AllocateResponse allocateResponse) {
|
||||||
|
@ -351,20 +352,20 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
.getProgress()));
|
.getProgress()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public FinishApplicationMasterResponse finishApplicationMaster(
|
@Override
|
||||||
|
public void finishApplicationMaster(
|
||||||
ApplicationAttemptId applicationAttemptId,
|
ApplicationAttemptId applicationAttemptId,
|
||||||
FinishApplicationMasterRequest request) {
|
FinishApplicationMasterRequest request,
|
||||||
|
FinishApplicationMasterResponse response) {
|
||||||
RMApp app =
|
RMApp app =
|
||||||
getRmContext().getRMApps().get(applicationAttemptId.getApplicationId());
|
getRmContext().getRMApps().get(applicationAttemptId.getApplicationId());
|
||||||
// For UnmanagedAMs, return true so they don't retry
|
// For UnmanagedAMs, return true so they don't retry
|
||||||
FinishApplicationMasterResponse response =
|
response.setIsUnregistered(
|
||||||
FinishApplicationMasterResponse.newInstance(
|
|
||||||
app.getApplicationSubmissionContext().getUnmanagedAM());
|
app.getApplicationSubmissionContext().getUnmanagedAM());
|
||||||
getRmContext().getDispatcher().getEventHandler().handle(
|
getRmContext().getDispatcher().getEventHandler().handle(
|
||||||
new RMAppAttemptUnregistrationEvent(applicationAttemptId, request
|
new RMAppAttemptUnregistrationEvent(applicationAttemptId, request
|
||||||
.getTrackingUrl(), request.getFinalApplicationStatus(), request
|
.getTrackingUrl(), request.getFinalApplicationStatus(), request
|
||||||
.getDiagnostics()));
|
.getDiagnostics()));
|
||||||
return response;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreemptionMessage generatePreemptionMessage(Allocation allocation){
|
private PreemptionMessage generatePreemptionMessage(Allocation allocation){
|
||||||
|
@ -424,7 +425,7 @@ class DefaultAMSProcessor implements ApplicationMasterServiceProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected YarnScheduler getScheduler() {
|
protected YarnScheduler getScheduler() {
|
||||||
return scheduler;
|
return rmContext.getScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void addToContainerUpdates(AllocateResponse allocateResponse,
|
private static void addToContainerUpdates(AllocateResponse allocateResponse,
|
||||||
|
|
|
@ -23,9 +23,13 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.ipc.RPC;
|
import org.apache.hadoop.ipc.RPC;
|
||||||
import org.apache.hadoop.ipc.Server;
|
import org.apache.hadoop.ipc.Server;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceContext;
|
||||||
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
||||||
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceUtils;
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceUtils;
|
||||||
import org.apache.hadoop.yarn.api.ApplicationMasterProtocolPB;
|
import org.apache.hadoop.yarn.api.ApplicationMasterProtocolPB;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords
|
||||||
|
.FinishApplicationMasterRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
||||||
import org.apache.hadoop.yarn.api.records.Container;
|
import org.apache.hadoop.yarn.api.records.Container;
|
||||||
import org.apache.hadoop.yarn.api.records.NodeId;
|
import org.apache.hadoop.yarn.api.records.NodeId;
|
||||||
|
@ -101,17 +105,29 @@ public class OpportunisticContainerAllocatorAMService
|
||||||
private volatile List<RemoteNode> cachedNodes;
|
private volatile List<RemoteNode> cachedNodes;
|
||||||
private volatile long lastCacheUpdateTime;
|
private volatile long lastCacheUpdateTime;
|
||||||
|
|
||||||
class OpportunisticAMSProcessor extends DefaultAMSProcessor {
|
class OpportunisticAMSProcessor implements
|
||||||
|
ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
OpportunisticAMSProcessor(RMContext rmContext, YarnScheduler
|
private ApplicationMasterServiceContext context;
|
||||||
scheduler) {
|
private ApplicationMasterServiceProcessor nextProcessor;
|
||||||
super(rmContext, scheduler);
|
|
||||||
|
private YarnScheduler getScheduler() {
|
||||||
|
return ((RMContext)context).getScheduler();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegisterApplicationMasterResponse registerApplicationMaster(
|
public void init(ApplicationMasterServiceContext amsContext,
|
||||||
|
ApplicationMasterServiceProcessor next) {
|
||||||
|
this.context = amsContext;
|
||||||
|
// The AMSProcessingChain guarantees that 'next' is not null.
|
||||||
|
this.nextProcessor = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerApplicationMaster(
|
||||||
ApplicationAttemptId applicationAttemptId,
|
ApplicationAttemptId applicationAttemptId,
|
||||||
RegisterApplicationMasterRequest request) throws IOException {
|
RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse response) throws IOException {
|
||||||
SchedulerApplicationAttempt appAttempt = ((AbstractYarnScheduler)
|
SchedulerApplicationAttempt appAttempt = ((AbstractYarnScheduler)
|
||||||
getScheduler()).getApplicationAttempt(applicationAttemptId);
|
getScheduler()).getApplicationAttempt(applicationAttemptId);
|
||||||
if (appAttempt.getOpportunisticContainerContext() == null) {
|
if (appAttempt.getOpportunisticContainerContext() == null) {
|
||||||
|
@ -135,12 +151,14 @@ public class OpportunisticContainerAllocatorAMService
|
||||||
tokenExpiryInterval);
|
tokenExpiryInterval);
|
||||||
appAttempt.setOpportunisticContainerContext(opCtx);
|
appAttempt.setOpportunisticContainerContext(opCtx);
|
||||||
}
|
}
|
||||||
return super.registerApplicationMaster(applicationAttemptId, request);
|
nextProcessor.registerApplicationMaster(
|
||||||
|
applicationAttemptId, request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AllocateResponse allocate(ApplicationAttemptId appAttemptId,
|
public void allocate(ApplicationAttemptId appAttemptId,
|
||||||
AllocateRequest request) throws YarnException {
|
AllocateRequest request, AllocateResponse response)
|
||||||
|
throws YarnException {
|
||||||
// Partition requests to GUARANTEED and OPPORTUNISTIC.
|
// Partition requests to GUARANTEED and OPPORTUNISTIC.
|
||||||
OpportunisticContainerAllocator.PartitionedResourceRequests
|
OpportunisticContainerAllocator.PartitionedResourceRequests
|
||||||
partitionedAsks =
|
partitionedAsks =
|
||||||
|
@ -165,17 +183,22 @@ public class OpportunisticContainerAllocatorAMService
|
||||||
if (!oppContainers.isEmpty()) {
|
if (!oppContainers.isEmpty()) {
|
||||||
handleNewContainers(oppContainers, false);
|
handleNewContainers(oppContainers, false);
|
||||||
appAttempt.updateNMTokens(oppContainers);
|
appAttempt.updateNMTokens(oppContainers);
|
||||||
|
ApplicationMasterServiceUtils.addToAllocatedContainers(
|
||||||
|
response, oppContainers);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate GUARANTEED containers.
|
// Allocate GUARANTEED containers.
|
||||||
request.setAskList(partitionedAsks.getGuaranteed());
|
request.setAskList(partitionedAsks.getGuaranteed());
|
||||||
|
nextProcessor.allocate(appAttemptId, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
AllocateResponse response = super.allocate(appAttemptId, request);
|
@Override
|
||||||
if (!oppContainers.isEmpty()) {
|
public void finishApplicationMaster(
|
||||||
ApplicationMasterServiceUtils.addToAllocatedContainers(
|
ApplicationAttemptId applicationAttemptId,
|
||||||
response, oppContainers);
|
FinishApplicationMasterRequest request,
|
||||||
}
|
FinishApplicationMasterResponse response) {
|
||||||
return response;
|
nextProcessor.finishApplicationMaster(applicationAttemptId,
|
||||||
|
request, response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +259,6 @@ public class OpportunisticContainerAllocatorAMService
|
||||||
this.nodeMonitor = topKSelector;
|
this.nodeMonitor = topKSelector;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ApplicationMasterServiceProcessor createProcessor() {
|
|
||||||
return new OpportunisticAMSProcessor(rmContext, rmContext.getScheduler());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Server getServer(YarnRPC rpc, Configuration serverConf,
|
public Server getServer(YarnRPC rpc, Configuration serverConf,
|
||||||
InetSocketAddress addr, AMRMTokenSecretManager secretManager) {
|
InetSocketAddress addr, AMRMTokenSecretManager secretManager) {
|
||||||
|
@ -261,6 +279,15 @@ public class OpportunisticContainerAllocatorAMService
|
||||||
return super.getServer(rpc, serverConf, addr, secretManager);
|
return super.getServer(rpc, serverConf, addr, secretManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ApplicationMasterServiceProcessor> getProcessorList(
|
||||||
|
Configuration conf) {
|
||||||
|
List<ApplicationMasterServiceProcessor> retVal =
|
||||||
|
super.getProcessorList(conf);
|
||||||
|
retVal.add(new OpportunisticAMSProcessor());
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RegisterDistributedSchedulingAMResponse
|
public RegisterDistributedSchedulingAMResponse
|
||||||
registerApplicationMasterForDistributedScheduling(
|
registerApplicationMasterForDistributedScheduling(
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
import org.apache.hadoop.conf.Configuration;
|
import org.apache.hadoop.conf.Configuration;
|
||||||
import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
|
import org.apache.hadoop.ha.HAServiceProtocol.HAServiceState;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceContext;
|
||||||
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
import org.apache.hadoop.yarn.api.records.ApplicationId;
|
||||||
import org.apache.hadoop.yarn.api.records.NodeId;
|
import org.apache.hadoop.yarn.api.records.NodeId;
|
||||||
import org.apache.hadoop.yarn.conf.ConfigurationProvider;
|
import org.apache.hadoop.yarn.conf.ConfigurationProvider;
|
||||||
|
@ -53,7 +54,7 @@ import org.apache.hadoop.yarn.server.resourcemanager.timelineservice.RMTimelineC
|
||||||
/**
|
/**
|
||||||
* Context of the ResourceManager.
|
* Context of the ResourceManager.
|
||||||
*/
|
*/
|
||||||
public interface RMContext {
|
public interface RMContext extends ApplicationMasterServiceContext {
|
||||||
|
|
||||||
Dispatcher getDispatcher();
|
Dispatcher getDispatcher();
|
||||||
|
|
||||||
|
|
|
@ -20,20 +20,29 @@ package org.apache.hadoop.yarn.server.resourcemanager;
|
||||||
|
|
||||||
import static java.lang.Thread.sleep;
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.apache.hadoop.security.UserGroupInformation;
|
import org.apache.hadoop.security.UserGroupInformation;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceContext;
|
||||||
|
import org.apache.hadoop.yarn.ams.ApplicationMasterServiceProcessor;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.AllocateRequest;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
|
import org.apache.hadoop.yarn.api.protocolrecords.AllocateResponse;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest;
|
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterRequest;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords.FinishApplicationMasterResponse;
|
||||||
|
import org.apache.hadoop.yarn.api.protocolrecords
|
||||||
|
.RegisterApplicationMasterRequest;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
|
import org.apache.hadoop.yarn.api.protocolrecords.RegisterApplicationMasterResponse;
|
||||||
import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.AllocateRequestPBImpl;
|
import org.apache.hadoop.yarn.api.protocolrecords.impl.pb.AllocateRequestPBImpl;
|
||||||
|
import org.apache.hadoop.yarn.api.records.ApplicationAttemptId;
|
||||||
import org.apache.hadoop.yarn.api.records.Container;
|
import org.apache.hadoop.yarn.api.records.Container;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerId;
|
import org.apache.hadoop.yarn.api.records.ContainerId;
|
||||||
import org.apache.hadoop.yarn.api.records.ContainerUpdateType;
|
import org.apache.hadoop.yarn.api.records.ContainerUpdateType;
|
||||||
|
@ -44,6 +53,7 @@ import org.apache.hadoop.yarn.api.records.UpdateContainerRequest;
|
||||||
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
import org.apache.hadoop.yarn.conf.YarnConfiguration;
|
||||||
import org.apache.hadoop.yarn.exceptions.ApplicationMasterNotRegisteredException;
|
import org.apache.hadoop.yarn.exceptions.ApplicationMasterNotRegisteredException;
|
||||||
import org.apache.hadoop.yarn.exceptions.InvalidContainerReleaseException;
|
import org.apache.hadoop.yarn.exceptions.InvalidContainerReleaseException;
|
||||||
|
import org.apache.hadoop.yarn.exceptions.YarnException;
|
||||||
import org.apache.hadoop.yarn.proto.YarnServiceProtos.SchedulerResourceTypes;
|
import org.apache.hadoop.yarn.proto.YarnServiceProtos.SchedulerResourceTypes;
|
||||||
import org.apache.hadoop.yarn.security.ContainerTokenIdentifier;
|
import org.apache.hadoop.yarn.security.ContainerTokenIdentifier;
|
||||||
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMApp;
|
||||||
|
@ -61,7 +71,7 @@ import org.apache.hadoop.yarn.server.utils.BuilderUtils;
|
||||||
import org.apache.hadoop.yarn.util.resource.DominantResourceCalculator;
|
import org.apache.hadoop.yarn.util.resource.DominantResourceCalculator;
|
||||||
import org.apache.hadoop.yarn.util.resource.Resources;
|
import org.apache.hadoop.yarn.util.resource.Resources;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
public class TestApplicationMasterService {
|
public class TestApplicationMasterService {
|
||||||
|
@ -71,13 +81,160 @@ public class TestApplicationMasterService {
|
||||||
private final int GB = 1024;
|
private final int GB = 1024;
|
||||||
private static YarnConfiguration conf;
|
private static YarnConfiguration conf;
|
||||||
|
|
||||||
@BeforeClass
|
private static AtomicInteger beforeRegCount = new AtomicInteger(0);
|
||||||
public static void setup() {
|
private static AtomicInteger afterRegCount = new AtomicInteger(0);
|
||||||
|
private static AtomicInteger beforeAllocCount = new AtomicInteger(0);
|
||||||
|
private static AtomicInteger afterAllocCount = new AtomicInteger(0);
|
||||||
|
private static AtomicInteger beforeFinishCount = new AtomicInteger(0);
|
||||||
|
private static AtomicInteger afterFinishCount = new AtomicInteger(0);
|
||||||
|
private static AtomicInteger initCount = new AtomicInteger(0);
|
||||||
|
|
||||||
|
static class TestInterceptor1 implements
|
||||||
|
ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
|
private ApplicationMasterServiceProcessor nextProcessor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ApplicationMasterServiceContext amsContext,
|
||||||
|
ApplicationMasterServiceProcessor next) {
|
||||||
|
initCount.incrementAndGet();
|
||||||
|
this.nextProcessor = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerApplicationMaster(ApplicationAttemptId
|
||||||
|
applicationAttemptId, RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse response) throws IOException {
|
||||||
|
nextProcessor.registerApplicationMaster(
|
||||||
|
applicationAttemptId, request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allocate(ApplicationAttemptId appAttemptId,
|
||||||
|
AllocateRequest request,
|
||||||
|
AllocateResponse response) throws YarnException {
|
||||||
|
beforeAllocCount.incrementAndGet();
|
||||||
|
nextProcessor.allocate(appAttemptId, request, response);
|
||||||
|
afterAllocCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishApplicationMaster(
|
||||||
|
ApplicationAttemptId applicationAttemptId,
|
||||||
|
FinishApplicationMasterRequest request,
|
||||||
|
FinishApplicationMasterResponse response) {
|
||||||
|
beforeFinishCount.incrementAndGet();
|
||||||
|
afterFinishCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class TestInterceptor2 implements
|
||||||
|
ApplicationMasterServiceProcessor {
|
||||||
|
|
||||||
|
private ApplicationMasterServiceProcessor nextProcessor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(ApplicationMasterServiceContext amsContext,
|
||||||
|
ApplicationMasterServiceProcessor next) {
|
||||||
|
initCount.incrementAndGet();
|
||||||
|
this.nextProcessor = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerApplicationMaster(
|
||||||
|
ApplicationAttemptId applicationAttemptId,
|
||||||
|
RegisterApplicationMasterRequest request,
|
||||||
|
RegisterApplicationMasterResponse response) throws IOException {
|
||||||
|
beforeRegCount.incrementAndGet();
|
||||||
|
nextProcessor.registerApplicationMaster(applicationAttemptId,
|
||||||
|
request, response);
|
||||||
|
afterRegCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void allocate(ApplicationAttemptId appAttemptId,
|
||||||
|
AllocateRequest request, AllocateResponse response)
|
||||||
|
throws YarnException {
|
||||||
|
beforeAllocCount.incrementAndGet();
|
||||||
|
nextProcessor.allocate(appAttemptId, request, response);
|
||||||
|
afterAllocCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishApplicationMaster(
|
||||||
|
ApplicationAttemptId applicationAttemptId,
|
||||||
|
FinishApplicationMasterRequest request,
|
||||||
|
FinishApplicationMasterResponse response) {
|
||||||
|
beforeFinishCount.incrementAndGet();
|
||||||
|
nextProcessor.finishApplicationMaster(
|
||||||
|
applicationAttemptId, request, response);
|
||||||
|
afterFinishCount.incrementAndGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
conf = new YarnConfiguration();
|
conf = new YarnConfiguration();
|
||||||
conf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class,
|
conf.setClass(YarnConfiguration.RM_SCHEDULER, FifoScheduler.class,
|
||||||
ResourceScheduler.class);
|
ResourceScheduler.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(timeout = 300000)
|
||||||
|
public void testApplicationMasterInterceptor() throws Exception {
|
||||||
|
conf.set(YarnConfiguration.RM_APPLICATION_MASTER_SERVICE_PROCESSORS,
|
||||||
|
TestInterceptor1.class.getName() + ","
|
||||||
|
+ TestInterceptor2.class.getName());
|
||||||
|
MockRM rm = new MockRM(conf);
|
||||||
|
rm.start();
|
||||||
|
|
||||||
|
// Register node1
|
||||||
|
MockNM nm1 = rm.registerNode("127.0.0.1:1234", 6 * GB);
|
||||||
|
|
||||||
|
// Submit an application
|
||||||
|
RMApp app1 = rm.submitApp(2048);
|
||||||
|
|
||||||
|
// kick the scheduling
|
||||||
|
nm1.nodeHeartbeat(true);
|
||||||
|
RMAppAttempt attempt1 = app1.getCurrentAppAttempt();
|
||||||
|
MockAM am1 = rm.sendAMLaunched(attempt1.getAppAttemptId());
|
||||||
|
am1.registerAppAttempt();
|
||||||
|
int allocCount = 0;
|
||||||
|
|
||||||
|
am1.addRequests(new String[] {"127.0.0.1"}, GB, 1, 1);
|
||||||
|
AllocateResponse alloc1Response = am1.schedule(); // send the request
|
||||||
|
allocCount++;
|
||||||
|
|
||||||
|
// kick the scheduler
|
||||||
|
nm1.nodeHeartbeat(true);
|
||||||
|
while (alloc1Response.getAllocatedContainers().size() < 1) {
|
||||||
|
LOG.info("Waiting for containers to be created for app 1...");
|
||||||
|
sleep(1000);
|
||||||
|
alloc1Response = am1.schedule();
|
||||||
|
allocCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// assert RMIdentifer is set properly in allocated containers
|
||||||
|
Container allocatedContainer =
|
||||||
|
alloc1Response.getAllocatedContainers().get(0);
|
||||||
|
ContainerTokenIdentifier tokenId =
|
||||||
|
BuilderUtils.newContainerTokenIdentifier(allocatedContainer
|
||||||
|
.getContainerToken());
|
||||||
|
am1.unregisterAppAttempt();
|
||||||
|
|
||||||
|
Assert.assertEquals(1, beforeRegCount.get());
|
||||||
|
Assert.assertEquals(1, afterRegCount.get());
|
||||||
|
|
||||||
|
// The allocate calls should be incremented twice
|
||||||
|
Assert.assertEquals(allocCount * 2, beforeAllocCount.get());
|
||||||
|
Assert.assertEquals(allocCount * 2, afterAllocCount.get());
|
||||||
|
|
||||||
|
// Finish should only be called once, since the FirstInterceptor
|
||||||
|
// does not forward the call.
|
||||||
|
Assert.assertEquals(1, beforeFinishCount.get());
|
||||||
|
Assert.assertEquals(1, afterFinishCount.get());
|
||||||
|
rm.stop();
|
||||||
|
}
|
||||||
|
|
||||||
@Test(timeout = 3000000)
|
@Test(timeout = 3000000)
|
||||||
public void testRMIdentifierOnContainerAllocation() throws Exception {
|
public void testRMIdentifierOnContainerAllocation() throws Exception {
|
||||||
MockRM rm = new MockRM(conf);
|
MockRM rm = new MockRM(conf);
|
||||||
|
|
Loading…
Reference in New Issue