SLIDER-979 AM web UI to show state of AA request
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/591ba99e Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/591ba99e Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/591ba99e Branch: refs/heads/feature/SLIDER-82-pass-3.1 Commit: 591ba99ecbcec2edc208cafec6b36cc84c6f23cf Parents: 8efc4c2 Author: Steve Loughran <[email protected]> Authored: Mon Nov 16 20:07:59 2015 +0000 Committer: Steve Loughran <[email protected]> Committed: Mon Nov 16 20:07:59 2015 +0000 ---------------------------------------------------------------------- .../org/apache/slider/api/proto/Messages.java | 191 ++++++++++++++----- .../slider/api/proto/RestTypeMarshalling.java | 8 +- .../types/ApplicationLivenessInformation.java | 6 + .../slider/api/types/ComponentInformation.java | 4 +- .../apache/slider/api/types/RoleStatistics.java | 66 +++++++ .../rest/SliderApplicationApiRestClient.java | 14 ++ .../appmaster/actions/ActionKillContainer.java | 2 +- .../server/appmaster/actions/QueueService.java | 8 +- .../slider/server/appmaster/state/AppState.java | 33 ++-- .../appmaster/state/ProviderAppState.java | 5 + .../server/appmaster/state/RoleStatus.java | 20 ++ .../state/StateAccessForProviders.java | 7 + .../web/rest/AbstractSliderResource.java | 7 +- .../server/appmaster/web/rest/RestPaths.java | 11 ++ .../web/view/ClusterSpecificationBlock.java | 13 +- .../appmaster/web/view/ContainerStatsBlock.java | 9 +- .../server/appmaster/web/view/IndexBlock.java | 84 ++++---- .../server/appmaster/web/view/NavBlock.java | 26 ++- .../appmaster/web/view/SliderHamletBlock.java | 56 ++++++ .../src/main/proto/SliderClusterMessages.proto | 1 + .../agent/AgentMiniClusterTestBase.groovy | 7 +- .../slider/agent/rest/TestStandaloneREST.groovy | 5 +- .../slider/providers/agent/AgentTestBase.groovy | 1 + .../providers/agent/DemoAgentAAEcho.groovy | 8 +- .../providers/agent/TestAgentAAEcho.groovy | 29 ++- .../slider/providers/agent/TestAgentEcho.groovy | 6 +- .../org/apache/slider/test/KeysForTests.groovy | 3 +- slider-core/src/test/python/agent.py | 25 ++- slider-core/src/test/python/agent/main.py | 18 +- slider-core/src/test/python/echo.py | 23 ++- slider-core/src/test/python/metainfo.xml | 2 +- 31 files changed, 529 insertions(+), 169 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java index 569660d..ed056f5 100644 --- a/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java +++ b/slider-core/src/main/java/org/apache/slider/api/proto/Messages.java @@ -15110,6 +15110,16 @@ public final class Messages { * <code>optional int32 pendingAntiAffineRequestCount = 18;</code> */ int getPendingAntiAffineRequestCount(); + + // optional bool isAARequestOutstanding = 19; + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + boolean hasIsAARequestOutstanding(); + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + boolean getIsAARequestOutstanding(); } /** * Protobuf type {@code org.apache.slider.api.ComponentInformationProto} @@ -15260,6 +15270,11 @@ public final class Messages { pendingAntiAffineRequestCount_ = input.readInt32(); break; } + case 152: { + bitField0_ |= 0x00020000; + isAARequestOutstanding_ = input.readBool(); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -15659,6 +15674,22 @@ public final class Messages { return pendingAntiAffineRequestCount_; } + // optional bool isAARequestOutstanding = 19; + public static final int ISAAREQUESTOUTSTANDING_FIELD_NUMBER = 19; + private boolean isAARequestOutstanding_; + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public boolean hasIsAARequestOutstanding() { + return ((bitField0_ & 0x00020000) == 0x00020000); + } + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public boolean getIsAARequestOutstanding() { + return isAARequestOutstanding_; + } + private void initFields() { name_ = ""; priority_ = 0; @@ -15678,6 +15709,7 @@ public final class Messages { nodeFailed_ = 0; preempted_ = 0; pendingAntiAffineRequestCount_ = 0; + isAARequestOutstanding_ = false; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -15745,6 +15777,9 @@ public final class Messages { if (((bitField0_ & 0x00010000) == 0x00010000)) { output.writeInt32(18, pendingAntiAffineRequestCount_); } + if (((bitField0_ & 0x00020000) == 0x00020000)) { + output.writeBool(19, isAARequestOutstanding_); + } getUnknownFields().writeTo(output); } @@ -15831,6 +15866,10 @@ public final class Messages { size += com.google.protobuf.CodedOutputStream .computeInt32Size(18, pendingAntiAffineRequestCount_); } + if (((bitField0_ & 0x00020000) == 0x00020000)) { + size += com.google.protobuf.CodedOutputStream + .computeBoolSize(19, isAARequestOutstanding_); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -15941,6 +15980,11 @@ public final class Messages { result = result && (getPendingAntiAffineRequestCount() == other.getPendingAntiAffineRequestCount()); } + result = result && (hasIsAARequestOutstanding() == other.hasIsAARequestOutstanding()); + if (hasIsAARequestOutstanding()) { + result = result && (getIsAARequestOutstanding() + == other.getIsAARequestOutstanding()); + } result = result && getUnknownFields().equals(other.getUnknownFields()); return result; @@ -16026,6 +16070,10 @@ public final class Messages { hash = (37 * hash) + PENDINGANTIAFFINEREQUESTCOUNT_FIELD_NUMBER; hash = (53 * hash) + getPendingAntiAffineRequestCount(); } + if (hasIsAARequestOutstanding()) { + hash = (37 * hash) + ISAAREQUESTOUTSTANDING_FIELD_NUMBER; + hash = (53 * hash) + hashBoolean(getIsAARequestOutstanding()); + } hash = (29 * hash) + getUnknownFields().hashCode(); memoizedHashCode = hash; return hash; @@ -16176,6 +16224,8 @@ public final class Messages { bitField0_ = (bitField0_ & ~0x00010000); pendingAntiAffineRequestCount_ = 0; bitField0_ = (bitField0_ & ~0x00020000); + isAARequestOutstanding_ = false; + bitField0_ = (bitField0_ & ~0x00040000); return this; } @@ -16278,6 +16328,10 @@ public final class Messages { to_bitField0_ |= 0x00010000; } result.pendingAntiAffineRequestCount_ = pendingAntiAffineRequestCount_; + if (((from_bitField0_ & 0x00040000) == 0x00040000)) { + to_bitField0_ |= 0x00020000; + } + result.isAARequestOutstanding_ = isAARequestOutstanding_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -16359,6 +16413,9 @@ public final class Messages { if (other.hasPendingAntiAffineRequestCount()) { setPendingAntiAffineRequestCount(other.getPendingAntiAffineRequestCount()); } + if (other.hasIsAARequestOutstanding()) { + setIsAARequestOutstanding(other.getIsAARequestOutstanding()); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -17122,6 +17179,39 @@ public final class Messages { return this; } + // optional bool isAARequestOutstanding = 19; + private boolean isAARequestOutstanding_ ; + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public boolean hasIsAARequestOutstanding() { + return ((bitField0_ & 0x00040000) == 0x00040000); + } + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public boolean getIsAARequestOutstanding() { + return isAARequestOutstanding_; + } + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public Builder setIsAARequestOutstanding(boolean value) { + bitField0_ |= 0x00040000; + isAARequestOutstanding_ = value; + onChanged(); + return this; + } + /** + * <code>optional bool isAARequestOutstanding = 19;</code> + */ + public Builder clearIsAARequestOutstanding() { + bitField0_ = (bitField0_ & ~0x00040000); + isAARequestOutstanding_ = false; + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:org.apache.slider.api.ComponentInformationProto) } @@ -34023,7 +34113,7 @@ public final class Messages { " \002(\t\022\023\n\013application\030\003 \002(\t\"`\n#Application" + "LivenessInformationProto\022\034\n\024allRequestsS" + "atisfied\030\001 \001(\010\022\033\n\023requestsOutstanding\030\002 " + - "\001(\005\"\216\003\n\031ComponentInformationProto\022\014\n\004nam", + "\001(\005\"\256\003\n\031ComponentInformationProto\022\014\n\004nam", "e\030\001 \001(\t\022\020\n\010priority\030\002 \001(\005\022\017\n\007desired\030\003 \001" + "(\005\022\016\n\006actual\030\004 \001(\005\022\021\n\treleasing\030\005 \001(\005\022\021\n" + "\trequested\030\006 \001(\005\022\016\n\006failed\030\007 \001(\005\022\017\n\007star" + @@ -34033,54 +34123,55 @@ public final class Messages { "(\005\022\022\n\ncontainers\030\016 \003(\t\022\026\n\016failedRecently" + "\030\017 \001(\005\022\022\n\nnodeFailed\030\020 \001(\005\022\021\n\tpreempted\030" + "\021 \001(\005\022%\n\035pendingAntiAffineRequestCount\030\022" + - " \001(\005\"\210\002\n\031ContainerInformationProto\022\023\n\013co", - "ntainerId\030\001 \001(\t\022\021\n\tcomponent\030\002 \001(\t\022\020\n\010re" + - "leased\030\003 \001(\010\022\r\n\005state\030\004 \001(\005\022\020\n\010exitCode\030" + - "\005 \001(\005\022\023\n\013diagnostics\030\006 \001(\t\022\022\n\ncreateTime" + - "\030\007 \001(\003\022\021\n\tstartTime\030\010 \001(\003\022\016\n\006output\030\t \003(" + - "\t\022\014\n\004host\030\n \001(\t\022\017\n\007hostURL\030\013 \001(\t\022\021\n\tplac" + - "ement\030\014 \001(\t\022\022\n\nappVersion\030\r \001(\t\"N\n\024PingI" + - "nformationProto\022\014\n\004text\030\001 \001(\t\022\014\n\004verb\030\002 " + - "\001(\t\022\014\n\004body\030\003 \001(\t\022\014\n\004time\030\004 \001(\003\"\325\001\n\031Node" + - "EntryInformationProto\022\020\n\010priority\030\001 \002(\005\022" + - "\021\n\trequested\030\002 \002(\005\022\020\n\010starting\030\003 \002(\005\022\023\n\013", - "startFailed\030\004 \002(\005\022\016\n\006failed\030\005 \002(\005\022\026\n\016fai" + - "ledRecently\030\006 \002(\005\022\021\n\tpreempted\030\007 \002(\005\022\014\n\004" + - "live\030\010 \002(\005\022\021\n\treleasing\030\t \002(\005\022\020\n\010lastUse" + - "d\030\n \002(\003\"\334\001\n\024NodeInformationProto\022\020\n\010host" + - "name\030\001 \002(\t\022\r\n\005state\030\002 \002(\t\022\023\n\013httpAddress" + - "\030\003 \002(\t\022\020\n\010rackName\030\004 \002(\t\022\016\n\006labels\030\005 \002(\t" + - "\022\024\n\014healthReport\030\006 \002(\t\022\023\n\013lastUpdated\030\007 " + - "\002(\003\022A\n\007entries\030\010 \003(\01320.org.apache.slider" + - ".api.NodeEntryInformationProto\"\026\n\024GetMod" + - "elRequestProto\"\035\n\033GetModelDesiredRequest", - "Proto\"$\n\"GetModelDesiredAppconfRequestPr" + - "oto\"&\n$GetModelDesiredResourcesRequestPr" + - "oto\"%\n#GetModelResolvedAppconfRequestPro" + - "to\"\'\n%GetModelResolvedResourcesRequestPr" + - "oto\"#\n!GetModelLiveResourcesRequestProto" + - "\"\037\n\035GetLiveContainersRequestProto\"u\n\036Get" + - "LiveContainersResponseProto\022\r\n\005names\030\001 \003" + - "(\t\022D\n\ncontainers\030\002 \003(\01320.org.apache.slid" + - "er.api.ContainerInformationProto\"3\n\034GetL" + - "iveContainerRequestProto\022\023\n\013containerId\030", - "\001 \002(\t\"\037\n\035GetLiveComponentsRequestProto\"u" + - "\n\036GetLiveComponentsResponseProto\022\r\n\005name" + - "s\030\001 \003(\t\022D\n\ncomponents\030\002 \003(\01320.org.apache" + - ".slider.api.ComponentInformationProto\",\n" + - "\034GetLiveComponentRequestProto\022\014\n\004name\030\001 " + - "\002(\t\"$\n\"GetApplicationLivenessRequestProt" + - "o\"\023\n\021EmptyPayloadProto\" \n\020WrappedJsonPro" + - "to\022\014\n\004json\030\001 \002(\t\"h\n\037GetCertificateStoreR" + - "equestProto\022\020\n\010hostname\030\001 \001(\t\022\023\n\013request" + - "erId\030\002 \002(\t\022\020\n\010password\030\003 \002(\t\022\014\n\004type\030\004 \002", - "(\t\"1\n GetCertificateStoreResponseProto\022\r" + - "\n\005store\030\001 \002(\014\"\032\n\030GetLiveNodesRequestProt" + - "o\"f\n\031GetLiveNodesResponseProto\022\r\n\005names\030" + - "\001 \003(\t\022:\n\005nodes\030\002 \003(\0132+.org.apache.slider" + - ".api.NodeInformationProto\"\'\n\027GetLiveNode" + - "RequestProto\022\014\n\004name\030\001 \002(\tB-\n\033org.apache" + - ".slider.api.protoB\010Messages\210\001\001\240\001\001" + " \001(\005\022\036\n\026isAARequestOutstanding\030\023 \001(\010\"\210\002\n", + "\031ContainerInformationProto\022\023\n\013containerI" + + "d\030\001 \001(\t\022\021\n\tcomponent\030\002 \001(\t\022\020\n\010released\030\003" + + " \001(\010\022\r\n\005state\030\004 \001(\005\022\020\n\010exitCode\030\005 \001(\005\022\023\n" + + "\013diagnostics\030\006 \001(\t\022\022\n\ncreateTime\030\007 \001(\003\022\021" + + "\n\tstartTime\030\010 \001(\003\022\016\n\006output\030\t \003(\t\022\014\n\004hos" + + "t\030\n \001(\t\022\017\n\007hostURL\030\013 \001(\t\022\021\n\tplacement\030\014 " + + "\001(\t\022\022\n\nappVersion\030\r \001(\t\"N\n\024PingInformati" + + "onProto\022\014\n\004text\030\001 \001(\t\022\014\n\004verb\030\002 \001(\t\022\014\n\004b" + + "ody\030\003 \001(\t\022\014\n\004time\030\004 \001(\003\"\325\001\n\031NodeEntryInf" + + "ormationProto\022\020\n\010priority\030\001 \002(\005\022\021\n\treque", + "sted\030\002 \002(\005\022\020\n\010starting\030\003 \002(\005\022\023\n\013startFai" + + "led\030\004 \002(\005\022\016\n\006failed\030\005 \002(\005\022\026\n\016failedRecen" + + "tly\030\006 \002(\005\022\021\n\tpreempted\030\007 \002(\005\022\014\n\004live\030\010 \002" + + "(\005\022\021\n\treleasing\030\t \002(\005\022\020\n\010lastUsed\030\n \002(\003\"" + + "\334\001\n\024NodeInformationProto\022\020\n\010hostname\030\001 \002" + + "(\t\022\r\n\005state\030\002 \002(\t\022\023\n\013httpAddress\030\003 \002(\t\022\020" + + "\n\010rackName\030\004 \002(\t\022\016\n\006labels\030\005 \002(\t\022\024\n\014heal" + + "thReport\030\006 \002(\t\022\023\n\013lastUpdated\030\007 \002(\003\022A\n\007e" + + "ntries\030\010 \003(\01320.org.apache.slider.api.Nod" + + "eEntryInformationProto\"\026\n\024GetModelReques", + "tProto\"\035\n\033GetModelDesiredRequestProto\"$\n" + + "\"GetModelDesiredAppconfRequestProto\"&\n$G" + + "etModelDesiredResourcesRequestProto\"%\n#G" + + "etModelResolvedAppconfRequestProto\"\'\n%Ge" + + "tModelResolvedResourcesRequestProto\"#\n!G" + + "etModelLiveResourcesRequestProto\"\037\n\035GetL" + + "iveContainersRequestProto\"u\n\036GetLiveCont" + + "ainersResponseProto\022\r\n\005names\030\001 \003(\t\022D\n\nco" + + "ntainers\030\002 \003(\01320.org.apache.slider.api.C" + + "ontainerInformationProto\"3\n\034GetLiveConta", + "inerRequestProto\022\023\n\013containerId\030\001 \002(\t\"\037\n" + + "\035GetLiveComponentsRequestProto\"u\n\036GetLiv" + + "eComponentsResponseProto\022\r\n\005names\030\001 \003(\t\022" + + "D\n\ncomponents\030\002 \003(\01320.org.apache.slider." + + "api.ComponentInformationProto\",\n\034GetLive" + + "ComponentRequestProto\022\014\n\004name\030\001 \002(\t\"$\n\"G" + + "etApplicationLivenessRequestProto\"\023\n\021Emp" + + "tyPayloadProto\" \n\020WrappedJsonProto\022\014\n\004js" + + "on\030\001 \002(\t\"h\n\037GetCertificateStoreRequestPr" + + "oto\022\020\n\010hostname\030\001 \001(\t\022\023\n\013requesterId\030\002 \002", + "(\t\022\020\n\010password\030\003 \002(\t\022\014\n\004type\030\004 \002(\t\"1\n Ge" + + "tCertificateStoreResponseProto\022\r\n\005store\030" + + "\001 \002(\014\"\032\n\030GetLiveNodesRequestProto\"f\n\031Get" + + "LiveNodesResponseProto\022\r\n\005names\030\001 \003(\t\022:\n" + + "\005nodes\030\002 \003(\0132+.org.apache.slider.api.Nod" + + "eInformationProto\"\'\n\027GetLiveNodeRequestP" + + "roto\022\014\n\004name\030\001 \002(\tB-\n\033org.apache.slider." + + "api.protoB\010Messages\210\001\001\240\001\001" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -34236,7 +34327,7 @@ public final class Messages { internal_static_org_apache_slider_api_ComponentInformationProto_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_org_apache_slider_api_ComponentInformationProto_descriptor, - new java.lang.String[] { "Name", "Priority", "Desired", "Actual", "Releasing", "Requested", "Failed", "Started", "StartFailed", "Completed", "TotalRequested", "FailureMessage", "PlacementPolicy", "Containers", "FailedRecently", "NodeFailed", "Preempted", "PendingAntiAffineRequestCount", }); + new java.lang.String[] { "Name", "Priority", "Desired", "Actual", "Releasing", "Requested", "Failed", "Started", "StartFailed", "Completed", "TotalRequested", "FailureMessage", "PlacementPolicy", "Containers", "FailedRecently", "NodeFailed", "Preempted", "PendingAntiAffineRequestCount", "IsAARequestOutstanding", }); internal_static_org_apache_slider_api_ContainerInformationProto_descriptor = getDescriptor().getMessageTypes().get(25); internal_static_org_apache_slider_api_ContainerInformationProto_fieldAccessorTable = new http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java index 85a8358..8dcf65f 100644 --- a/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java +++ b/slider-core/src/main/java/org/apache/slider/api/proto/RestTypeMarshalling.java @@ -86,7 +86,12 @@ public class RestTypeMarshalling { if (wire.hasFailureMessage()) { info.failureMessage = wire.getFailureMessage(); } - info.pendingAntiAffineRequestCount = wire.getPendingAntiAffineRequestCount(); + if (wire.hasPendingAntiAffineRequestCount()) { + info.pendingAntiAffineRequestCount = wire.getPendingAntiAffineRequestCount(); + } + if (wire.hasIsAARequestOutstanding()) { + info.isAARequestOutstanding = wire.getIsAARequestOutstanding(); + } return info; } @@ -137,6 +142,7 @@ public class RestTypeMarshalling { builder.addAllContainers(info.containers); } builder.setPendingAntiAffineRequestCount(info.pendingAntiAffineRequestCount); + builder.setIsAARequestOutstanding(info.isAARequestOutstanding); return builder.build(); } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java index 4dd2cb7..9879d05 100644 --- a/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java +++ b/slider-core/src/main/java/org/apache/slider/api/types/ApplicationLivenessInformation.java @@ -30,9 +30,15 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; @JsonIgnoreProperties(ignoreUnknown = true) @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) public class ApplicationLivenessInformation { + /** flag set if the cluster is at size */ public boolean allRequestsSatisfied; + + /** number of outstanding requests: those needed to satisfy */ public int requestsOutstanding; + /** number of requests submitted to YARN */ + public int activeRequests; + @Override public String toString() { final StringBuilder sb = http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java b/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java index 9d8a4ee..3771988 100644 --- a/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java +++ b/slider-core/src/main/java/org/apache/slider/api/types/ComponentInformation.java @@ -53,6 +53,7 @@ public class ComponentInformation { public int failed, started, startFailed, completed, totalRequested; public int nodeFailed, failedRecently, preempted; public int pendingAntiAffineRequestCount; + public boolean isAARequestOutstanding; public String failureMessage; public List<String> containers; @@ -84,12 +85,13 @@ public class ComponentInformation { new StringBuilder("ComponentInformation{"); sb.append(", name='").append(name).append('\''); sb.append(", actual=").append(actual); - sb.append(", anti-affine pending").append(pendingAntiAffineRequestCount); sb.append(", completed=").append(completed); sb.append(", desired=").append(desired); sb.append(", failed=").append(failed); sb.append(", failureMessage='").append(failureMessage).append('\''); sb.append(", placementPolicy=").append(placementPolicy); + sb.append(", isAARequestOutstanding=").append(isAARequestOutstanding); + sb.append(", pendingAntiAffineRequestCount").append(pendingAntiAffineRequestCount); sb.append(", priority=").append(priority); sb.append(", releasing=").append(releasing); sb.append(", requested=").append(requested); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java b/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java new file mode 100644 index 0000000..c926600 --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/api/types/RoleStatistics.java @@ -0,0 +1,66 @@ +/* + * 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.slider.api.types; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +/** + * Simple role statistics for state views; can be generated by RoleStatus + * instances, and aggregated for summary information. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class RoleStatistics { + public long activeAA = 0L; + public long actual = 0L; + public long completed = 0L; + public long desired = 0L; + public long failed = 0L; + public long failedRecently = 0L; + public long limitsExceeded = 0L; + public long nodeFailed = 0L; + public long preempted = 0L; + public long releasing = 0L; + public long requested = 0L; + public long started = 0L; + public long startFailed = 0L; + public long totalRequested = 0L; + + /** + * Add another statistics instance + * @param that the other value + * @return this entry + */ + public RoleStatistics add(final RoleStatistics that) { + activeAA += that.activeAA; + actual += that.actual; + completed += that.completed; + desired += that.desired; + failed += that.failed; + failedRecently += that.failedRecently; + limitsExceeded += that.limitsExceeded; + nodeFailed += that.nodeFailed; + preempted += that.preempted; + releasing += that.releasing; + requested += that.requested; + started += that.started; + startFailed += that.totalRequested; + totalRequested += that.totalRequested; + return this; + } +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java b/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java index ce2817a..54c60d1 100644 --- a/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java +++ b/slider-core/src/main/java/org/apache/slider/client/rest/SliderApplicationApiRestClient.java @@ -25,6 +25,7 @@ import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.GenericType; import com.sun.jersey.api.client.UniformInterfaceException; import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.LoggingFilter; import com.sun.jersey.api.representation.Form; import org.apache.commons.lang.StringUtils; import org.apache.slider.api.types.ApplicationLivenessInformation; @@ -68,6 +69,19 @@ public class SliderApplicationApiRestClient extends BaseRestClient this.appResource = appResource; } + /** + * Create an instance + * @param jerseyClient jersey client for operations + * @param appmaster URL of appmaster/proxy to AM + */ + public SliderApplicationApiRestClient(Client jerseyClient, String appmaster) { + super(jerseyClient); + WebResource amResource = jerseyClient.resource(appmaster); + amResource.type(MediaType.APPLICATION_JSON); + this.appResource = amResource.path(SLIDER_PATH_APPLICATION); + } + + @Override public String toString() { final StringBuilder sb = http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java index 1aa9088..7446e82 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/ActionKillContainer.java @@ -77,7 +77,7 @@ public class ActionKillContainer extends AsyncAction { public void execute(SliderAppMaster appMaster, QueueAccess queueService, AppState appState) throws Exception { - List<AbstractRMOperation> opsList = new LinkedList<AbstractRMOperation>(); + List<AbstractRMOperation> opsList = new LinkedList<>(); ContainerReleaseOperation release = new ContainerReleaseOperation(containerId); opsList.add(release); //now apply the operations http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java index 146dea4..34acade 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/actions/QueueService.java @@ -58,20 +58,20 @@ implements Runnable, QueueAccess { * Immediate actions. */ public final BlockingDeque<AsyncAction> actionQueue = - new LinkedBlockingDeque<AsyncAction>(); + new LinkedBlockingDeque<>(); /** * Actions to be scheduled in the future */ - public final DelayQueue<AsyncAction> scheduledActions = new DelayQueue<AsyncAction>(); + public final DelayQueue<AsyncAction> scheduledActions = new DelayQueue<>(); /** * Map of renewing actions by name ... this is to allow them to * be cancelled by name */ private final Map<String, RenewingAction<? extends AsyncAction>> renewingActions - = new ConcurrentHashMap<String, RenewingAction<? extends AsyncAction>>(); - + = new ConcurrentHashMap<>(); + /** * Create a queue instance with a single thread executor */ http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java index 4152a89..2da5d36 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/AppState.java @@ -46,6 +46,7 @@ import org.apache.slider.api.RoleKeys; import org.apache.slider.api.StatusKeys; import org.apache.slider.api.types.ApplicationLivenessInformation; import org.apache.slider.api.types.ComponentInformation; +import org.apache.slider.api.types.RoleStatistics; import org.apache.slider.common.SliderExitCodes; import org.apache.slider.common.SliderKeys; import org.apache.slider.common.tools.ConfigHelper; @@ -250,12 +251,6 @@ public class AppState { private final LongGauge outstandingContainerRequests = new LongGauge(); /** - * Track the number of pending (not yet active) requests - * Important: this does not include AA requests which are yet to be issued. - */ - private final LongGauge pendingAARequests = new LongGauge(); - - /** * Map of requested nodes. This records the command used to start it, * resources, etc. When container started callback is received, * the node is promoted from here to the containerMap @@ -382,10 +377,6 @@ public class AppState { startFailedContainerCount.inc(); } - public long getTotalOutstandingRequests() { - return outstandingContainerRequests.get() + - pendingAARequests.get(); - } public AtomicInteger getCompletionOfNodeNotInLiveListEvent() { return completionOfNodeNotInLiveListEvent; } @@ -1777,9 +1768,11 @@ public class AppState { */ public ApplicationLivenessInformation getApplicationLivenessInformation() { ApplicationLivenessInformation li = new ApplicationLivenessInformation(); - int outstanding = outstandingContainerRequests.intValue(); + RoleStatistics stats = getRoleStatistics(); + int outstanding = (int)(stats.desired - stats.actual); li.requestsOutstanding = outstanding; li.allRequestsSatisfied = outstanding <= 0; + li.activeRequests = (int)stats.requested; return li; } @@ -1808,6 +1801,18 @@ public class AppState { } /** + * Get the aggregate statistics across all roles + * @return role statistics + */ + public RoleStatistics getRoleStatistics() { + RoleStatistics stats = new RoleStatistics(); + for (RoleStatus role : getRoleStatusMap().values()) { + stats.add(role.getStatistics()); + } + return stats; + } + + /** * Get a snapshot of component information. * <p> * This does <i>not</i> include any container list, which @@ -1817,8 +1822,7 @@ public class AppState { public Map<String, ComponentInformation> getComponentInfoSnapshot() { Map<Integer, RoleStatus> statusMap = getRoleStatusMap(); - Map<String, ComponentInformation> results = - new HashMap<String, ComponentInformation>( + Map<String, ComponentInformation> results = new HashMap<>( statusMap.size()); for (RoleStatus status : statusMap.values()) { @@ -2372,9 +2376,10 @@ public class AppState { sb.append(", startFailedContainerCount=").append(startFailedContainerCount); sb.append(", surplusContainers=").append(surplusContainers); sb.append(", failedContainerCount=").append(failedContainerCount); - sb.append(", outstandingContainerRequests=") + sb.append(", outstanding non-AA Container Requests=") .append(outstandingContainerRequests); sb.append('}'); return sb.toString(); } + } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java index 82b2f2a..1d96a1c 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/ProviderAppState.java @@ -26,6 +26,7 @@ import org.apache.slider.api.ClusterNode; import org.apache.slider.api.types.ApplicationLivenessInformation; import org.apache.slider.api.types.ComponentInformation; import org.apache.slider.api.types.NodeInformation; +import org.apache.slider.api.types.RoleStatistics; import org.apache.slider.core.conf.AggregateConf; import org.apache.slider.core.conf.ConfTreeOperations; import org.apache.slider.core.exceptions.NoSuchNodeException; @@ -298,4 +299,8 @@ public class ProviderAppState implements StateAccessForProviders { return appState.getRoleHistory().getNodeInformation(hostname); } + @Override + public RoleStatistics getRoleStatistics() { + return appState.getRoleStatistics(); + } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleStatus.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleStatus.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleStatus.java index b530d18..0fc3dc2 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleStatus.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/RoleStatus.java @@ -21,6 +21,7 @@ package org.apache.slider.server.appmaster.state; import com.google.common.base.Preconditions; import org.apache.hadoop.yarn.api.records.Resource; import org.apache.slider.api.types.ComponentInformation; +import org.apache.slider.api.types.RoleStatistics; import org.apache.slider.providers.PlacementPolicy; import org.apache.slider.providers.ProviderRole; import org.apache.slider.server.appmaster.management.LongGauge; @@ -441,6 +442,7 @@ public final class RoleStatus implements Cloneable { info.nodeFailed = nodeFailed.intValue(); info.preempted = preempted.intValue(); info.pendingAntiAffineRequestCount = pendingAntiAffineRequests.intValue(); + info.isAARequestOutstanding = isAARequestOutstanding(); return info; } @@ -494,4 +496,22 @@ public final class RoleStatus implements Cloneable { resource.setVirtualCores(resourceRequirements.getVirtualCores()); return resource; } + + public synchronized RoleStatistics getStatistics() { + RoleStatistics stats = new RoleStatistics(); + stats.activeAA = isAARequestOutstanding() ? 1: 0; + stats.actual = actual.get(); + stats.desired = desired.get(); + stats.failed = failed.get(); + stats.limitsExceeded = limitsExceeded.get(); + stats.nodeFailed = nodeFailed.get(); + stats.preempted = preempted.get(); + stats.releasing = releasing.get(); + stats.requested = requested.get(); + stats.started = started.get(); + stats.startFailed = startFailed.get(); + stats.totalRequested = totalRequested.get(); + return stats; + } + } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java index 2fc00b2..ad91183 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/state/StateAccessForProviders.java @@ -27,6 +27,7 @@ import org.apache.slider.api.StatusKeys; import org.apache.slider.api.types.ApplicationLivenessInformation; import org.apache.slider.api.types.ComponentInformation; import org.apache.slider.api.types.NodeInformation; +import org.apache.slider.api.types.RoleStatistics; import org.apache.slider.core.conf.AggregateConf; import org.apache.slider.core.conf.ConfTreeOperations; import org.apache.slider.core.exceptions.NoSuchNodeException; @@ -303,4 +304,10 @@ public interface StateAccessForProviders { * @return the information, or null if there is no information held. */ NodeInformation getNodeInformation(String hostname); + + /** + * Get the aggregate statistics across all roles + * @return role statistics + */ + RoleStatistics getRoleStatistics(); } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/AbstractSliderResource.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/AbstractSliderResource.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/AbstractSliderResource.java index cfddb12..7ff83b6 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/AbstractSliderResource.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/AbstractSliderResource.java @@ -45,12 +45,11 @@ public abstract class AbstractSliderResource { protected final WebAppApi slider; protected final MetricsAndMonitoring metricsAndMonitoring; - public AbstractSliderResource(WebAppApi slider) { + protected AbstractSliderResource(WebAppApi slider) { this.slider = slider; metricsAndMonitoring = slider.getMetricsAndMonitoring(); } - /** * Generate a redirect to the WASL * @param request to base the URL on @@ -105,6 +104,7 @@ public abstract class AbstractSliderResource { protected void mark(String verb, String path) { metricsAndMonitoring.markMeterAndCounter(verb + "-" + path); } + /** * Mark an GET operation on a path * @param verb HTTP Verb @@ -129,6 +129,7 @@ public abstract class AbstractSliderResource { protected void markGet(String path, String subpath) { mark("GET", path, subpath); } + /** * Mark a GET operation on a path * @param path path relative to slider API @@ -136,6 +137,7 @@ public abstract class AbstractSliderResource { protected void markPost(String path, String subpath) { mark("POST", path, subpath); } + /** * Mark a GET operation on a path * @param path path relative to slider API @@ -143,6 +145,7 @@ public abstract class AbstractSliderResource { protected void markPut(String path, String subpath) { mark("PUT", path, subpath); } + /** * Mark a GET operation on a path * @param path path relative to slider API http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java index 424107c..b90eb62 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/rest/RestPaths.java @@ -148,4 +148,15 @@ public class RestPaths { public static final String ACTION = "/action"; public static final String ACTION_PING = ACTION + "/ping"; public static final String ACTION_STOP = ACTION + "/stop"; + + /** + * Path to a role + * @param name role name + * @return a path to it + */ + public String pathToRole(String name) { + + // ws/v1/slider/application/live/components/$name + return SLIDER_PATH_APPLICATION + LIVE_COMPONENTS + "/" + name; + } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ClusterSpecificationBlock.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ClusterSpecificationBlock.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ClusterSpecificationBlock.java index 137c476..2f02f27 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ClusterSpecificationBlock.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ClusterSpecificationBlock.java @@ -18,23 +18,16 @@ package org.apache.slider.server.appmaster.web.view; import com.google.inject.Inject; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; -import org.apache.hadoop.yarn.webapp.view.HtmlBlock; -import org.apache.slider.server.appmaster.state.StateAccessForProviders; import org.apache.slider.server.appmaster.web.WebAppApi; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * */ -public class ClusterSpecificationBlock extends HtmlBlock { - private static final Logger log = LoggerFactory.getLogger(ClusterSpecificationBlock.class); - - private StateAccessForProviders appState; +public class ClusterSpecificationBlock extends SliderHamletBlock { @Inject public ClusterSpecificationBlock(WebAppApi slider) { - this.appState = slider.getAppState(); + super(slider); } @Override @@ -50,7 +43,7 @@ public class ClusterSpecificationBlock extends HtmlBlock { pre(). _(getJson())._()._(); } - + /** * Get the JSON, catching any exceptions and returning error text instead * @return http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ContainerStatsBlock.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ContainerStatsBlock.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ContainerStatsBlock.java index 65d8b39..56285c2 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ContainerStatsBlock.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/ContainerStatsBlock.java @@ -26,12 +26,10 @@ import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TABLE; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TBODY; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.TR; -import org.apache.hadoop.yarn.webapp.view.HtmlBlock; import org.apache.slider.api.ClusterDescription; import org.apache.slider.api.ClusterNode; import org.apache.slider.api.types.ComponentInformation; import org.apache.slider.server.appmaster.state.RoleInstance; -import org.apache.slider.server.appmaster.state.StateAccessForProviders; import org.apache.slider.server.appmaster.web.WebAppApi; import java.io.Serializable; @@ -45,7 +43,7 @@ import java.util.Map.Entry; /** * */ -public class ContainerStatsBlock extends HtmlBlock { +public class ContainerStatsBlock extends SliderHamletBlock { private static final String EVEN = "even", ODD = "odd", BOLD = "bold", SCHEME = "http://", PATH = "/node/container/"; @@ -54,11 +52,9 @@ public class ContainerStatsBlock extends HtmlBlock { protected static final Function<Entry<String,Long>,Entry<TableContent,Long>> stringLongPairFunc = toTableContentFunction(); protected static final Function<Entry<String,String>,Entry<TableContent,String>> stringStringPairFunc = toTableContentFunction(); - private WebAppApi slider; - @Inject public ContainerStatsBlock(WebAppApi slider) { - this.slider = slider; + super(slider); } /** @@ -93,7 +89,6 @@ public class ContainerStatsBlock extends HtmlBlock { @Override protected void render(Block html) { - StateAccessForProviders appState = slider.getAppState(); final Map<String,RoleInstance> containerInstances = getContainerInstances( appState.cloneOwnedContainerList()); http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java index 41e1c01..8152f27 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/IndexBlock.java @@ -21,28 +21,28 @@ import com.google.inject.Inject; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.DIV; import org.apache.hadoop.yarn.webapp.hamlet.Hamlet.UL; -import org.apache.hadoop.yarn.webapp.view.HtmlBlock; import org.apache.slider.api.ClusterDescription; import org.apache.slider.api.StatusKeys; import org.apache.slider.api.types.ApplicationLivenessInformation; +import org.apache.slider.api.types.RoleStatistics; import org.apache.slider.common.tools.SliderUtils; import org.apache.slider.providers.ProviderService; import org.apache.slider.server.appmaster.state.RoleStatus; -import org.apache.slider.server.appmaster.state.StateAccessForProviders; import org.apache.slider.server.appmaster.web.WebAppApi; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.Map.Entry; +import static org.apache.slider.server.appmaster.web.rest.RestPaths.LIVE_COMPONENTS; + /** * */ -public class IndexBlock extends HtmlBlock { +public class IndexBlock extends SliderHamletBlock { private static final Logger log = LoggerFactory.getLogger(IndexBlock.class); /** @@ -52,13 +52,9 @@ public class IndexBlock extends HtmlBlock { */ public static final String ALL_CONTAINERS_ALLOCATED = "all containers allocated"; - private StateAccessForProviders appView; - private ProviderService providerService; - @Inject public IndexBlock(WebAppApi slider) { - this.appView = slider.getAppState(); - this.providerService = slider.getProviderService(); + super(slider); } @Override @@ -71,7 +67,8 @@ public class IndexBlock extends HtmlBlock { // An extra method to make testing easier since you can't make an instance of Block @VisibleForTesting protected void doIndex(Hamlet html, String providerName) { - ClusterDescription clusterStatus = appView.getClusterStatus(); + ClusterDescription clusterStatus = appState.getClusterStatus(); + RoleStatistics roleStats = appState.getRoleStatistics(); String name = clusterStatus.name; if (name != null && (name.startsWith(" ") || name.endsWith(" "))) { name = "'" + name + "'"; @@ -81,9 +78,8 @@ public class IndexBlock extends HtmlBlock { "Application: " + name); ApplicationLivenessInformation liveness = - appView.getApplicationLivenessInformation(); - String livestatus = - liveness.allRequestsSatisfied + appState.getApplicationLivenessInformation(); + String livestatus = liveness.allRequestsSatisfied ? ALL_CONTAINERS_ALLOCATED : String.format("Awaiting %d containers", liveness.requestsOutstanding); Hamlet.TABLE<DIV<Hamlet>> table1 = div.table(); @@ -93,7 +89,7 @@ public class IndexBlock extends HtmlBlock { ._(); table1.tr() .td("Total number of containers") - .td(Integer.toString(appView.getNumOwnedContainers())) + .td(Integer.toString(appState.getNumOwnedContainers())) ._(); table1.tr() .td("Create time: ") @@ -121,26 +117,40 @@ public class IndexBlock extends HtmlBlock { html.div("container_instances").h3("Component Instances"); Hamlet.TABLE<DIV<Hamlet>> table = div.table(); - table.tr() - .td("Component") - .td("Desired") - .td("Actual") - .td("Outstanding Requests") - .td("Failed") - .td("Failed to start") - ._(); - - List<RoleStatus> roleStatuses = appView.cloneRoleStatusList(); + Hamlet.TR<Hamlet.THEAD<Hamlet.TABLE<DIV<Hamlet>>>> tr = table.thead().tr(); + trb(tr, "Component"); + trb(tr, "Desired"); + trb(tr, "Actual"); + trb(tr, "Outstanding Requests"); + trb(tr, "Failed"); + trb(tr, "Failed to start"); + trb(tr, "Placement"); + tr._()._(); + + List<RoleStatus> roleStatuses = appState.cloneRoleStatusList(); Collections.sort(roleStatuses, new RoleStatus.CompareByName()); for (RoleStatus status : roleStatuses) { + String roleName = status.getName(); + String nameUrl = apiPath(LIVE_COMPONENTS) + "/" + roleName; + String aatext; + if (status.isAntiAffinePlacement()) { + int outstanding = status.isAARequestOutstanding() ? 1: 0; + int pending = (int)status.getPendingAntiAffineRequests(); + aatext = String.format("Anti-affine: %d outstanding %s, %d pending %s", + outstanding, plural(outstanding, "request"), + pending, plural(pending, "request")); + } else { + aatext = ""; + } table.tr() - .td(status.getName()) - .td(String.format("%d", status.getDesired())) - .td(String.format("%d", status.getActual())) - .td(String.format("%d", status.getRequested())) - .td(String.format("%d", status.getFailed())) - .td(String.format("%d", status.getStartFailed())) - ._(); + .td().a(nameUrl, roleName)._() + .td(String.format("%d", status.getDesired())) + .td(String.format("%d", status.getActual())) + .td(String.format("%d", status.getRequested())) + .td(String.format("%d", status.getFailed())) + .td(String.format("%d", status.getStartFailed())) + .td(aatext) + ._(); } table._()._(); @@ -155,12 +165,21 @@ public class IndexBlock extends HtmlBlock { ul._()._(); } + private String plural(int n, String text) { + return n == 1 ? text : (text + "s"); + } + + private void trb(Hamlet.TR<Hamlet.THEAD<Hamlet.TABLE<DIV<Hamlet>>>> tr, + String text) { + tr.td().b(text)._(); + } + private String getProviderName() { return providerService.getHumanName(); } private String getInfoAvoidingNulls(String key) { - String createTime = appView.getClusterStatus().getInfo(key); + String createTime = appState.getClusterStatus().getInfo(key); return null == createTime ? "N/A" : createTime; } @@ -183,4 +202,5 @@ public class IndexBlock extends HtmlBlock { } } + } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java index b2327ba..515b1a3 100644 --- a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/NavBlock.java @@ -16,16 +16,21 @@ */ package org.apache.slider.server.appmaster.web.view; -import org.apache.hadoop.yarn.webapp.view.HtmlBlock; +import com.google.inject.Inject; +import org.apache.slider.server.appmaster.web.WebAppApi; + import static org.apache.slider.server.appmaster.web.SliderAMWebApp.*; import static org.apache.slider.server.appmaster.web.rest.RestPaths.*; -import static org.apache.hadoop.yarn.util.StringHelper.ujoin; - /** * */ -public class NavBlock extends HtmlBlock { +public class NavBlock extends SliderHamletBlock { + + @Inject + public NavBlock(WebAppApi slider) { + super(slider); + } @Override protected void render(Block html) { @@ -48,20 +53,11 @@ public class NavBlock extends HtmlBlock { li().a(apiPath(LIVE_RESOURCES), "Resources")._(). li().a(apiPath(LIVE_COMPONENTS), "Components")._(). li().a(apiPath(LIVE_CONTAINERS), "Containers")._(). + li().a(apiPath(LIVE_NODES), "Nodes")._(). + li().a(apiPath(LIVE_STATISTICS), "Statistics")._(). li().a(apiPath(LIVE_LIVENESS), "Liveness")._() ._() ._(); } - private String rootPath(String absolutePath) { - return root_url(absolutePath); - } - - private String relPath(String... args) { - return ujoin(this.prefix(), args); - } - private String apiPath(String api) { - return root_url(SLIDER_PATH_APPLICATION, api); - } - } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/SliderHamletBlock.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/SliderHamletBlock.java b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/SliderHamletBlock.java new file mode 100644 index 0000000..82d7c8f --- /dev/null +++ b/slider-core/src/main/java/org/apache/slider/server/appmaster/web/view/SliderHamletBlock.java @@ -0,0 +1,56 @@ +/* + * 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.slider.server.appmaster.web.view; + +import org.apache.hadoop.yarn.webapp.view.HtmlBlock; +import org.apache.slider.providers.ProviderService; +import org.apache.slider.server.appmaster.state.StateAccessForProviders; +import org.apache.slider.server.appmaster.web.WebAppApi; +import org.apache.slider.server.appmaster.web.rest.RestPaths; + +import static org.apache.hadoop.yarn.util.StringHelper.ujoin; +import static org.apache.slider.server.appmaster.web.rest.RestPaths.SLIDER_PATH_APPLICATION; + +/** + * Anything we want to share across slider hamlet blocks + */ +public abstract class SliderHamletBlock extends HtmlBlock { + + protected final StateAccessForProviders appState; + protected final ProviderService providerService; + protected final RestPaths restPaths = new RestPaths(); + + public SliderHamletBlock(WebAppApi slider) { + this.appState = slider.getAppState(); + this.providerService = slider.getProviderService(); + } + + protected String rootPath(String absolutePath) { + return root_url(absolutePath); + } + + protected String relPath(String... args) { + return ujoin(this.prefix(), args); + } + + protected String apiPath(String api) { + return root_url(SLIDER_PATH_APPLICATION, api); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/main/proto/SliderClusterMessages.proto ---------------------------------------------------------------------- diff --git a/slider-core/src/main/proto/SliderClusterMessages.proto b/slider-core/src/main/proto/SliderClusterMessages.proto index 50c10e4..2836454 100644 --- a/slider-core/src/main/proto/SliderClusterMessages.proto +++ b/slider-core/src/main/proto/SliderClusterMessages.proto @@ -258,6 +258,7 @@ message ComponentInformationProto { optional int32 nodeFailed = 16; optional int32 preempted = 17; optional int32 pendingAntiAffineRequestCount = 18; + optional bool isAARequestOutstanding = 19; } /* http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/agent/AgentMiniClusterTestBase.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/AgentMiniClusterTestBase.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/AgentMiniClusterTestBase.groovy index a7bc0a3..41bb7b1 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/AgentMiniClusterTestBase.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/AgentMiniClusterTestBase.groovy @@ -27,15 +27,13 @@ import org.apache.commons.io.FileUtils import org.apache.slider.client.SliderClient import org.apache.slider.common.SliderXMLConfKeysForTesting import org.apache.slider.common.params.Arguments -import org.apache.slider.common.tools.SliderUtils import org.apache.slider.core.main.ServiceLauncher import org.apache.slider.providers.agent.AgentKeys +import org.apache.slider.test.KeysForTests import org.apache.slider.test.YarnZKMiniClusterTestBase import org.junit.AfterClass import org.junit.BeforeClass import org.junit.rules.TemporaryFolder -import org.slf4j.Logger -import org.slf4j.LoggerFactory /** * test base for agent clusters @@ -43,8 +41,7 @@ import org.slf4j.LoggerFactory @CompileStatic @Slf4j public abstract class AgentMiniClusterTestBase -extends YarnZKMiniClusterTestBase { - private static Logger LOG = LoggerFactory.getLogger(AgentMiniClusterTestBase) +extends YarnZKMiniClusterTestBase implements KeysForTests { protected static File agentConf protected static File agentDef protected static Map<String, String> agentDefOptions http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy index 7cb1837..0bd1df0 100644 --- a/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/agent/rest/TestStandaloneREST.groovy @@ -32,6 +32,7 @@ import org.apache.slider.common.params.Arguments import org.apache.slider.core.main.ServiceLauncher import org.apache.slider.core.restclient.HttpOperationResponse import org.apache.slider.server.appmaster.rpc.RpcBinder +import org.apache.slider.test.KeysForTests import org.junit.Test import static org.apache.slider.server.appmaster.management.MetricsKeys.* @@ -39,7 +40,7 @@ import static org.apache.slider.server.appmaster.web.rest.RestPaths.* @CompileStatic @Slf4j -class TestStandaloneREST extends AgentMiniClusterTestBase { +class TestStandaloneREST extends AgentMiniClusterTestBase { @Test public void testStandaloneREST() throws Throwable { @@ -88,7 +89,7 @@ class TestStandaloneREST extends AgentMiniClusterTestBase { // this should be from AM launch itself awaitGaugeValue( appendToURL(proxyAM, SYSTEM_METRICS_JSON), - "org.apache.slider.server.appmaster.state.RoleHistory.nodes-updated.flag", + NODES_UPDATED_FLAG_METRIC, 1, WEB_STARTUP_TIME * 2, 500) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/providers/agent/AgentTestBase.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/providers/agent/AgentTestBase.groovy b/slider-core/src/test/groovy/org/apache/slider/providers/agent/AgentTestBase.groovy index 0e5cd00..e5951ac 100644 --- a/slider-core/src/test/groovy/org/apache/slider/providers/agent/AgentTestBase.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/providers/agent/AgentTestBase.groovy @@ -136,6 +136,7 @@ public abstract class AgentTestBase extends YarnZKMiniClusterTestBase { boolean create, boolean blockUntilRunning) { + YarnConfiguration conf = testConfiguration def clusterOps = [:] return createOrBuildCluster( http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/providers/agent/DemoAgentAAEcho.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/providers/agent/DemoAgentAAEcho.groovy b/slider-core/src/test/groovy/org/apache/slider/providers/agent/DemoAgentAAEcho.groovy index 6f21006..8606417 100644 --- a/slider-core/src/test/groovy/org/apache/slider/providers/agent/DemoAgentAAEcho.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/providers/agent/DemoAgentAAEcho.groovy @@ -18,7 +18,6 @@ package org.apache.slider.providers.agent -import org.apache.hadoop.yarn.api.records.ApplicationReport import org.apache.slider.client.SliderClient /** @@ -37,7 +36,12 @@ class DemoAgentAAEcho extends TestAgentAAEcho { def applicationReport = sliderClient.applicationReport def url = applicationReport.trackingUrl // spin repeating the URl in the logs so YARN chatter doesn't lose it - 1..5.each { + describe("Web UI is at $url") + + // run the superclass rest tests + // queryRestAPI(sliderClient, roles) + + 5.times { describe("Web UI is at $url") sleep(60 *1000) } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentAAEcho.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentAAEcho.groovy b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentAAEcho.groovy index 3835330..f2f38e0 100644 --- a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentAAEcho.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentAAEcho.groovy @@ -20,8 +20,11 @@ package org.apache.slider.providers.agent import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import org.apache.slider.agent.rest.RestAPIClientTestDelegates import org.apache.slider.api.ResourceKeys +import org.apache.slider.api.types.ComponentInformation import org.apache.slider.client.SliderClient +import org.apache.slider.client.rest.SliderApplicationApiRestClient import org.apache.slider.common.SliderXmlConfKeys import org.apache.slider.core.main.ServiceLauncher import org.apache.slider.providers.PlacementPolicy @@ -29,6 +32,8 @@ import org.junit.Test import static org.apache.slider.common.params.Arguments.* import static org.apache.slider.providers.agent.AgentKeys.* +import static org.apache.slider.server.appmaster.management.MetricsKeys.METRICS_LOGGING_ENABLED +import static org.apache.slider.server.appmaster.management.MetricsKeys.METRICS_LOGGING_LOG_INTERVAL /** * Tests an echo command @@ -38,10 +43,12 @@ import static org.apache.slider.providers.agent.AgentKeys.* class TestAgentAAEcho extends TestAgentEcho { @Test - public void testEchoOperation() throws Throwable { + public void testAgentEcho() throws Throwable { assumeValidServerEnv() - - String clustername = createMiniCluster("", + def conf = configuration + conf.setBoolean(METRICS_LOGGING_ENABLED, true) + conf.setInt(METRICS_LOGGING_LOG_INTERVAL, 1) + String clustername = createMiniCluster("testaaecho", configuration, 1, 1, @@ -73,7 +80,6 @@ class TestAgentAAEcho extends TestAgentEcho { true, true, true) postLaunchActions(launcher.service, clustername, echo, roles) - } /** @@ -105,6 +111,7 @@ class TestAgentAAEcho extends TestAgentEcho { //expect the role count to be the same waitForRoleCount(sliderClient, onlyOneEcho, 1000) + queryRestAPI(sliderClient, roles) // flex size // while running, ask for many more, expect them to still be outstanding sleep(5000) @@ -117,4 +124,18 @@ class TestAgentAAEcho extends TestAgentEcho { waitForRoleCount(sliderClient, onlyOneEcho, 1000) } + + protected void queryRestAPI(SliderClient sliderClient, Map<String, Integer> roles) { + initHttpTestSupport(sliderClient.config) + def applicationReport = sliderClient.applicationReport + def proxyAM = applicationReport.trackingUrl + GET(proxyAM) + describe "Proxy SliderRestClient Tests" + SliderApplicationApiRestClient restAPI = + new SliderApplicationApiRestClient(createUGIJerseyClient(), proxyAM) + def echoInfo = restAPI.getComponent(ECHO) + assert echoInfo.pendingAntiAffineRequestCount == 3 + // no active requests ... there's no capacity + assert !echoInfo.isAARequestOutstanding + } } http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentEcho.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentEcho.groovy b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentEcho.groovy index f14fc43..4ceeca0 100644 --- a/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentEcho.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/providers/agent/TestAgentEcho.groovy @@ -40,6 +40,7 @@ import static org.apache.slider.providers.agent.AgentKeys.* @Slf4j class TestAgentEcho extends AgentTestBase { + protected static final String ECHO = "echo" File slider_core String echo_py File echo_py_path @@ -59,7 +60,6 @@ class TestAgentEcho extends AgentTestBase { agt_ver_path = new File(slider_core, agt_ver) agt_conf = "agent.ini" agt_conf_path = new File(slider_core, agt_conf) - } @Override @@ -68,7 +68,7 @@ class TestAgentEcho extends AgentTestBase { } @Test - public void testEchoOperation() throws Throwable { + public void testAgentEcho() throws Throwable { assumeValidServerEnv() String clustername = createMiniCluster("", @@ -81,7 +81,7 @@ class TestAgentEcho extends AgentTestBase { validatePaths() - def role = "echo" + def role = ECHO Map<String, Integer> roles = [ (role): 2, ]; http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/groovy/org/apache/slider/test/KeysForTests.groovy ---------------------------------------------------------------------- diff --git a/slider-core/src/test/groovy/org/apache/slider/test/KeysForTests.groovy b/slider-core/src/test/groovy/org/apache/slider/test/KeysForTests.groovy index 4721552..b4a7ac9 100644 --- a/slider-core/src/test/groovy/org/apache/slider/test/KeysForTests.groovy +++ b/slider-core/src/test/groovy/org/apache/slider/test/KeysForTests.groovy @@ -33,8 +33,9 @@ public interface KeysForTests extends SliderKeys, SliderXMLConfKeysForTesting { String USERNAME = "bigdataborat" int WAIT_TIME = 120; - String WAIT_TIME_ARG = WAIT_TIME.toString() + String WAIT_TIME_ARG = Integer.toString(WAIT_TIME) String SLIDER_TEST_XML = "slider-test.xml" + String NODES_UPDATED_FLAG_METRIC = "org.apache.slider.server.appmaster.state.RoleHistory.nodes-updated.flag" } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/python/agent.py ---------------------------------------------------------------------- diff --git a/slider-core/src/test/python/agent.py b/slider-core/src/test/python/agent.py index 4177074..1c9ff5b 100644 --- a/slider-core/src/test/python/agent.py +++ b/slider-core/src/test/python/agent.py @@ -24,14 +24,21 @@ import time from optparse import OptionParser import os + # A representative Agent code for the embedded agent def main(): - print "Executing echo" - print 'Argument List: {0}'.format(str(sys.argv)) + print "Executing src/test/python/agent.py" + try: + print 'Argument List: {0}'.format(str(sys.argv)) + except AttributeError: + pass parser = OptionParser() parser.add_option("--log", dest="log_folder", help="log destination") parser.add_option("--config", dest="conf_folder", help="conf folder") + parser.add_option('--sleep', dest='sleep', help='sleep time') + parser.add_option('--exitcode', dest='exitcode', help='exit code to return') + (options, args) = parser.parse_args() if options.log_folder: @@ -43,9 +50,17 @@ def main(): logging.info("Number of arguments: %s arguments.", str(len(sys.argv))) logging.info("Argument List: %s", str(sys.argv)) - time.sleep(30) + sleeptime = 30 + if options.sleep: + sleeptime = int(options.sleep) + if sleeptime > 0: + logging.info("Sleeping for %d seconds", sleeptime) + time.sleep(sleeptime) + exitcode = 0 + if options.exitcode: + exitcode = int(options.exitcode) + return exitcode if __name__ == "__main__": - main() - sys.exit(0) + sys.exit(main()) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/python/agent/main.py ---------------------------------------------------------------------- diff --git a/slider-core/src/test/python/agent/main.py b/slider-core/src/test/python/agent/main.py index 116d179..1e851bb 100755 --- a/slider-core/src/test/python/agent/main.py +++ b/slider-core/src/test/python/agent/main.py @@ -26,7 +26,7 @@ import os def main(): - print "Executing echo" + print "Executing src/test/python/agent/main.py" try: print 'Argument List: {0}'.format(str(sys.argv)) except AttributeError: @@ -37,6 +37,8 @@ def main(): parser.add_option("--config", dest="conf_folder", help="conf folder") parser.add_option('--command', dest='command', help='command to execute') parser.add_option('--label', dest='label', help='label') + parser.add_option('--sleep', dest='sleep', help='sleep time') + parser.add_option('--exitcode', dest='exitcode', help='exit code to return') parser.add_option('--zk-quorum', dest='host:2181', help='zookeeper quorum') parser.add_option('--zk-reg-path', dest='/register/org-apache-slider/cl1', help='zookeeper registry path') @@ -51,9 +53,17 @@ def main(): logging.info("Number of arguments: %s arguments.", str(len(sys.argv))) logging.info("Argument List: %s", str(sys.argv)) - time.sleep(30) + sleeptime = 30 + if options.sleep: + sleeptime = int(options.sleep) + if sleeptime > 0: + logging.info("Sleeping for %d seconds", sleeptime) + time.sleep(sleeptime) + exitcode = 0 + if options.exitcode: + exitcode = int(options.exitcode) + return exitcode if __name__ == "__main__": - main() - sys.exit(0) + sys.exit(main()) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/python/echo.py ---------------------------------------------------------------------- diff --git a/slider-core/src/test/python/echo.py b/slider-core/src/test/python/echo.py index ea5e8ce..1dabf1c 100644 --- a/slider-core/src/test/python/echo.py +++ b/slider-core/src/test/python/echo.py @@ -26,13 +26,18 @@ import os def main(): - print "Executing echo" - print 'Argument List: {0}'.format(str(sys.argv)) + print "Executing src/test/python/echo.py" + try: + print 'Argument List: {0}'.format(str(sys.argv)) + except AttributeError: + pass parser = OptionParser() parser.add_option("--log", dest="log_folder", help="log destination") parser.add_option("--config", dest="conf_folder", help="conf folder") parser.add_option('--command', dest='command', help='command to execute') + parser.add_option('--sleep', dest='sleep', help='sleep time') + parser.add_option('--exitcode', dest='exitcode', help='exit code to return') (options, args) = parser.parse_args() if options.log_folder: @@ -44,9 +49,17 @@ def main(): logging.info("Number of arguments: %s arguments.", str(len(sys.argv))) logging.info("Argument List: %s", str(sys.argv)) - time.sleep(30) + sleeptime = 300 + if options.sleep: + sleeptime = int(options.sleep) + if sleeptime > 0: + logging.info("Sleeping for %d seconds", sleeptime) + time.sleep(sleeptime) + exitcode = 0 + if options.exitcode: + exitcode = int(options.exitcode) + return exitcode if __name__ == "__main__": - main() - sys.exit(0) + sys.exit(main()) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/591ba99e/slider-core/src/test/python/metainfo.xml ---------------------------------------------------------------------- diff --git a/slider-core/src/test/python/metainfo.xml b/slider-core/src/test/python/metainfo.xml index 7f9cd23..b7251d3 100644 --- a/slider-core/src/test/python/metainfo.xml +++ b/slider-core/src/test/python/metainfo.xml @@ -24,7 +24,7 @@ </comment> <version>0.1</version> <type>YARN-APP</type> - <minHadoopVersion>2.1.0</minHadoopVersion> + <minHadoopVersion>2.6.0</minHadoopVersion> <components> <component> <name>hbase-rs</name>
