YARN-3948. Display Application Priority in RM Web UI.(Sunil G via rohithsharmaks)

(cherry picked from commit b6265d39c5d0fda21dfe55273f193d8a6a20c6a8)
This commit is contained in:
Rohith Sharma K S 2015-08-07 10:43:41 +05:30
parent 42a05d29ee
commit a0da1ec010
15 changed files with 116 additions and 21 deletions

View File

@ -104,6 +104,8 @@ Release 2.8.0 - UNRELEASED
YARN-3736. Add RMStateStore apis to store and load accepted reservations for YARN-3736. Add RMStateStore apis to store and load accepted reservations for
failover (adhoot via asuresh) failover (adhoot via asuresh)
YARN-3948. Display Application Priority in RM Web UI.(Sunil G via rohithsharmaks)
IMPROVEMENTS IMPROVEMENTS
YARN-644. Basic null check is not performed on passed in arguments before YARN-644. Basic null check is not performed on passed in arguments before

View File

@ -408,4 +408,17 @@ public abstract void setLogAggregationStatus(
@Public @Public
@Unstable @Unstable
public abstract void setUnmanagedApp(boolean unmanagedApplication); public abstract void setUnmanagedApp(boolean unmanagedApplication);
/**
* Get priority of the application
*
* @return Application's priority
*/
@Public
@Stable
public abstract Priority getPriority();
@Private
@Unstable
public abstract void setPriority(Priority priority);
} }

View File

@ -196,6 +196,7 @@ message ApplicationReportProto {
repeated string applicationTags = 20; repeated string applicationTags = 20;
optional LogAggregationStatusProto log_aggregation_status = 21; optional LogAggregationStatusProto log_aggregation_status = 21;
optional bool unmanaged_application = 22 [default = false]; optional bool unmanaged_application = 22 [default = false];
optional PriorityProto priority = 23;
} }
enum LogAggregationStatusProto { enum LogAggregationStatusProto {

View File

@ -501,6 +501,8 @@ private int printApplicationReport(String applicationId)
appReportStr.println(appReport.getUser()); appReportStr.println(appReport.getUser());
appReportStr.print("\tQueue : "); appReportStr.print("\tQueue : ");
appReportStr.println(appReport.getQueue()); appReportStr.println(appReport.getQueue());
appReportStr.print("\tApplication Priority : ");
appReportStr.println(appReport.getPriority());
appReportStr.print("\tStart-Time : "); appReportStr.print("\tStart-Time : ");
appReportStr.println(appReport.getStartTime()); appReportStr.println(appReport.getStartTime());
appReportStr.print("\tFinish-Time : "); appReportStr.print("\tFinish-Time : ");

View File

@ -106,6 +106,7 @@ public void testGetApplicationReport() throws Exception {
FinalApplicationStatus.SUCCEEDED, usageReport, "N/A", 0.53789f, "YARN", FinalApplicationStatus.SUCCEEDED, usageReport, "N/A", 0.53789f, "YARN",
null, null, false); null, null, false);
newApplicationReport.setLogAggregationStatus(LogAggregationStatus.SUCCEEDED); newApplicationReport.setLogAggregationStatus(LogAggregationStatus.SUCCEEDED);
newApplicationReport.setPriority(Priority.newInstance(0));
when(client.getApplicationReport(any(ApplicationId.class))).thenReturn( when(client.getApplicationReport(any(ApplicationId.class))).thenReturn(
newApplicationReport); newApplicationReport);
int result = cli.run(new String[] { "application", "-status", applicationId.toString() }); int result = cli.run(new String[] { "application", "-status", applicationId.toString() });
@ -119,6 +120,7 @@ public void testGetApplicationReport() throws Exception {
pw.println("\tApplication-Type : YARN"); pw.println("\tApplication-Type : YARN");
pw.println("\tUser : user"); pw.println("\tUser : user");
pw.println("\tQueue : queue"); pw.println("\tQueue : queue");
pw.println("\tApplication Priority : 0");
pw.println("\tStart-Time : 0"); pw.println("\tStart-Time : 0");
pw.println("\tFinish-Time : 0"); pw.println("\tFinish-Time : 0");
pw.println("\tProgress : 53.79%"); pw.println("\tProgress : 53.79%");

View File

@ -27,6 +27,7 @@
import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport; import org.apache.hadoop.yarn.api.records.ApplicationResourceUsageReport;
import org.apache.hadoop.yarn.api.records.FinalApplicationStatus; import org.apache.hadoop.yarn.api.records.FinalApplicationStatus;
import org.apache.hadoop.yarn.api.records.LogAggregationStatus; import org.apache.hadoop.yarn.api.records.LogAggregationStatus;
import org.apache.hadoop.yarn.api.records.Priority;
import org.apache.hadoop.yarn.api.records.Token; import org.apache.hadoop.yarn.api.records.Token;
import org.apache.hadoop.yarn.api.records.YarnApplicationState; import org.apache.hadoop.yarn.api.records.YarnApplicationState;
import org.apache.hadoop.yarn.proto.YarnProtos.ApplicationAttemptIdProto; import org.apache.hadoop.yarn.proto.YarnProtos.ApplicationAttemptIdProto;
@ -36,6 +37,7 @@
import org.apache.hadoop.yarn.proto.YarnProtos.ApplicationResourceUsageReportProto; import org.apache.hadoop.yarn.proto.YarnProtos.ApplicationResourceUsageReportProto;
import org.apache.hadoop.yarn.proto.YarnProtos.FinalApplicationStatusProto; import org.apache.hadoop.yarn.proto.YarnProtos.FinalApplicationStatusProto;
import org.apache.hadoop.yarn.proto.YarnProtos.LogAggregationStatusProto; import org.apache.hadoop.yarn.proto.YarnProtos.LogAggregationStatusProto;
import org.apache.hadoop.yarn.proto.YarnProtos.PriorityProto;
import org.apache.hadoop.yarn.proto.YarnProtos.YarnApplicationStateProto; import org.apache.hadoop.yarn.proto.YarnProtos.YarnApplicationStateProto;
import com.google.protobuf.TextFormat; import com.google.protobuf.TextFormat;
@ -55,6 +57,7 @@ public class ApplicationReportPBImpl extends ApplicationReport {
private Token clientToAMToken = null; private Token clientToAMToken = null;
private Token amRmToken = null; private Token amRmToken = null;
private Set<String> applicationTags = null; private Set<String> applicationTags = null;
private Priority priority = null;
public ApplicationReportPBImpl() { public ApplicationReportPBImpl() {
builder = ApplicationReportProto.newBuilder(); builder = ApplicationReportProto.newBuilder();
@ -484,6 +487,11 @@ private void mergeLocalToBuilder() {
builder.clearApplicationTags(); builder.clearApplicationTags();
builder.addAllApplicationTags(this.applicationTags); builder.addAllApplicationTags(this.applicationTags);
} }
if (this.priority != null
&& !((PriorityPBImpl) this.priority).getProto().equals(
builder.getPriority())) {
builder.setPriority(convertToProtoFormat(this.priority));
}
} }
private void mergeLocalToProto() { private void mergeLocalToProto() {
@ -551,6 +559,14 @@ private TokenProto convertToProtoFormat(Token t) {
return ((TokenPBImpl)t).getProto(); return ((TokenPBImpl)t).getProto();
} }
private PriorityPBImpl convertFromProtoFormat(PriorityProto p) {
return new PriorityPBImpl(p);
}
private PriorityProto convertToProtoFormat(Priority t) {
return ((PriorityPBImpl)t).getProto();
}
@Override @Override
public LogAggregationStatus getLogAggregationStatus() { public LogAggregationStatus getLogAggregationStatus() {
ApplicationReportProtoOrBuilder p = viaProto ? proto : builder; ApplicationReportProtoOrBuilder p = viaProto ? proto : builder;
@ -593,4 +609,25 @@ public void setUnmanagedApp(boolean unmanagedApplication) {
maybeInitBuilder(); maybeInitBuilder();
builder.setUnmanagedApplication(unmanagedApplication); builder.setUnmanagedApplication(unmanagedApplication);
} }
@Override
public Priority getPriority() {
ApplicationReportProtoOrBuilder p = viaProto ? proto : builder;
if (this.priority != null) {
return this.priority;
}
if (!p.hasPriority()) {
return null;
}
this.priority = convertFromProtoFormat(p.getPriority());
return this.priority;
}
@Override
public void setPriority(Priority priority) {
maybeInitBuilder();
if (priority == null)
builder.clearPriority();
this.priority = priority;
}
} }

View File

@ -324,7 +324,8 @@ public static ApplicationReport newApplicationReport(
String url, long startTime, long finishTime, String url, long startTime, long finishTime,
FinalApplicationStatus finalStatus, FinalApplicationStatus finalStatus,
ApplicationResourceUsageReport appResources, String origTrackingUrl, ApplicationResourceUsageReport appResources, String origTrackingUrl,
float progress, String appType, Token amRmToken, Set<String> tags) { float progress, String appType, Token amRmToken, Set<String> tags,
Priority priority) {
ApplicationReport report = recordFactory ApplicationReport report = recordFactory
.newRecordInstance(ApplicationReport.class); .newRecordInstance(ApplicationReport.class);
report.setApplicationId(applicationId); report.setApplicationId(applicationId);
@ -347,6 +348,7 @@ public static ApplicationReport newApplicationReport(
report.setApplicationType(appType); report.setApplicationType(appType);
report.setAMRMToken(amRmToken); report.setAMRMToken(amRmToken);
report.setApplicationTags(tags); report.setApplicationTags(tags);
report.setPriority(priority);
return report; return report;
} }

View File

@ -167,6 +167,7 @@ public ApplicationReport run() throws Exception {
._("Application Type:", app.getType()) ._("Application Type:", app.getType())
._("Application Tags:", ._("Application Tags:",
app.getApplicationTags() == null ? "" : app.getApplicationTags()) app.getApplicationTags() == null ? "" : app.getApplicationTags())
._("Application Priority:", clarifyAppPriority(app.getPriority()))
._( ._(
"YarnApplicationState:", "YarnApplicationState:",
app.getAppState() == null ? UNAVAILABLE : clarifyAppState(app app.getAppState() == null ? UNAVAILABLE : clarifyAppState(app
@ -342,6 +343,10 @@ private String clarifyAppState(YarnApplicationState state) {
} }
} }
private String clarifyAppPriority(int priority) {
return priority + " (Higher Integer value indicates higher priority)";
}
private String clairfyAppFinalStatus(FinalApplicationStatus status) { private String clairfyAppFinalStatus(FinalApplicationStatus status) {
if (status == FinalApplicationStatus.UNDEFINED) { if (status == FinalApplicationStatus.UNDEFINED) {
return "Application has not completed yet."; return "Application has not completed yet.";

View File

@ -52,13 +52,13 @@ private static String getAppsTableColumnDefs(
.append("{'sType':'string', 'aTargets': [0]") .append("{'sType':'string', 'aTargets': [0]")
.append(", 'mRender': parseHadoopID }") .append(", 'mRender': parseHadoopID }")
.append("\n, {'sType':'numeric', 'aTargets': " + .append("\n, {'sType':'numeric', 'aTargets': " +
(isFairSchedulerPage ? "[6, 7]": "[5, 6]")) (isFairSchedulerPage ? "[6, 7]": "[6, 7]"))
.append(", 'mRender': renderHadoopDate }") .append(", 'mRender': renderHadoopDate }")
.append("\n, {'sType':'numeric', bSearchable:false, 'aTargets':"); .append("\n, {'sType':'numeric', bSearchable:false, 'aTargets':");
if (isFairSchedulerPage) { if (isFairSchedulerPage) {
sb.append("[13]"); sb.append("[13]");
} else if (isResourceManager) { } else if (isResourceManager) {
sb.append("[12]"); sb.append("[13]");
} else { } else {
sb.append("[9]"); sb.append("[9]");
} }

View File

@ -58,6 +58,7 @@ public class AppInfo {
protected long finishedTime; protected long finishedTime;
protected long elapsedTime; protected long elapsedTime;
protected String applicationTags; protected String applicationTags;
protected int priority;
private int allocatedCpuVcores; private int allocatedCpuVcores;
private int allocatedMemoryMB; private int allocatedMemoryMB;
protected boolean unmanagedApplication; protected boolean unmanagedApplication;
@ -86,6 +87,10 @@ public AppInfo(ApplicationReport app) {
finishedTime = app.getFinishTime(); finishedTime = app.getFinishTime();
elapsedTime = Times.elapsed(startedTime, finishedTime); elapsedTime = Times.elapsed(startedTime, finishedTime);
finalAppStatus = app.getFinalApplicationStatus(); finalAppStatus = app.getFinalApplicationStatus();
priority = 0;
if (app.getPriority() != null) {
priority = app.getPriority().getPriority();
}
if (app.getApplicationResourceUsageReport() != null) { if (app.getApplicationResourceUsageReport() != null) {
runningContainers = app.getApplicationResourceUsageReport() runningContainers = app.getApplicationResourceUsageReport()
.getNumUsedContainers(); .getNumUsedContainers();
@ -194,4 +199,8 @@ public String getApplicationTags() {
public boolean isUnmanagedApp() { public boolean isUnmanagedApp() {
return unmanagedApplication; return unmanagedApplication;
} }
public int getPriority() {
return priority;
}
} }

View File

@ -660,10 +660,10 @@ public ApplicationReport createAndGetApplicationReport(String clientUserName,
ApplicationReport report = BuilderUtils.newApplicationReport( ApplicationReport report = BuilderUtils.newApplicationReport(
this.applicationId, currentApplicationAttemptId, this.user, this.applicationId, currentApplicationAttemptId, this.user,
this.queue, this.name, host, rpcPort, clientToAMToken, this.queue, this.name, host, rpcPort, clientToAMToken,
createApplicationState(), diags, createApplicationState(), diags, trackingUrl, this.startTime,
trackingUrl, this.startTime, this.finishTime, finishState, this.finishTime, finishState, appUsageReport, origTrackingUrl,
appUsageReport, origTrackingUrl, progress, this.applicationType, progress, this.applicationType, amrmToken, applicationTags,
amrmToken, applicationTags); this.submissionContext.getPriority());
report.setLogAggregationStatus(logAggregationStatus); report.setLogAggregationStatus(logAggregationStatus);
report.setUnmanagedApp(submissionContext.getUnmanagedAM()); report.setUnmanagedApp(submissionContext.getUnmanagedAM());
return report; return report;

View File

@ -56,7 +56,8 @@ protected void renderData(Block html) {
TBODY<TABLE<Hamlet>> tbody = TBODY<TABLE<Hamlet>> tbody =
html.table("#apps").thead().tr().th(".id", "ID").th(".user", "User") html.table("#apps").thead().tr().th(".id", "ID").th(".user", "User")
.th(".name", "Name").th(".type", "Application Type") .th(".name", "Name").th(".type", "Application Type")
.th(".queue", "Queue").th(".starttime", "StartTime") .th(".queue", "Queue").th(".priority", "Application Priority")
.th(".starttime", "StartTime")
.th(".finishtime", "FinishTime").th(".state", "State") .th(".finishtime", "FinishTime").th(".state", "State")
.th(".finalstatus", "FinalStatus") .th(".finalstatus", "FinalStatus")
.th(".runningcontainer", "Running Containers") .th(".runningcontainer", "Running Containers")
@ -106,7 +107,9 @@ protected void renderData(Block html) {
.append("\",\"") .append("\",\"")
.append( .append(
StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app StringEscapeUtils.escapeJavaScript(StringEscapeUtils.escapeHtml(app
.getQueue()))).append("\",\"").append(app.getStartedTime()) .getQueue()))).append("\",\"").append(String
.valueOf(app.getPriority()))
.append("\",\"").append(app.getStartedTime())
.append("\",\"").append(app.getFinishedTime()) .append("\",\"").append(app.getFinishedTime())
.append("\",\"") .append("\",\"")
.append(app.getAppState() == null ? UNAVAILABLE : app.getAppState()) .append(app.getAppState() == null ? UNAVAILABLE : app.getAppState())

View File

@ -74,7 +74,8 @@ public class AppInfo {
protected long clusterId; protected long clusterId;
protected String applicationType; protected String applicationType;
protected String applicationTags = ""; protected String applicationTags = "";
protected int priority;
// these are only allowed if acls allow // these are only allowed if acls allow
protected long startedTime; protected long startedTime;
protected long finishedTime; protected long finishedTime;
@ -130,6 +131,11 @@ public AppInfo(ResourceManager rm, RMApp app, Boolean hasAccess,
this.user = app.getUser().toString(); this.user = app.getUser().toString();
this.name = app.getName().toString(); this.name = app.getName().toString();
this.queue = app.getQueue().toString(); this.queue = app.getQueue().toString();
this.priority = 0;
if (app.getApplicationSubmissionContext().getPriority() != null) {
this.priority = app.getApplicationSubmissionContext().getPriority()
.getPriority();
}
this.progress = app.getProgress() * 100; this.progress = app.getProgress() * 100;
this.diagnostics = app.getDiagnostics().toString(); this.diagnostics = app.getDiagnostics().toString();
if (diagnostics == null || diagnostics.isEmpty()) { if (diagnostics == null || diagnostics.isEmpty()) {
@ -328,4 +334,8 @@ public LogAggregationStatus getLogAggregationStatus() {
public boolean isUnmanagedApp() { public boolean isUnmanagedApp() {
return unmanagedApplication; return unmanagedApplication;
} }
public int getPriority() {
return this.priority;
}
} }

View File

@ -1290,6 +1290,7 @@ public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException,
WebServicesTestUtils.getXmlString(element, "name"), WebServicesTestUtils.getXmlString(element, "name"),
WebServicesTestUtils.getXmlString(element, "applicationType"), WebServicesTestUtils.getXmlString(element, "applicationType"),
WebServicesTestUtils.getXmlString(element, "queue"), WebServicesTestUtils.getXmlString(element, "queue"),
WebServicesTestUtils.getXmlInt(element, "priority"),
WebServicesTestUtils.getXmlString(element, "state"), WebServicesTestUtils.getXmlString(element, "state"),
WebServicesTestUtils.getXmlString(element, "finalStatus"), WebServicesTestUtils.getXmlString(element, "finalStatus"),
WebServicesTestUtils.getXmlFloat(element, "progress"), WebServicesTestUtils.getXmlFloat(element, "progress"),
@ -1316,18 +1317,18 @@ public void verifyAppsXML(NodeList nodes, RMApp app) throws JSONException,
public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException, public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
Exception { Exception {
assertEquals("incorrect number of elements", 29, info.length()); assertEquals("incorrect number of elements", 30, info.length());
verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"), verifyAppInfoGeneric(app, info.getString("id"), info.getString("user"),
info.getString("name"), info.getString("applicationType"), info.getString("name"), info.getString("applicationType"),
info.getString("queue"), info.getString("state"), info.getString("queue"), info.getInt("priority"),
info.getString("finalStatus"), (float) info.getDouble("progress"), info.getString("state"), info.getString("finalStatus"),
info.getString("trackingUI"), info.getString("diagnostics"), (float) info.getDouble("progress"), info.getString("trackingUI"),
info.getLong("clusterId"), info.getLong("startedTime"), info.getString("diagnostics"), info.getLong("clusterId"),
info.getLong("finishedTime"), info.getLong("elapsedTime"), info.getLong("startedTime"), info.getLong("finishedTime"),
info.getString("amHostHttpAddress"), info.getString("amContainerLogs"), info.getLong("elapsedTime"), info.getString("amHostHttpAddress"),
info.getInt("allocatedMB"), info.getInt("allocatedVCores"), info.getString("amContainerLogs"), info.getInt("allocatedMB"),
info.getInt("runningContainers"), info.getInt("allocatedVCores"), info.getInt("runningContainers"),
info.getInt("preemptedResourceMB"), info.getInt("preemptedResourceMB"),
info.getInt("preemptedResourceVCores"), info.getInt("preemptedResourceVCores"),
info.getInt("numNonAMContainerPreempted"), info.getInt("numNonAMContainerPreempted"),
@ -1337,8 +1338,8 @@ public void verifyAppInfo(JSONObject info, RMApp app) throws JSONException,
} }
public void verifyAppInfoGeneric(RMApp app, String id, String user, public void verifyAppInfoGeneric(RMApp app, String id, String user,
String name, String applicationType, String queue, String state, String name, String applicationType, String queue, int prioirty,
String finalStatus, float progress, String trackingUI, String state, String finalStatus, float progress, String trackingUI,
String diagnostics, long clusterId, long startedTime, long finishedTime, String diagnostics, long clusterId, long startedTime, long finishedTime,
long elapsedTime, String amHostHttpAddress, String amContainerLogs, long elapsedTime, String amHostHttpAddress, String amContainerLogs,
int allocatedMB, int allocatedVCores, int numContainers, int allocatedMB, int allocatedVCores, int numContainers,
@ -1355,6 +1356,7 @@ public void verifyAppInfoGeneric(RMApp app, String id, String user,
WebServicesTestUtils.checkStringMatch("applicationType", WebServicesTestUtils.checkStringMatch("applicationType",
app.getApplicationType(), applicationType); app.getApplicationType(), applicationType);
WebServicesTestUtils.checkStringMatch("queue", app.getQueue(), queue); WebServicesTestUtils.checkStringMatch("queue", app.getQueue(), queue);
assertEquals("priority doesn't match", 0, prioirty);
WebServicesTestUtils.checkStringMatch("state", app.getState().toString(), WebServicesTestUtils.checkStringMatch("state", app.getState().toString(),
state); state);
WebServicesTestUtils.checkStringMatch("finalStatus", app WebServicesTestUtils.checkStringMatch("finalStatus", app

View File

@ -1382,6 +1382,7 @@ Response Body:
"memorySeconds" : 151730, "memorySeconds" : 151730,
"vcoreSeconds" : 103, "vcoreSeconds" : 103,
"unmanagedApplication":"false" "unmanagedApplication":"false"
"applicationPriority":0
}, },
{ {
"finishedTime" : 1326815789546, "finishedTime" : 1326815789546,
@ -1408,6 +1409,7 @@ Response Body:
"memorySeconds" : 640064, "memorySeconds" : 640064,
"vcoreSeconds" : 442 "vcoreSeconds" : 442
"unmanagedApplication":"false" "unmanagedApplication":"false"
"applicationPriority":0
} }
] ]
} }
@ -1458,6 +1460,7 @@ Response Body:
<memorySeconds>151730</memorySeconds> <memorySeconds>151730</memorySeconds>
<vcoreSeconds>103</vcoreSeconds> <vcoreSeconds>103</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication> <unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
</app> </app>
<app> <app>
<id>application_1326815542473_0002</id> <id>application_1326815542473_0002</id>
@ -1484,6 +1487,7 @@ Response Body:
<memorySeconds>640064</memorySeconds> <memorySeconds>640064</memorySeconds>
<vcoreSeconds>442</vcoreSeconds> <vcoreSeconds>442</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication> <unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
</app> </app>
</apps> </apps>
``` ```
@ -1644,6 +1648,7 @@ Note that depending on security settings a user might not be able to see all the
| memorySeconds | long | The amount of memory the application has allocated (megabyte-seconds) | | memorySeconds | long | The amount of memory the application has allocated (megabyte-seconds) |
| vcoreSeconds | long | The amount of CPU resources the application has allocated (virtual core-seconds) | | vcoreSeconds | long | The amount of CPU resources the application has allocated (virtual core-seconds) |
| unmanagedApplication | boolean | Is the application unmanaged. | | unmanagedApplication | boolean | Is the application unmanaged. |
| applicationPriority | int | priority of the submitted application |
### Response Examples ### Response Examples
@ -1685,6 +1690,7 @@ Response Body:
"memorySeconds" : 151730, "memorySeconds" : 151730,
"vcoreSeconds" : 103, "vcoreSeconds" : 103,
"unmanagedApplication":"false" "unmanagedApplication":"false"
"applicationPriority":0
} }
} }
``` ```
@ -1727,6 +1733,7 @@ Response Body:
<memorySeconds>151730</memorySeconds> <memorySeconds>151730</memorySeconds>
<vcoreSeconds>103</vcoreSeconds> <vcoreSeconds>103</vcoreSeconds>
<unmanagedApplication>false</unmanagedApplication> <unmanagedApplication>false</unmanagedApplication>
<applicationPriority>0</applicationPriority>
</app> </app>
``` ```