Author: justi9
Date: 2009-06-17 16:20:11 -0400 (Wed, 17 Jun 2009)
New Revision: 3457
Added:
mgmt/trunk/cumin/metadata/
mgmt/trunk/cumin/metadata/model.xml
mgmt/trunk/cumin/metadata/qmf/
mgmt/trunk/cumin/metadata/qmf/Makefile
mgmt/trunk/cumin/metadata/qmf/condor.xml
mgmt/trunk/cumin/metadata/qmf/qpid-acl.xml
mgmt/trunk/cumin/metadata/qmf/qpid-cluster.xml
mgmt/trunk/cumin/metadata/qmf/qpid-store.xml
mgmt/trunk/cumin/metadata/qmf/qpid.xml
mgmt/trunk/cumin/metadata/qmf/sesame.xml
mgmt/trunk/cumin/python/cumin/messaging/model.py
Modified:
mgmt/trunk/cumin/python/cumin/__init__.py
mgmt/trunk/cumin/python/cumin/account/main.py
mgmt/trunk/cumin/python/cumin/account/main.strings
mgmt/trunk/cumin/python/cumin/account/user.py
mgmt/trunk/cumin/python/cumin/grid/main.py
mgmt/trunk/cumin/python/cumin/inventory/main.py
mgmt/trunk/cumin/python/cumin/messaging/binding.py
mgmt/trunk/cumin/python/cumin/messaging/binding.strings
mgmt/trunk/cumin/python/cumin/messaging/broker.py
mgmt/trunk/cumin/python/cumin/messaging/broker.strings
mgmt/trunk/cumin/python/cumin/messaging/brokergroup.py
mgmt/trunk/cumin/python/cumin/messaging/brokerlink.py
mgmt/trunk/cumin/python/cumin/messaging/brokerlink.strings
mgmt/trunk/cumin/python/cumin/messaging/client.py
mgmt/trunk/cumin/python/cumin/messaging/client.strings
mgmt/trunk/cumin/python/cumin/messaging/exchange.py
mgmt/trunk/cumin/python/cumin/messaging/exchange.strings
mgmt/trunk/cumin/python/cumin/messaging/main.py
mgmt/trunk/cumin/python/cumin/messaging/queue.py
mgmt/trunk/cumin/python/cumin/messaging/queue.strings
mgmt/trunk/cumin/python/cumin/model.py
mgmt/trunk/cumin/python/cumin/modelwidgets.py
mgmt/trunk/cumin/python/cumin/page.py
mgmt/trunk/cumin/python/cumin/parameters.py
mgmt/trunk/cumin/python/cumin/usergrid/main.py
mgmt/trunk/cumin/python/cumin/usergrid/submission.py
mgmt/trunk/cumin/python/cumin/util.py
mgmt/trunk/cumin/python/cumin/widgets.py
mgmt/trunk/cumin/python/cumin/widgets.strings
mgmt/trunk/cumin/resources/app.css
Log:
* Introduce module objects for usergrid, messaging, grid, inventory,
and account
* Introduce a top-level form page, for holding and serving forms;
forms are now top-level things themselves, rather than being
embedded with object views
* Add a CuminSubject class to the ui metadata
* Introduce Task, a replacement for Action; Tasks know how to
navigate to their own forms, and they encapsulate domain logic
Attendant things: TaskInvocation, QmfTask, SetTask,
TaskInvocationSet
Tasks and Actions coexist for now
* Convert all the messaging actions to tasks, and taskify the related
forms
* Eliminate ModelPage, which is no longer used
* Put in missing super calls in class init methods
* Add a VhostParameter, BindingParameter, RouteParameter, and
LinkParameter, with PeerParameter aliased to the last
* Introduce a BackgroundInclude widget, for throwing the output of
some url inside a page area
* Introduce CuminSelectionTable, to replace a lot of custom table
code; it is a table that comes with a checkbox column and a set of
buttons (for set tasks) and links (for add tasks, for instance); it
takes an item parameter
* For use in the above class, a TaskButton and TaskLink. These take
tasks in their constructors and use that metadata to do navigation
* Convert messaging module tables to use CuminSelectionTable
* Add plural(noun) and conjugate(noun, count) methods for
pluralizing words
* Modernize the names of things under brokerlink
* Move BindingSet to a better location
* Rename NewBrokerSet to BrokerSet
* Remove various unused status widgets
Added: mgmt/trunk/cumin/metadata/model.xml
===================================================================
--- mgmt/trunk/cumin/metadata/model.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/model.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,27 @@
+<model>
+ <package name="org.apache.qpid.broker">
+ <class name="System">
+ <property name="systemId">
+ <title>System ID</title>
+ </property>
+ </class>
+ </package>
+</model>
+<model>
+ <package name="org.apache.qpid.broker">
+ <class name="System">
+ <property name="systemId">
+ <title>System ID</title>
+ </property>
+ </class>
+ </package>
+</model>
+<model>
+ <package name="org.apache.qpid.broker">
+ <class name="System">
+ <property name="systemId">
+ <title>System ID</title>
+ </property>
+ </class>
+ </package>
+</model>
Added: mgmt/trunk/cumin/metadata/qmf/Makefile
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/Makefile (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/Makefile 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,78 @@
+.PHONY: schema clean
+
+FILES := qpid.xml qpid-store.xml qpid-acl.xml qpid-cluster.xml condor.xml sesame.xml
+
+schema: ${FILES}
+
+clean:
+ rm -f ${FILES}
+
+qpid.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/specs/management-schema.xml
qpid.xml
+
+qpid-store.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/store/trunk/cpp/lib/qmf-schema...
qpid-store.xml
+
+qpid-acl.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/acl/manageme...
qpid-acl.xml
+
+qpid-cluster.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/cluster/mana...
qpid-cluster.xml
+
+condor.xml:
+ wget
"http://git.et.redhat.com/?p=mrg-grid.git;a=blob_plain;f=src/management/condor-management-schema.xml;hb=refs/heads/V7.3-QMF-Plugins"
-O condor.xml
+
+sesame.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/mgmt/trunk/sesame/cpp/src/qmfg...
sesame.xml
+.PHONY: schema clean
+
+FILES := qpid.xml qpid-store.xml qpid-acl.xml qpid-cluster.xml condor.xml sesame.xml
+
+schema: ${FILES}
+
+clean:
+ rm -f ${FILES}
+
+qpid.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/specs/management-schema.xml
qpid.xml
+
+qpid-store.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/store/trunk/cpp/lib/qmf-schema...
qpid-store.xml
+
+qpid-acl.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/acl/manageme...
qpid-acl.xml
+
+qpid-cluster.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/cluster/mana...
qpid-cluster.xml
+
+condor.xml:
+ wget
"http://git.et.redhat.com/?p=mrg-grid.git;a=blob_plain;f=src/management/condor-management-schema.xml;hb=refs/heads/V7.3-QMF-Plugins"
-O condor.xml
+
+sesame.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/mgmt/trunk/sesame/cpp/src/qmfg...
sesame.xml
+.PHONY: schema clean
+
+FILES := qpid.xml qpid-store.xml qpid-acl.xml qpid-cluster.xml condor.xml sesame.xml
+
+schema: ${FILES}
+
+clean:
+ rm -f ${FILES}
+
+qpid.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/specs/management-schema.xml
qpid.xml
+
+qpid-store.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/store/trunk/cpp/lib/qmf-schema...
qpid-store.xml
+
+qpid-acl.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/acl/manageme...
qpid-acl.xml
+
+qpid-cluster.xml:
+ svn export
http://svn.apache.org/repos/asf/qpid/trunk/qpid/cpp/src/qpid/cluster/mana...
qpid-cluster.xml
+
+condor.xml:
+ wget
"http://git.et.redhat.com/?p=mrg-grid.git;a=blob_plain;f=src/management/condor-management-schema.xml;hb=refs/heads/V7.3-QMF-Plugins"
-O condor.xml
+
+sesame.xml:
+ svn export
http://anonsvn.jboss.org/repos/rhmessaging/mgmt/trunk/sesame/cpp/src/qmfg...
sesame.xml
Added: mgmt/trunk/cumin/metadata/qmf/condor.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/condor.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/condor.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,816 @@
+<schema package="mrg.grid">
+
+<!--
+/*
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * Licensed 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.
+ */
+-->
+
+<group name="daemon-stats">
+ <property name="CondorPlatform"
+ type="sstr"
+ desc="The Condor platform string for the daemon's platform"/>
+ <property name="CondorVersion"
+ type="sstr"
+ desc="The Condor version string for the daemon's version"/>
+ <property name="DaemonStartTime"
+ type="absTime" unit="nanosecond"
+ desc="Number of nanoseconds since epoch when the daemon
+ was started"/>
+
+ <statistic name="MonitorSelfAge" type="uint32"/>
+ <statistic name="MonitorSelfCPUUsage" type="double"/>
+ <statistic name="MonitorSelfImageSize" type="double"/>
+ <statistic name="MonitorSelfRegisteredSocketCount"
type="uint32"/>
+ <statistic name="MonitorSelfResidentSetSize" type="uint32"/>
+ <statistic name="MonitorSelfTime" type="absTime"/>
+</group>
+
+<!--
+CpuBusy = ((LoadAvg - CondorLoadAvg) >= 0.500000)
+CpuBusyTime = 0
+CpuIsBusy = FALSE
+
+HasCheckpointing = TRUE
+HasFileTransfer = TRUE
+HasIOProxy = TRUE
+HasJava = TRUE
+HasJICLocalConfig = TRUE
+HasJICLocalStdin = TRUE
+HasJobDeferral = TRUE
+HasMPI = TRUE
+HasPerFileEncryption = TRUE
+HasReconnect = TRUE
+HasRemoteSyscalls = TRUE
+HasTDP = TRUE
+HasVM = FALSE
+
+JavaMFlops = 8.156164
+JavaVendor = "Free Software Foundation, Inc."
+JavaVersion = "1.4.2"
+
+Subnet = "10.16.43"
+
+Set by Collector:
+ UpdateSequenceNumber = 627
+ UpdatesHistory = "0x00000000000000000000000000000000"
+ UpdatesLost = 0
+ UpdatesSequenced = 58
+ UpdatesTotal = 59
+-->
+
+ <class name="Slot">
+
+ <group name="daemon-stats"/>
+
+ <property name="Pool" type="sstr" index="y"/>
+ <property name="System" type="sstr" index="y"/>
+
+ <property name="AccountingGroup"
+ type="sstr"
+ optional="y"
+ desc="AccountingGroup of the running job, fully
+ qualified with a UidDomain, UidDomain taken from
+ RemoteUser, only present when a job is
+ executing"/>
+ <statistic name="Activity"
+ type="sstr"
+ desc="One of: Idle, No job activity; Busy, Job is
+ running; Suspended, Job is suspended; Vacating,
+ Job is being removed; Killing, Job is being
+ killed; Benchmarking, Benchmarks being run"/>
+ <property name="Arch"
+ type="sstr"
+ desc="Slot's architecture, e.g.: ALPHA, Diginal Alpha;
+ HPPA1, HP PA-RISC 1.x (7000 series); HPPA2, HP
+ PA-RISC 2.x (8000 series); IA64, Intel Itanium;
+ INTEL, Intel x86 (Pentium, Xeon, etc); SGI, SGI
+ MIPS; SUN4u, Sun UltraSparc; SUN4x, Sun Sparc
+ (not UltraSparc); PPC, Power Macintosh; PPC64,
+ 64-bit Power Macintosh; X86_64, AMD/Intel 64-bit
+ x86"/>
+ <property name="CheckpointPlatform"
+ type="sstr"
+ desc="Opaque string encoding OS, hardware and kernel
+ attributes"/>
+ <property name="ClientMachine"
+ type="sstr"
+ optional="y"
+ desc="The hostname of the machine that has claimed the
+ slot, only present when slot is claimed"/>
+ <statistic name="ClockDay"
+ type="uint32"
+ desc="Day of the week: 0 = Sunday, 1 = Monday, ..., 6 =
+ Saturaday"/>
+ <statistic name="ClockMin"
+ type="uint32" unit="minute"
+ desc="Number of elapsed minutes since midnight"/>
+ <property name="ConcurrencyLimits"
+ type="sstr"
+ optional="y"
+ desc="Set of concurrency limits associated with the
+ current job"/>
+ <statistic name="CondorLoadAvg"
+ type="double"
+ desc="Portion of LoadAvg generated by Condor (job or
+ benchmark)"/>
+ <statistic name="ConsoleIdle"
+ type="uint32" unit="second"
+ desc="Seconds since activity on console keyboard or
+ mouse"/>
+ <property name="Cpus"
+ type="uint32"
+ desc="Number of CPUs in slot"/>
+ <!-- XXX: CurrentRank could quite possibly be a statistic -->
+ <property name="CurrentRank"
+ type="double"
+ optional="y"
+ desc="Slots' affinity for running the job it is
+ currently hosting, calculated as Rank expression
+ evaluated in context of the running job's ad"/>
+ <property name="Disk"
+ type="uint32" unit="KiB"
+ desc="Amount of disk space in KiB available in the slot"/>
+ <statistic name="EnteredCurrentActivity"
+ type="absTime" unit="nanosecond"
+ desc="Time at which current Activity was entered,
+ number of nanoseconds since Unix epoch"/>
+ <statistic name="EnteredCurrentState"
+ type="absTime" unit="nanosecond"
+ desc="Time at which current State was entered,
+ number of seconds since Unix epoch"/>
+ <property name="FileSystemDomain"
+ type="sstr"
+ desc="Configured namespace shared by slots with
+ uniformly mounted shared storage"/>
+ <property name="GlobalJobId"
+ type="sstr"
+ optional="y"
+ desc="The running job's GlobalJobId, only present when
+ a job is executing"/>
+ <!-- XXX: ImageSize could quite possibly be a statistic -->
+ <property name="ImageSize"
+ type="uint32" unit="KiB"
+ optional="y"
+ desc="Estimate of the memory image size, in KiB, of the
+ running job, only present when a job is
+ executing, pulled by STARTD_JOB_EXPRS"/>
+ <property name="IsValidCheckpointPlatform"
+ type="lstr"
+ desc="A configurable expression representing if a
+ checkpointed job can run on the slot, part of the
+ slot's Requirements along with the Start
+ expression"/>
+ <!-- XXX: JobId could quite possibly be a statistic, snapshots
+ would show use over time -->
+ <property name="JobId"
+ type="sstr"
+ optional="y"
+ desc="The running job's identifier,
+ i.e. ClusterId.ProcId, only present when a job is
+ executing"/>
+ <property name="JobStart"
+ type="absTime" unit="nanosecond"
+ optional="y"
+ desc="The number of nanosecond since epoch when the job
+ began executing, only present when a job is
+ executing"/>
+ <statistic name="KeyboardIdle"
+ type="uint32" unit="second"
+ desc="Number of seconds since any activity on any
+ keyboard or mouse associated with the machine,
+ including pseudo-terminals"/>
+ <property name="KFlops"
+ type="uint32"
+ desc="Relative floating point performance on a Linpack
+ benchmark"/>
+ <statistic name="LastBenchmark"
+ type="absTime" unit="nanosecond"
+ desc="Number of nanoseconds since epoch when the last
+ benchmark was run"/>
+ <statistic name="LastFetchWorkCompleted"
+ type="absTime" unit="nanosecond"
+ desc="Number of nanoseconds since epoch when the
+ FetchWork Hook returned"/>
+
+ <statistic name="LastFetchWorkSpawned"
+ type="absTime" unit="nanosecond"
+ desc="Number of nanoseconds since epoch when the
+ FetchWork Hook was invoked"/>
+ <statistic name="LastPeriodicCheckpoint"
+ type="absTime" unit="nanosecond"
+ desc="The number of nanoseconds since epoch when the
+ job last performed a periodic checkpoint, only
+ present when a job is executing"/>
+<!--
+ <statistic name="LastHeardFrom"
+ type="absTime" unit="nanosecond"
+ desc="Time when the Collector received an update from
+ the slot, nanoseconds since epoch, inserted by
+ Collector"/>
+-->
+ <statistic name="LoadAvg"
+ type="double"
+ desc="Load average of CPUs hosting the slot"/>
+ <property name="Machine"
+ type="sstr"
+ desc="The fully qualified hostname of slot's host
+ machine"/>
+ <property name="MaxJobRetirementTime"
+ type="lstr" unit="second"
+ desc="Expression evaluated in context of job ad
+ producing the number of seconds a job is allowed
+ to finish before being killed, relevant when job
+ is being kicked out of the slot"/>
+ <property name="Memory"
+ type="uint32" unit="MiB"
+ desc="Amount of RAM available in the slot, in MiB"/>
+ <property name="Mips"
+ type="uint32"
+ desc="Relative integer performance on a Dhrystone
+ benchmark"/>
+ <property name="MyAddress"
+ type="sstr"
+ desc="IP:Port of StartD in charge of the slot"/>
+ <statistic name="MyCurrentTime"
+ type="absTime" unit="nanosecond"
+ desc="The number of nanoseconds since epoch that the
+ slot produced an updated ad"/>
+<!--
+ <property name="MyType"
+ type="sstr"
+ desc="Always 'Machine'"\>
+-->
+ <property name="Name"
+ type="sstr"
+ index="y"
+ desc="Name of the slot, either the same as Machine,
+ slot#@Machine, or a configured value"/>
+ <statistic name="NextFetchWorkDelay"
+ type="int32" unit="second"
+ desc="Number of seconds until the next FetchWork
+ Hook will be invoked, -1 means never"/>
+ <property name="OpSys"
+ type="sstr"
+ desc="Slot's operating system, e.g.: HPUX10, HPUX
+ 10.20; HPUX11, HPUX B.11.00; LINUX, Linux
+ 2.[0,2,4,6].x kernels; OSF1, Diginal Unix 4.x;
+ OSX, Darwin; OSX10_2, Darwin 6.4; SOLARIS25,
+ Solaris 2.4 or 5.5; SOLARIS251, Solaris 2.5.1 or
+ 5.5.1; SOLARIS26, Solaris 2.6 or 5.6; SOLARIS27,
+ Solaris 2.7 or 5.7; SOLARIS28, Solaris 2.8 or
+ 5.8; SOLARIS29, Solaris 2.9 or 5.9; WINNT50,
+ Windows 2000; WINNT51, Windows XP; WINNT52,
+ Windows Server 2003; WINNT60, Windows Vista"/>
+ <property name="PreemptingConcurrencyLimits"
+ type="sstr"
+ optional="y"
+ desc="Set of concurrency limits associated with the
+ preempting job"/>
+ <property name="PreemptingOwner"
+ type="sstr"
+ optional="y"
+ desc="The name of the user originally preempting the
+ current job, i.e. the incoming user, only present
+ when slot is claimed"/>
+ <!-- XXX: PreemptingUser could quite possibly be a statistic -->
+ <property name="PreemptingUser"
+ type="sstr"
+ optional="y"
+ desc="The name of the user preempting the current job,
+ different from PreemptingOwner only if the claim
+ was given to another user who is using it to
+ preempt, only present when slot is claimed"/>
+ <!-- XXX: PreemptingRank could quite possibly be a statistic -->
+ <property name="PreemptingRank"
+ type="double"
+ optional="y"
+ desc="Slots' affinity for running the incoming,
+ preempting, job, calculated as Rank expression
+ evaluated in context of the incoming job's ad,
+ only present when slot is claimed"/>
+ <!-- XXX: RemoteOwner could quite possibly be a statistic, showing
+ use over time -->
+ <property name="RemoteOwner"
+ type="sstr"
+ optional="y"
+ desc="The name of the user who originally claimed the
+ slot, only present when slot is claimed"/>
+ <!-- XXX: RemoteUser could quite possibly be a statistic, showing
+ use over time -->
+ <property name="RemoteUser"
+ type="sstr"
+ optional="y"
+ desc="The name of the user who is currently using the
+ slot, different from RemoteOwner only if the
+ claim was given to another user who is using the
+ slot, only present when slot is claimed"/>
+ <property name="Requirements"
+ type="lstr"
+ desc="Expression evaluated in the context of a job ad
+ to determine if the slot will run a job"/>
+ <property name="PublicNetworkIpAddr"
+ type="sstr"
+ desc="IP:Port used to communicate with the slot"/>
+ <property name="Rank"
+ type="lstr"
+ desc="Configured expression representing how the slot
+ prefers jobs"/>
+ <property name="SlotID"
+ type="uint32"
+ desc="The # in the slot's Name, i.e.
Name='slot#@Machine'"/>
+ <property name="Start"
+ type="lstr"
+ desc="Expression evaluated to determine if a slot is
+ willing to start running a job"/>
+ <property name="StarterAbilityList"
+ type="lstr"
+ desc="StringList, comma separated, set of abilities the
+ slot has, i.e. HasFileTransfer,HasJava,HasVM,
+ query with stringListMember('Element',
+ StarterAbilityList)"/>
+ <statistic name="State"
+ type="sstr"
+ desc="One of: Owner, unavailable to Condor; Unclaimed,
+ available to Condor, but no job match yet;
+ Matched, job found, but not yet claimed; Claimed,
+ claimed and job likely running (see Activity);
+ Preempting, running job is being kicked off the
+ slot"/>
+<!--
+ <statistic name="TargetType"
+ type="sstr"
+ desc="Always 'Job'"/>
+-->
+ <statistic name="TimeToLive"
+ type="uint32" unit="second"
+ desc="Number of second until StartD managing the slot
+ has until it will exit"/>
+ <!-- XXX: TotalClaimRunTime is a statistic -->
+ <property name="TotalClaimRunTime"
+ type="uint32" unit="second"
+ optional="y"
+ desc="Number of seconds the current claim has spent
+ running jobs, only present when slot is
+ claimed"/>
+ <!-- XXX: TotalClaimSuspendTime is a statistic -->
+ <property name="TotalClaimSuspendTime"
+ type="uint32" unit="second"
+ optional="y"
+ desc="Number of seconds the current claim has spent
+ with suspended jobs, only present when slot is
+ claimed"/>
+ <statistic name="TotalCondorLoadAvg"
+ type="double"
+ desc="Portion of TotalLoadAvg generated by Condor (jobs
+ or benchmarks)"/>
+ <property name="TotalCpus"
+ type="uint32"
+ desc="Total number of CPUs on slot's host machine, or
+ NUM_CPUS configuration option"/>
+ <property name="TotalDisk"
+ type="uint32" unit="KiB"
+ desc="Amount of disk space available on the slot's host
+ machine"/>
+ <!-- XXX: TotalJobRunTime is a statistic -->
+ <property name="TotalJobRunTime"
+ type="uint32" unit="second"
+ optional="y"
+ desc="Number of seconds the current job has spent
+ running, i.e. Claimed/Busy, only present when
+ slot is claimed"/>
+ <!-- XXX: TotalJobSuspendTime is a statistic -->
+ <property name="TotalJobSuspendTime"
+ type="uint32" unit="second"
+ optional="y"
+ desc="Number of seconds the current job has spent
+ suspended, i.e. Claimed/Suspended, only present
+ when slot is claimed"/>
+ <statistic name="TotalLoadAvg"
+ type="double"
+ desc="Total load average of the slot's host machine"/>
+ <property name="TotalMemory"
+ type="uint32" unit="MiB"
+ desc="Total RAM available on slot's machine, in MiB"/>
+ <property name="TotalSlots"
+ type="uint32"
+ desc="Total number of slots sharing the Machine"/>
+ <statistic name="TotalTimeBackfillBusy"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Backfill and Activity=Busy since the
+ Startd started"/>
+ <statistic name="TotalTimeBackfillIdle"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Backfill and Activity=Idle since the
+ Startd started"/>
+ <statistic name="TotalTimeBackfillKilling"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Backfill and Activity=Killing since the
+ Startd started"/>
+ <statistic name="TotalTimeClaimedBusy"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Claimed and Activity=Busy since the
+ Startd started"/>
+ <statistic name="TotalTimeClaimedIdle"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Claimed and Activity=Idle since the
+ Startd started"/>
+ <statistic name="TotalTimeClaimedRetiring"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Claimed and Activity=Retiring since the
+ Startd started"/>
+ <statistic name="TotalTimeClaimedSuspended"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Claimed and Activity=Suspended since the
+ Startd started"/>
+ <statistic name="TotalTimeMatchedIdle"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Matched and Activity=Idle since the
+ Startd started"/>
+ <statistic name="TotalTimeOwnerIdle"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Owner and Activity=Idle since the
+ Startd started"/>
+ <statistic name="TotalTimePreemptingKilling"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Preempting and Activity=Killing since the
+ Startd started"/>
+ <statistic name="TotalTimePreemptingVacating"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Preempting and Activity=Vacating since the
+ Startd started"/>
+ <statistic name="TotalTimeUnclaimedBenchmarking"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Unclaimed and Activity=Benchmarking since
+ the Startd started"/>
+ <statistic name="TotalTimeUnclaimedIdle"
+ type="uint32" unit="second"
+ desc="Accumulated number of seconds the slot has been
+ in State=Unclaimed and Activity=Idle since the
+ Startd started"/>
+ <property name="TotalVirtualMemory"
+ type="uint32" unit="KiB"
+ desc="Amount of swap space available on slot"/>
+ <property name="UidDomain"
+ type="sstr"
+ desc="Configured namespace shared by slots with
+ uniform uid/gid entries, i.e. same logins and
+ groups"/>
+ <property name="VirtualMemory"
+ type="uint32" unit="KiB"
+ desc="Amount of currently available virtual memory
+ (swap space) in KiB"/>
+ <property name="WindowsBuildNumber"
+ type="uint32"
+ desc="Integer extracted from the platform type,
+ representing a build number for a Windows
+ operating system, only present on Windows
+ slots"/>
+ <property name="WindowsMajorVersion"
+ type="uint32"
+ desc="Integer extracted from the platform type,
+ representing a major version number for a Windows
+ operating system, only present on Windows
+ slots, e.g. 5 for OpSys=WINNT50"/>
+ <property name="WindowsMinorVersion"
+ type="uint32"
+ desc="Integer extected from the platform type,
+ representing a minor version numer for a Windows
+ operating system, only present on Windows
+ slots, e.g. 2 for OpSys=WINNT52"/>
+
+<!--
+ <property name="AdditionalAttributes" type="map"/>
+-->
+ </class>
+
+<!--
+Exec Host, Order(Rank?), StartTime, TotalTime (Sys, User), Project, AccountingGroup
+-->
+ <class name="Job">
+ <property name="schedulerRef" type="objId"
parentRef="y" index="y"
references="mrg.grid.Scheduler"/>
+ <property name="submitterRef" type="objId"
references="mrg.grid.Submitter"/>
+
+ <property name="AccountingGroup" type="sstr"
optional="y" desc=""/>
+ <property name="Args" type="lstr" optional="y"
desc=""/>
+ <property name="ClusterId"
+ type="uint32" index="y"
+ desc="The id of the cluster the job belongs
+ to. ClusterIds are unique within a SchedD."/>
+ <property name="Cmd" type="lstr" desc=""/>
+ <property name="ConcurrencyLimits" type="lstr"
optional="y" desc=""/>
+ <property name="CustomGroup" type="sstr"
optional="y" desc=""/>
+ <property name="CustomId" type="sstr" optional="y"
desc=""/>
+ <property name="CustomPriority" type="uint32"
optional="y" desc=""/>
+ <property name="GlobalJobId" type="sstr"
desc=""/>
+ <property name="In"
+ type="lstr"
+ desc="The file where the job's standard input is read
+ from."/>
+ <property name="Iwd" type="lstr" desc=""/>
+ <property name="JobStatus"
+ type="uint32"
+ desc="One of: 0, unexpanded; 1, idle; 2, running; 3,
+ removed; 4, completed; 5, held; or, 6, submission
+ error"/>
+ <property name="Note"
+ type="lstr" optional="y"
+ desc="An arbitrary note attached to the job."/>
+ <property name="Out"
+ type="lstr"
+ desc="The file where the job's standard output is
+ written."/>
+ <property name="Owner"
+ type="sstr"
+ desc="The submitter of the job."/>
+ <property name="User"
+ type="sstr"
+ desc="The Owner '@' the configured UidDomain namespace"/>
+ <property name="ProcId"
+ type="uint32" index="y"
+ desc="The id of the job within its cluster. ProcIds re
+ unique within a cluster."/>
+ <property name="QDate"
+ type="absTime" unit="nanoseconds"
+ desc="The number of nanoseconds since epoch when the
+ job was submitted."/>
+
+<!--
+ <property name="Requirements" type="lstr"
desc=""/>
+ <property name="Scheduler" type="sstr" desc=""/>
+-->
+
+ <property name="JobUniverse"
+ type="uint32"
+ desc=""/>
+
+ <property name="Title" type="sstr" optional="y"
desc=""/>
+ <property name="UserLog" type="lstr" optional="y"
desc=""/>
+
+ <property name="HoldReason" type="lstr" optional="y"
desc=""/>
+
+ <property name="DAGNodeName"
+ type="sstr" optional="y" desc=""/>
+ <property name="DAGParentNodeNames"
+ type="lstr" optional="y"
+ desc="Comma separated list of the job's parent's node
+ names"/>
+ <property name="DAGManJobId"
+ type="uint32" optional="y"
+ desc="The ClusterId of the DAGMan job who spawned the
+ job"/>
+
+ <property name="Ad" type="map" optional="y"
desc=""/>
+
+ <method name="GetAd">
+ <arg name="JobAd" dir="O" type="map"
+ desc="(name,value,type) tuples; Values are INTEGER, FLOAT,
+ STRING and EXPR. The EXPR value is not first class,
+ it is an unquoted, with double quotes, string"/>
+ </method>
+
+ <method name="SetAttribute">
+ <arg name="Name" dir="I" type="sstr"/>
+ <arg name="Value" dir="I" type="lstr"/>
+ </method>
+
+ <method name="Hold">
+ <arg name="Reason" dir="I" type="sstr"/>
+ </method>
+
+ <method name="Release">
+ <arg name="Reason" dir="I" type="sstr"/>
+ </method>
+
+ <method name="Remove">
+ <arg name="Reason" dir="I" type="sstr"/>
+ </method>
+
+ <method name="Fetch">
+ <arg name="File" dir="I" type="sstr"/>
+ <arg name="Start" dir="I" type="int32"/>
+ <arg name="End" dir="I" type="int32"/>
+ <arg name="Data" dir="O" type="lstr"/>
+ </method>
+ </class>
+
+ <class name="Scheduler">
+ <group name="daemon-stats"/>
+
+ <property name="Pool" type="sstr" index="y"/>
+ <property name="System" type="sstr" index="y"/>
+
+ <property name="JobQueueBirthdate" type="absTime"/>
+ <property name="MaxJobsRunning" type="uint32"
desc=""/>
+ <property name="Machine" type="sstr" desc=""/>
+ <property name="MyAddress" type="sstr" desc=""/>
+ <statistic name="NumUsers" type="uint32"/>
+ <property name="Name" type="sstr" index="y"
desc=""/>
+ <property name="PublicNetworkIpAddr" type="sstr"
desc=""/>
+ <statistic name="TotalHeldJobs" type="uint32"/>
+ <statistic name="TotalIdleJobs" type="uint32"/>
+ <statistic name="TotalJobAds" type="uint32"/>
+ <statistic name="TotalRemovedJobs" type="uint32"/>
+ <statistic name="TotalRunningJobs" type="uint32"/>
+
+ <method name="Submit">
+ <arg name="Ad" dir="I" type="map"/>
+ <arg name="Id" dir="O" type="sstr"/>
+ </method>
+ </class>
+
+ <class name="Submitter">
+ <property name="schedulerRef" type="objId"
parentRef="y" index="y"
references="mrg.grid.Scheduler"/>
+
+ <statistic name="HeldJobs" type="uint32"/>
+ <statistic name="IdleJobs" type="uint32"/>
+ <property name="JobQueueBirthdate" type="absTime"/>
+ <property name="Machine" type="sstr"/>
+ <property name="Name" type="sstr" index="y"/>
+ <statistic name="RunningJobs" type="uint32"/>
+ <property name="ScheddName" type="sstr"/>
+ </class>
+
+ <class name="Negotiator">
+ <property name="Pool" type="sstr" index="y"/>
+ <property name="System" type="sstr" index="y"/>
+
+ <property name="Name" type="sstr" index="y"/>
+ <property name="Machine" type="sstr"/>
+ <property name="MyAddress" type="sstr" desc=""/>
+
+ <!-- NOTE: MonitorSelf* statistics are currently missing in 7.0.0 -->
+ <group name="daemon-stats"/>
+
+ <method name="GetLimits">
+ <arg name="Limits" dir="O" type="map"/>
+ </method>
+
+ <method name="SetLimit">
+ <arg name="Name" dir="I" type="sstr"/>
+ <arg name="Max" dir="I" type="double"/>
+ </method>
+
+ <method name="GetStats">
+ <arg name="Name" dir="I" type="sstr"
desc="User or group name"/>
+ <arg name="Ad" dir="O" type="map"/>
+<!--
+ <arg name="Effective" dir="O" type="double"/>
+ <arg name="Real" dir="O" type="double"/>
+ <arg name="Factor" dir="O" type="double"/>
+ <arg name="Resources" dir="O" type="unit32"/>
+ <arg name="Usage" dir="O" type="double"
units="hours"/>
+-->
+ </method>
+
+ <method name="SetPriority">
+ <arg name="Name" dir="I" type="sstr"
desc="User or group name"/>
+ <arg name="Priority" dir="I" type="double"/>
+ </method>
+
+ <method name="SetPriorityFactor">
+ <arg name="Name" dir="I" type="sstr"
desc="User or group name"/>
+ <arg name="PriorityFactor" dir="I"
type="double"/>
+ </method>
+
+ <method name="SetUsage">
+ <arg name="Name" dir="I" type="sstr"
desc="User or group name"/>
+ <arg name="Usage" dir="I" type="double"/>
+ </method>
+
+ <!--
+ <method name="GetStaticQuota">
+ <arg name="Name" dir="I" type="sstr"
desc="Group name"/>
+ <arg name="Quota" dir="O" type="uint32"/>
+ </method>
+
+ <method name="GetDynamicQuota">
+ <arg name="Name" dir="I" type="sstr"
desc="Group name"/>
+ <arg name="Quota" dir="O" type="double"/>
+ </method>
+
+ <method name="SetStaticQuota">
+ <arg name="Name" dir="I" type="sstr"
desc="Group name"/>
+ <arg name="Quota" dir="I" type="uint32"/>
+ </method>
+
+ <method name="SetDynamicQuota">
+ <arg name="Name" dir="I" type="sstr"
desc="Group name"/>
+ <arg name="Quota" dir="I" type="double"/>
+ </method>
+-->
+
+ <method name="GetRawConfig">
+ <arg name="Name" dir="I" type="sstr"
desc="Config param name"/>
+ <arg name="Value" dir="O" type="lstr"/>
+ </method>
+
+ <method name="SetRawConfig">
+ <arg name="Name" dir="I" type="sstr"
desc="Config param name"/>
+ <arg name="Value" dir="I" type="lstr"/>
+ </method>
+
+ <method name="Reconfig"/>
+ </class>
+
+ <class name="Collector">
+ <property name="Pool" type="sstr" index="y"/>
+ <property name="System" type="sstr" index="y"/>
+
+ <property name="CondorPlatform" type="sstr"/>
+ <property name="CondorVersion" type="sstr"/>
+ <property name="Name" type="sstr" index="y"/>
+ <property name="PublicNetworkIpAddr" type="sstr"/>
+
+ <statistic name="RunningJobs" type="uint32"/>
+ <statistic name="IdleJobs" type="uint32"/>
+ <statistic name="HostsTotal" type="uint32"/>
+ <statistic name="HostsClaimed" type="uint32"/>
+ <statistic name="HostsUnclaimed" type="uint32"/>
+ <statistic name="HostsOwner" type="uint32"/>
+ </class>
+
+ <class name="Master">
+
+ <group name="daemon-stats"/>
+
+ <property name="Pool" type="sstr" index="y"/>
+ <property name="System" type="sstr" index="y"/>
+
+ <property name="Name" type="sstr" index="y"/>
+ <property name="Machine" type="sstr"/>
+ <property name="PublicNetworkIpAddr" type="sstr"/>
+ <property name="MyAddress" type="sstr"/>
+ <property name="RealUid" type="int32"/>
+
+ <method name="Start">
+ <arg name="Subsystem"
+ dir="I" type="sstr"
+ desc="The component/subsystem to start: one of STARTD,
+ SCHEDD, COLLECTOR, NEGOTIATOR, KBDD or QUILL"/>
+ </method>
+
+ <method name="Stop">
+ <arg name="Subsystem"
+ dir="I" type="sstr"
+ desc="The component/subsystem to stop: one of STARTD,
+ SCHEDD, COLLECTOR, NEGOTIATOR, KBDD or QUILL"/>
+ </method>
+ </class>
+
+ <class name="Grid">
+ <property name="Pool" type="sstr" index="y"/>
+
+ <property name="Name" type="sstr"/>
+ <property name="ScheddName" type="sstr"/>
+ <property name="Owner" type="sstr"/>
+
+ <statistic name="NumJobs" type="uint32"/>
+ <property name="JobLimit"
+ type="uint32"
+ desc="Maximum number of jobs that can be in the process
+ of being submitted at any time."/>
+ <property name="SubmitLimit"
+ type="uint32"
+ desc="Limit on the number of jobs that will be submitted
+ to the grid resource at once."/>
+
+ <statistic name="SubmitsInProgress" type="uint32"/>
+ <statistic name="SubmitsQueued" type="uint32"/>
+ <statistic name="SubmitsAllowed" type="uint32"/>
+ <statistic name="SubmitsWanted" type="uint32"/>
+
+ <property name="GridResourceUnavailableTime"
+ type="absTime" unit="nanosecond"
+ optional="y"
+ desc="If present, the Grid is down for the specified
+ amount of time."/>
+
+ <statistic name="RunningJobs" type="uint32"/>
+ <statistic name="IdleJobs" type="uint32"/>
+ </class>
+</schema>
Added: mgmt/trunk/cumin/metadata/qmf/qpid-acl.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/qpid-acl.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/qpid-acl.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,44 @@
+<schema package="org.apache.qpid.acl">
+
+<!--
+ * Copyright (c) 2008 The Apache Software Foundation
+ *
+ * Licensed 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.
+-->
+
+ <class name="Acl">
+ <property name="brokerRef" type="objId"
references="org.apache.qpid.broker:Broker" access="RO"
index="y" parentRef="y"/>
+ <property name="policyFile" type="sstr"
access="RO" desc="Name of the policy file"/>
+ <property name="enforcingAcl" type="bool"
access="RO" desc="Currently Enforcing ACL"/>
+ <property name="transferAcl" type="bool"
access="RO" desc="Any transfer ACL rules in force"/>
+ <property name="lastAclLoad" type="absTime"
access="RO" desc="Timestamp of last successful load of ACL"/>
+ <statistic name="aclDenyCount" type="count64"
unit="request" desc="Number of ACL requests denied"/>
+
+ <method name="reloadACLFile" desc="Reload the ACL file"/>
+ </class>
+
+ <eventArguments>
+ <arg name="action" type="sstr"/>
+ <arg name="arguments" type="map"/>
+ <arg name="objectName" type="sstr"/>
+ <arg name="objectType" type="sstr"/>
+ <arg name="reason" type="sstr"/>
+ <arg name="userId" type="sstr"/>
+ </eventArguments>
+
+ <event name="allow" sev="inform" args="userId,
action, objectType, objectName, arguments"/>
+ <event name="deny" sev="notice" args="userId,
action, objectType, objectName, arguments"/>
+ <event name="fileLoaded" sev="inform"
args="userId"/>
+ <event name="fileLoadFailed" sev="error" args="userId,
reason"/>
+
+</schema>
Added: mgmt/trunk/cumin/metadata/qmf/qpid-cluster.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/qpid-cluster.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/qpid-cluster.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,61 @@
+<schema package="org.apache.qpid.cluster">
+
+ <!--
+ 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.
+ -->
+
+ <!-- Type information:
+
+Numeric types with "_wm" suffix are watermarked numbers. These are compound
+values containing a current value, and a low and high water mark for the reporting
+interval. The low and high water marks are set to the current value at the
+beginning of each interval and track the minimum and maximum values of the statistic
+over the interval respectively.
+
+Access rights for configuration elements:
+
+RO => Read Only
+RC => Read/Create, can be set at create time only, read-only thereafter
+RW => Read/Write
+
+If access rights are omitted for a property, they are assumed to be RO.
+
+ -->
+
+ <class name="Cluster">
+ <property name="brokerRef" type="objId"
references="Broker" access="RC" index="y"
parentRef="y"/>
+ <property name="clusterName" type="sstr"
access="RC" desc="Name of cluster this server is a member of"/>
+ <property name="clusterID" type="sstr"
access="RO" desc="Globally unique ID (UUID) for this cluster
instance"/>
+ <property name="memberID" type="sstr"
access="RO" desc="ID of this member of the cluster"/>
+ <property name="publishedURL" type="sstr"
access="RC" desc="URL this node advertizes itself as"/>
+ <property name="clusterSize" type="uint16"
access="RO" desc="Number of brokers currently in the cluster"/>
+ <property name="status" type="sstr"
access="RO" desc="Cluster node status (STALLED,ACTIVE,JOINING)"/>
+ <property name="members" type="lstr"
access="RO" desc="List of member URLs delimited by ';'"/>
+ <property name="memberIDs" type="lstr"
access="RO" desc="List of member IDs delimited by ';'"/>
+
+ <method name="stopClusterNode">
+ <arg name="brokerId" type="sstr" dir="I"/>
+ </method>
+ <method name="stopFullCluster"/>
+
+ </class>
+
+
+
+</schema>
+
Added: mgmt/trunk/cumin/metadata/qmf/qpid-store.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/qpid-store.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/qpid-store.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,103 @@
+<schema package="com.redhat.rhm.store">
+
+<!--
+ Copyright (c) 2007, 2008 Red Hat, Inc.
+
+ This file is part of the Qpid async store library msgstore.so.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
+ USA
+
+ The GNU Lesser General Public License is available in the file COPYING.
+ -->
+
+ <class name="Store">
+ <property name="brokerRef" type="objId"
access="RO" references="qpid.Broker" index="y"
parentRef="y"/>
+ <property name="location" type="sstr"
access="RO" desc="Logical directory on disk"/>
+ <property name="defaultInitialFileCount" type="uint16"
access="RO" unit="file" desc="Default number of files initially
allocated to each journal"/>
+ <property name="defaultDataFileSize" type="uint32"
access="RO" unit="RdPg" desc="Default size of each journal data
file"/>
+ <property name="tplIsInitialized" type="bool"
access="RO" desc="Transaction prepared list has been
initialized by a transactional prepare"/>
+ <property name="tplDirectory" type="sstr"
access="RO" desc="Transaction prepared list
directory"/>
+ <property name="tplWritePageSize" type="uint32"
access="RO" unit="byte" desc="Page size in transaction prepared
list write-page-cache"/>
+ <property name="tplWritePages" type="uint32"
access="RO" unit="wpage" desc="Number of pages in transaction
prepared list write-page-cache"/>
+ <property name="tplInitialFileCount" type="uint16"
access="RO" unit="file" desc="Number of files initially
allocated to transaction prepared list journal"/>
+ <property name="tplDataFileSize" type="uint32"
access="RO" unit="byte" desc="Size of each journal data file in
transaction prepared list journal"/>
+ <property name="tplCurrentFileCount" type="uint32"
access="RO" unit="file" desc="Number of files currently
allocated to transaction prepared list journal"/>
+
+ <statistic name="tplTransactionDepth" type="hilo32"
unit="txn" desc="Number of currently enqueued prepared
transactions"/>
+ <statistic name="tplTxnPrepares" type="count64"
unit="record" desc="Total transaction prepares on transaction prepared
list"/>
+ <statistic name="tplTxnCommits" type="count64"
unit="record" desc="Total transaction commits on transaction prepared
list"/>
+ <statistic name="tplTxnAborts" type="count64"
unit="record" desc="Total transaction aborts on transaction prepared
list"/>
+ <statistic name="tplOutstandingAIOs" type="hilo32"
unit="aio_op" desc="Number of currently outstanding AIO requests in Async
IO system"/>
+ </class>
+
+ <class name="Journal">
+ <property name="queueRef" type="objId"
access="RO" references="qpid.Queue"
isGeneralReference="y"/>
+ <property name="name" type="sstr"
access="RO" index="y"/>
+ <property name="directory" type="sstr"
access="RO" desc="Directory containing journal
files"/>
+ <property name="baseFileName" type="sstr"
access="RO" desc="Base filename prefix for journal"/>
+ <property name="writePageSize" type="uint32"
access="RO" unit="byte" desc="Page size in
write-page-cache"/>
+ <property name="writePages" type="uint32"
access="RO" unit="wpage" desc="Number of pages in
write-page-cache"/>
+ <property name="readPageSize" type="uint32"
access="RO" unit="byte" desc="Page size in
read-page-cache"/>
+ <property name="readPages" type="uint32"
access="RO" unit="rpage" desc="Number of pages in
read-page-cache"/>
+ <property name="initialFileCount" type="uint16"
access="RO" unit="file" desc="Number of files initially
allocated to this journal"/>
+ <property name="autoExpand" type="bool"
access="RO" desc="Auto-expand enabled"/>
+ <property name="currentFileCount" type="uint16"
access="RO" unit="file" desc="Number of files currently
allocated to this journal"/>
+ <property name="maxFileCount" type="uint16"
access="RO" unit="file" desc="Max number of files allowed for
this journal"/>
+ <property name="dataFileSize" type="uint32"
access="RO" unit="byte" desc="Size of each journal data
file"/>
+
+ <statistic name="recordDepth" type="hilo32"
unit="record" desc="Number of currently enqueued records (durable
messages)"/>
+ <statistic name="enqueues" type="count64"
unit="record" desc="Total enqueued records on journal"/>
+ <statistic name="dequeues" type="count64"
unit="record" desc="Total dequeued records on journal"/>
+ <statistic name="txn" type="count32"
unit="record" desc="Total open transactions (xids) on journal"/>
+ <statistic name="txnEnqueues" type="count64"
unit="record" desc="Total transactional enqueued records on
journal"/>
+ <statistic name="txnDequeues" type="count64"
unit="record" desc="Total transactional dequeued records on
journal"/>
+ <statistic name="txnCommits" type="count64"
unit="record" desc="Total transactional commit records on
journal"/>
+ <statistic name="txnAborts" type="count64"
unit="record" desc="Total transactional abort records on
journal"/>
+ <statistic name="outstandingAIOs" type="hilo32"
unit="aio_op" desc="Number of currently outstanding AIO requests in Async
IO system"/>
+
+<!--
+ The following are not yet "wired up" in JournalImpl.cpp
+-->
+ <statistic name="freeFileCount" type="hilo32"
unit="file" desc="Number of files free on this journal. Includes free
files trapped in holes."/>
+ <statistic name="availableFileCount" type="hilo32"
unit="file" desc="Number of files available to be written. Excluding
holes"/>
+ <statistic name="writeWaitFailures" type="count64"
unit="record" desc="AIO Wait failures on write"/>
+ <statistic name="writeBusyFailures" type="count64"
unit="record" desc="AIO Busy failures on write"/>
+ <statistic name="readRecordCount" type="count64"
unit="record" desc="Records read from the journal"/>
+ <statistic name="readBusyFailures" type="count64"
unit="record" desc="AIO Busy failures on read"/>
+ <statistic name="writePageCacheDepth" type="hilo32"
unit="wpage" desc="Current depth of write-page-cache"/>
+ <statistic name="readPageCacheDepth" type="hilo32"
unit="rpage" desc="Current depth of read-page-cache"/>
+
+ <method name="expand" desc="Increase number of files allocated for
this journal">
+ <arg name="by" type="uint32" dir="I"
desc="Number of files to increase journal size by"/>
+ </method>
+ </class>
+
+ <eventArguments>
+ <arg name="autoExpand" type="bool" desc="Journal
auto-expand enabled"/>
+ <arg name="fileSize" type="uint32" desc="Journal file
size in bytes"/>
+ <arg name="jrnlId" type="sstr" desc="Journal
Id"/>
+ <arg name="numEnq" type="uint32" desc="Number of
recovered enqueues"/>
+ <arg name="numFiles" type="uint16" desc="Number of
journal files"/>
+ <arg name="numTxn" type="uint32" desc="Number of
recovered transactions"/>
+ <arg name="numTxnDeq" type="uint32" desc="Number of
recovered transactional dequeues"/>
+ <arg name="numTxnEnq" type="uint32" desc="Number of
recovered transactional enqueues"/>
+ <arg name="what" type="sstr" desc="Description of
event"/>
+ </eventArguments>
+ <event name="enqThresholdExceeded" sev="warn"
args="jrnlId, what"/>
+ <event name="created" sev="notice"
args="jrnlId, fileSize, numFiles"/>
+ <event name="full" sev="error"
args="jrnlId, what"/>
+ <event name="recovered" sev="notice"
args="jrnlId, fileSize, numFiles, numEnq, numTxn, numTxnEnq, numTxnDeq"/>
+</schema>
Added: mgmt/trunk/cumin/metadata/qmf/qpid.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/qpid.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/qpid.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,340 @@
+<schema package="org.apache.qpid.broker">
+
+<!--
+ 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.
+-->
+
+ <!-- Type information:
+
+ Numeric types with "_wm" suffix are watermarked numbers. These are
compound
+ values containing a current value, and a low and high water mark for the
reporting
+ interval. The low and high water marks are set to the current value at the
+ beginning of each interval and track the minimum and maximum values of the
statistic
+ over the interval respectively.
+
+ Access rights for configuration elements:
+
+ RO => Read Only
+ RC => Read/Create, can be set at create time only, read-only thereafter
+ RW => Read/Write
+
+ If access rights are omitted for a property, they are assumed to be RO.
+
+ -->
+
+ <!-- Questions: Does C++ broker round-robin dests on queues? -->
+
+ <!--
+ ===============================================================
+ System
+ ===============================================================
+ -->
+ <class name="System">
+ <property name="systemId" index="y" type="uuid"
access="RC"/>
+
+ <property name="osName" type="sstr" access="RO"
desc="Operating System Name"/>
+ <property name="nodeName" type="sstr" access="RO"
desc="Node Name"/>
+ <property name="release" type="sstr"
access="RO"/>
+ <property name="version" type="sstr"
access="RO"/>
+ <property name="machine" type="sstr"
access="RO"/>
+
+ </class>
+
+ <!--
+ ===============================================================
+ Broker
+ ===============================================================
+ -->
+ <class name="Broker">
+ <property name="systemRef" type="objId"
references="System" access="RC" index="y" desc="System
ID" parentRef="y"/>
+ <property name="port" type="uint16"
access="RC" index="y" desc="TCP Port for AMQP Service"/>
+ <property name="workerThreads" type="uint16"
access="RO" desc="Thread pool size"/>
+ <property name="maxConns" type="uint16"
access="RO" desc="Maximum allowed connections"/>
+ <property name="connBacklog" type="uint16"
access="RO" desc="Connection backlog limit for listening socket"/>
+ <property name="stagingThreshold" type="uint32"
access="RO" desc="Broker stages messages over this size to disk"/>
+ <property name="mgmtPubInterval" type="uint16"
access="RW" unit="second" min="1" desc="Interval for
management broadcasts"/>
+ <property name="version" type="sstr"
access="RO" desc="Running software version"/>
+ <property name="dataDir" type="sstr"
access="RO" optional="y" desc="Persistent configuration storage
location"/>
+ <statistic name="uptime" type="deltaTime"/>
+
+ <method name="echo" desc="Request a response to test the path to
the management broker">
+ <arg name="sequence" dir="IO" type="uint32"
default="0"/>
+ <arg name="body" dir="IO" type="lstr"
default=""/>
+ </method>
+
+ <method name="connect" desc="Establish a connection to another
broker">
+ <arg name="host" dir="I"
type="sstr"/>
+ <arg name="port" dir="I"
type="uint32"/>
+ <arg name="durable" dir="I"
type="bool"/>
+ <arg name="authMechanism" dir="I"
type="sstr"/>
+ <arg name="username" dir="I"
type="sstr"/>
+ <arg name="password" dir="I"
type="sstr"/>
+ <arg name="transport" dir="I"
type="sstr"/>
+ </method>
+
+ <method name="queueMoveMessages" desc="Move messages from one queue
to another">
+ <arg name="srcQueue" dir="I" type="sstr"
desc="Source queue"/>
+ <arg name="destQueue" dir="I" type="sstr"
desc="Destination queue"/>
+ <arg name="qty" dir="I"
type="uint32" desc="# of messages to move. 0 means all messages"/>
+ </method>
+
+ </class>
+
+ <!--
+ ===============================================================
+ Management Agent
+ ===============================================================
+ -->
+ <class name="Agent">
+ <property name="connectionRef" type="objId"
references="Connection" access="RO" index="y"/>
+ <property name="label" type="sstr"
access="RO" desc="Label for agent"/>
+ <property name="registeredTo" type="objId"
references="Broker" access="RO" desc="Broker agent is registered
to"/>
+ <property name="systemId" type="uuid"
access="RO" desc="Identifier of system where agent
resides"/>
+ <property name="brokerBank" type="uint32"
access="RO" desc="Assigned object-id broker bank"/>
+ <property name="agentBank" type="uint32"
access="RO" desc="Assigned object-id agent bank"/>
+ </class>
+
+ <!--
+ ===============================================================
+ Virtual Host
+ ===============================================================
+ -->
+ <class name="Vhost">
+ <property name="brokerRef" type="objId"
references="Broker" access="RC" index="y"
parentRef="y"/>
+ <property name="name" type="sstr"
access="RC" index="y"/>
+ <property name="federationTag" type="sstr"
access="RO"/>
+ </class>
+
+ <!--
+ ===============================================================
+ Queue
+ ===============================================================
+ -->
+ <class name="Queue">
+ <property name="vhostRef" type="objId"
references="Vhost" access="RC" index="y"
parentRef="y"/>
+ <property name="name" type="sstr" access="RC"
index="y"/>
+
+ <property name="durable" type="bool"
access="RC"/>
+ <property name="autoDelete" type="bool"
access="RC"/>
+ <property name="exclusive" type="bool"
access="RC"/>
+ <property name="arguments" type="map" access="RO"
desc="Arguments supplied in queue.declare"/>
+
+ <statistic name="msgTotalEnqueues" type="count64"
unit="message" desc="Total messages enqueued"/>
+ <statistic name="msgTotalDequeues" type="count64"
unit="message" desc="Total messages dequeued"/>
+ <statistic name="msgTxnEnqueues" type="count64"
unit="message" desc="Transactional messages enqueued"/>
+ <statistic name="msgTxnDequeues" type="count64"
unit="message" desc="Transactional messages dequeued"/>
+ <statistic name="msgPersistEnqueues" type="count64"
unit="message" desc="Persistent messages enqueued"/>
+ <statistic name="msgPersistDequeues" type="count64"
unit="message" desc="Persistent messages dequeued"/>
+ <statistic name="msgDepth" type="count32"
unit="message" desc="Current size of queue in messages"
assign="msgTotalEnqueues - msgTotalDequeues"/>
+ <statistic name="byteDepth" type="count32"
unit="octet" desc="Current size of queue in bytes"
assign="byteTotalEnqueues - byteTotalDequeues"/>
+ <statistic name="byteTotalEnqueues" type="count64"
unit="octet" desc="Total messages enqueued"/>
+ <statistic name="byteTotalDequeues" type="count64"
unit="octet" desc="Total messages dequeued"/>
+ <statistic name="byteTxnEnqueues" type="count64"
unit="octet" desc="Transactional messages enqueued"/>
+ <statistic name="byteTxnDequeues" type="count64"
unit="octet" desc="Transactional messages dequeued"/>
+ <statistic name="bytePersistEnqueues" type="count64"
unit="octet" desc="Persistent messages enqueued"/>
+ <statistic name="bytePersistDequeues" type="count64"
unit="octet" desc="Persistent messages dequeued"/>
+ <statistic name="consumerCount" type="hilo32"
unit="consumer" desc="Current consumers on queue"/>
+ <statistic name="bindingCount" type="hilo32"
unit="binding" desc="Current bindings"/>
+ <statistic name="unackedMessages" type="hilo32"
unit="message" desc="Messages consumed but not yet acked"/>
+ <statistic name="messageLatency" type="mmaTime"
unit="nanosecond" desc="Broker latency through this queue"/>
+
+ <method name="purge" desc="Discard all or some messages on a
queue">
+ <arg name="request" dir="I" type="uint32"
desc="0 for all messages or n>0 for n messages"/>
+ </method>
+ </class>
+
+ <!--
+ ===============================================================
+ Exchange
+ ===============================================================
+ -->
+ <class name="Exchange">
+ <property name="vhostRef" type="objId"
references="Vhost" access="RC" index="y"
parentRef="y"/>
+ <property name="name" type="sstr" access="RC"
index="y"/>
+ <property name="type" type="sstr"
access="RO"/>
+ <property name="durable" type="bool"
access="RC"/>
+ <property name="arguments" type="map" access="RO"
desc="Arguments supplied in exchange.declare"/>
+
+ <statistic name="producerCount" type="hilo32"
desc="Current producers on exchange"/>
+ <statistic name="bindingCount" type="hilo32"
desc="Current bindings"/>
+ <statistic name="msgReceives" type="count64"
desc="Total messages received"/>
+ <statistic name="msgDrops" type="count64"
desc="Total messages dropped (no matching key)"/>
+ <statistic name="msgRoutes" type="count64"
desc="Total routed messages"/>
+ <statistic name="byteReceives" type="count64"
desc="Total bytes received"/>
+ <statistic name="byteDrops" type="count64"
desc="Total bytes dropped (no matching key)"/>
+ <statistic name="byteRoutes" type="count64"
desc="Total routed bytes"/>
+ </class>
+
+ <!--
+ ===============================================================
+ Binding
+ ===============================================================
+ -->
+ <class name="Binding">
+ <property name="exchangeRef" type="objId"
references="Exchange" access="RC" index="y"
parentRef="y"/>
+ <property name="queueRef" type="objId"
references="Queue" access="RC" index="y"/>
+ <property name="bindingKey" type="sstr"
access="RC" index="y"/>
+ <property name="arguments" type="map"
access="RC"/>
+ <property name="origin" type="sstr"
access="RO" optional="y"/>
+
+ <statistic name="msgMatched" type="count64"/>
+ </class>
+
+ <!--
+ ===============================================================
+ Connection
+ ===============================================================
+ -->
+ <class name="Connection">
+ <property name="vhostRef" type="objId"
references="Vhost" access="RC" index="y"
parentRef="y"/>
+ <property name="address" type="sstr" access="RC"
index="y"/>
+ <property name="incoming" type="bool"
access="RC"/>
+ <property name="SystemConnection" type="bool"
access="RC" desc="Infrastucture/ Inter-system connection (Cluster,
Federation, ...)"/>
+ <property name="federationLink" type="bool"
access="RO" desc="Is this a federation link"/>
+ <property name="authIdentity" type="sstr"
access="RO" desc="authId of connection if authentication
enabled"/>
+ <property name="remoteProcessName" type="sstr"
access="RO" optional="y" desc="Name of executable running as
remote client"/>
+ <property name="remotePid" type="uint32"
access="RO" optional="y" desc="Process ID of remote
client"/>
+ <property name="remoteParentPid" type="uint32"
access="RO" optional="y" desc="Parent Process ID of remote
client"/>
+ <statistic name="closing" type="bool" desc="This
client is closing by management request"/>
+ <statistic name="framesFromClient" type="count64"/>
+ <statistic name="framesToClient" type="count64"/>
+ <statistic name="bytesFromClient" type="count64"/>
+ <statistic name="bytesToClient" type="count64"/>
+
+ <method name="close"/>
+ </class>
+
+ <!--
+ ===============================================================
+ Link
+ ===============================================================
+ -->
+ <class name="Link">
+
+ This class represents an inter-broker connection.
+
+ <property name="vhostRef" type="objId"
references="Vhost" access="RC" index="y"
parentRef="y"/>
+ <property name="host" type="sstr" access="RC"
index="y"/>
+ <property name="port" type="uint16" access="RC"
index="y"/>
+ <property name="transport" type="sstr"
access="RC"/>
+ <property name="durable" type="bool"
access="RC"/>
+
+ <statistic name="state" type="sstr"
desc="Operational state of the link"/>
+ <statistic name="lastError" type="sstr" desc="Reason
link is not operational"/>
+
+ <method name="close"/>
+
+ <method name="bridge" desc="Bridge messages over the
link">
+ <arg name="durable" dir="I" type="bool"/>
+ <arg name="src" dir="I" type="sstr"/>
+ <arg name="dest" dir="I" type="sstr"/>
+ <arg name="key" dir="I" type="sstr"/>
+ <arg name="tag" dir="I" type="sstr"/>
+ <arg name="excludes" dir="I" type="sstr"/>
+ <arg name="srcIsQueue" dir="I" type="bool"/>
+ <arg name="srcIsLocal" dir="I" type="bool"/>
+ <arg name="dynamic" dir="I" type="bool"/>
+ <arg name="sync" dir="I"
type="uint16"/>
+ </method>
+ </class>
+
+
+ <!--
+ ===============================================================
+ Bridge
+ ===============================================================
+ -->
+ <class name="Bridge">
+ <property name="linkRef" type="objId"
references="Link" access="RC" index="y"
parentRef="y"/>
+ <property name="channelId" type="uint16"
access="RC" index="y"/>
+ <property name="durable" type="bool"
access="RC"/>
+ <property name="src" type="sstr"
access="RC"/>
+ <property name="dest" type="sstr"
access="RC"/>
+ <property name="key" type="sstr"
access="RC"/>
+ <property name="srcIsQueue" type="bool"
access="RC"/>
+ <property name="srcIsLocal" type="bool"
access="RC"/>
+ <property name="tag" type="sstr"
access="RC"/>
+ <property name="excludes" type="sstr"
access="RC"/>
+ <property name="dynamic" type="bool"
access="RC"/>
+ <property name="sync" type="uint16"
access="RC"/>
+ <method name="close"/>
+ </class>
+
+
+ <!--
+ ===============================================================
+ Session
+ ===============================================================
+ -->
+ <class name="Session">
+ <property name="vhostRef" type="objId"
references="Vhost" access="RC" index="y"
parentRef="y"/>
+ <property name="name" type="sstr"
access="RC" index="y"/>
+ <property name="channelId" type="uint16"
access="RO"/>
+ <property name="connectionRef" type="objId"
references="Connection" access="RO"/>
+ <property name="detachedLifespan" type="uint32"
access="RO" unit="second"/>
+ <property name="attached" type="bool"
access="RO"/>
+ <property name="expireTime" type="absTime"
access="RO" optional="y"/>
+ <property name="maxClientRate" type="uint32"
access="RO" unit="msgs/sec" optional="y"/>
+
+ <statistic name="framesOutstanding" type="count32"/>
+
+ <statistic name="TxnStarts" type="count64"
unit="transaction" desc="Total transactions started "/>
+ <statistic name="TxnCommits" type="count64"
unit="transaction" desc="Total transactions committed"/>
+ <statistic name="TxnRejects" type="count64"
unit="transaction" desc="Total transactions rejected"/>
+ <statistic name="TxnCount" type="count32"
unit="transaction" desc="Current pending transactions"/>
+
+ <statistic name="clientCredit" type="count32"
unit="message" desc="Client message credit"/>
+
+ <method name="solicitAck"/>
+ <method name="detach"/>
+ <method name="resetLifespan"/>
+ <method name="close"/>
+ </class>
+
+ <eventArguments>
+ <arg name="altEx" type="sstr" desc="Name of the
alternate exchange"/>
+ <arg name="args" type="map" desc="Supplemental
arguments or parameters supplied"/>
+ <arg name="autoDel" type="bool" desc="Created object is
automatically deleted when no longer in use"/>
+ <arg name="dest" type="sstr" desc="Destination tag
for a subscription"/>
+ <arg name="disp" type="sstr" desc="Disposition of a
declaration: 'created' if object was created, 'existing' if object already
existed"/>
+ <arg name="durable" type="bool" desc="Created object is
durable"/>
+ <arg name="exName" type="sstr" desc="Name of an
exchange"/>
+ <arg name="exType" type="sstr" desc="Type of an
exchange"/>
+ <arg name="excl" type="bool" desc="Created object is
exclusive for the use of the owner only"/>
+ <arg name="key" type="lstr" desc="Key text used for
routing or binding"/>
+ <arg name="qName" type="sstr" desc="Name of a
queue"/>
+ <arg name="reason" type="lstr" desc="Reason for a
failure"/>
+ <arg name="rhost" type="sstr" desc="Address (i.e. DNS
name, IP address, etc.) of a remotely connected host"/>
+ <arg name="user" type="sstr" desc="Authentication
identity"/>
+ </eventArguments>
+
+ <event name="clientConnect" sev="inform" args="rhost,
user"/>
+ <event name="clientConnectFail" sev="warn" args="rhost,
user, reason"/>
+ <event name="clientDisconnect" sev="inform" args="rhost,
user"/>
+ <event name="brokerLinkUp" sev="inform"
args="rhost"/>
+ <event name="brokerLinkDown" sev="warn"
args="rhost"/>
+ <event name="queueDeclare" sev="inform" args="rhost,
user, qName, durable, excl, autoDel, args, disp"/>
+ <event name="queueDelete" sev="inform" args="rhost,
user, qName"/>
+ <event name="exchangeDeclare" sev="inform" args="rhost,
user, exName, exType, altEx, durable, autoDel, args, disp"/>
+ <event name="exchangeDelete" sev="inform" args="rhost,
user, exName"/>
+ <event name="bind" sev="inform" args="rhost,
user, exName, qName, key, args"/>
+ <event name="unbind" sev="inform" args="rhost,
user, exName, qName, key"/>
+ <event name="subscribe" sev="inform" args="rhost,
user, qName, dest, excl, args"/>
+ <event name="unsubscribe" sev="inform" args="rhost,
user, dest"/>
+</schema>
+
Added: mgmt/trunk/cumin/metadata/qmf/sesame.xml
===================================================================
--- mgmt/trunk/cumin/metadata/qmf/sesame.xml (rev 0)
+++ mgmt/trunk/cumin/metadata/qmf/sesame.xml 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,31 @@
+<schema package="com.redhat.sesame">
+
+ <class name="Sysimage">
+ <property name="uuid" index="y" type="uuid"
access="RC" desc="UUID of System Image"/>
+
+ <property name="osName" type="sstr" access="RO"
desc="Operating System Name"/>
+ <property name="nodeName" type="sstr" access="RO"
desc="Node Name"/>
+ <property name="release" type="sstr"
access="RO"/>
+ <property name="version" type="sstr"
access="RO"/>
+ <property name="machine" type="sstr"
access="RO"/>
+ <property name="distro" type="sstr" access="RO"
optional="y"/>
+
+ <property name="memTotal" type="uint32" access="RO"
unit="kByte"/>
+ <property name="swapTotal" type="uint32" access="RO"
unit="kByte"/>
+
+ The following statistics are gathered from /proc/meminfo
+
+ <statistic name="memFree" type="uint32"
unit="kByte"/>
+ <statistic name="swapFree" type="uint32"
unit="kByte"/>
+
+ The following statistics are gathered from /proc/loadavg
+
+ <statistic name="loadAverage1Min" type="float"/>
+ <statistic name="loadAverage5Min" type="float"/>
+ <statistic name="loadAverage10Min" type="float"/>
+ <statistic name="procTotal" type="uint32"/>
+ <statistic name="procRunning" type="uint32"/>
+ </class>
+
+</schema>
+
Modified: mgmt/trunk/cumin/python/cumin/__init__.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/__init__.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/__init__.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -1,4 +1,4 @@
-import sys, os
+import sys, os, logging
from random import randint
from parsley.config import Config, ConfigParameter
@@ -12,7 +12,7 @@
from time import sleep
from threading import Thread, Event
from urllib import quote
-from model import CuminModel, ModelPage, CallPage
+from model import CuminModel, CallPage
from demo import DemoData
from page import MainPage
from stat import StatChartPage, StatStackedPage, SlotMapPage
@@ -20,12 +20,17 @@
from account import LoginPage, AccountPage
from datetime import timedelta
from qpid.util import URL
+from widgets import CuminFormPage
from wooly import Session
+import account
+import messaging
+import grid
+import inventory
import usergrid
-log = getLogger("cumin")
+log = logging.getLogger("cumin")
class Cumin(Application):
def __init__(self, config):
@@ -47,18 +52,19 @@
self.add_page(self.main_page)
self.set_default_page(self.main_page)
+ self.form_page = FormPage(self, "form.html")
+ self.add_page(self.form_page)
+
+ # XXX move this to the account module
self.account_page = AccountPage(self, "account.html")
self.add_page(self.account_page)
+
self.add_page(DevelPage(self, "devel.html"))
- self.add_page(ModelPage(self, "model.xml"))
self.add_page(CallPage(self, "call.xml"))
self.add_page(StatChartPage(self, "stats.png"))
self.add_page(StatStackedPage(self, "stacked.png"))
self.add_page(SlotMapPage(self, "slots.png"))
- self.user_grid_page = usergrid.MainPage(self, "usergrid.html")
- self.add_page(self.user_grid_page)
-
unprotected = set()
unprotected.add(self.main_page.css_page)
@@ -83,10 +89,20 @@
self.model.check()
def init(self):
- super(Cumin, self).init()
+ modules = list()
+ modules.append(account.module)
+ modules.append(messaging.module)
+ modules.append(grid.module)
+ modules.append(inventory.module)
+ modules.append(usergrid.module)
+ for module in modules:
+ module.init(self)
+
self.model.init()
+ super(Cumin, self).init()
+
def start(self):
self.model.start()
self.user_session_expire_thread.start()
@@ -175,3 +191,7 @@
if self.debug:
enable_logging("cumin", "debug", sys.stderr)
+
+class FormPage(CuminFormPage):
+ def __init__(self, app, name):
+ super(FormPage, self).__init__(app, name)
Modified: mgmt/trunk/cumin/python/cumin/account/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/account/main.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/account/main.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -3,14 +3,25 @@
from wooly.resources import *
from cumin.widgets import *
+from cumin.modelwidgets import *
from cumin.util import *
from cumin.grid.job import JobTab
from user import UserSession
+from model import *
+
from wooly import Session
strings = StringCatalog(__file__)
+class AccountModule(object):
+ def init(self, app):
+ subject = app.model.subject
+
+ self.change_password = ChangePasswordTask(app, subject)
+
+module = AccountModule()
+
class AccountPage(CuminPage, ModeSet):
def __init__(self, app, name):
super(AccountPage, self).__init__(app, name)
@@ -39,9 +50,6 @@
self.view = AccountView(app, "view")
self.add_mode(self.view)
- self.change_password = ChangePasswordForm(app, "password")
- self.add_mode(self.change_password)
-
def render_title(self, session):
return "Account"
@@ -56,9 +64,8 @@
self.add_tab(self.MyGridJobs(app, "jobs"))
def render_change_password_href(self, session):
- branch = session.branch()
- self.frame.change_password.show(branch)
- return branch.marshal()
+ subject = session.user_session.subject
+ return self.app.change_password.get_href(session, subject)
class Heading(CuminHeading):
def render_title(self, session):
@@ -68,14 +75,20 @@
return "resource?name=action-36.png"
class AccountTab(ActionSet):
+ def __init__(self, app, name):
+ super(AccountView.AccountTab, self).__init__(app, name)
+
+ def init(self):
+ # XXX deferring this, but I don't like it
+ task = module.change_password
+ link = TaskLink(self.app, "change_password", task, None)
+ self.add_child(link)
+
+ super(AccountView.AccountTab, self).init()
+
def render_title(self, session):
return "Account Settings"
- def render_change_password_href(self, session):
- branch = session.branch()
- self.frame.change_password.show(branch)
- return branch.marshal()
-
class MyGridJobs(JobTab):
def render_title(self, session):
return "Your Grid Jobs %s" %
fmt_count(self.get_item_count(session))
@@ -129,19 +142,22 @@
def get_default(self, session):
return Session(self.app.main_page).marshal()
-class LoginForm(FieldForm):
+class LoginForm(Form):
def __init__(self, app, name):
super(LoginForm, self).__init__(app, name)
self.__login_invalid = Attribute(app, "login_invalid")
self.add_attribute(self.__login_invalid)
+ self.fields = FormFieldSet(app, "fields")
+ self.add_child(self.fields)
+
self.__name = self.Name(app, "name")
- self.add_field(self.__name)
+ self.fields.add_field(self.__name)
self.__name.input.size = 20
self.__password = self.Password(app, "password")
- self.add_field(self.__password)
+ self.fields.add_field(self.__password)
self.__password.input.size = 20
self.__submit = self.Submit(app, "submit")
@@ -198,80 +214,3 @@
class Submit(FormButton):
def render_content(self, session):
return "Submit"
-
-class ChangePasswordForm(CuminFieldForm):
- def __init__(self, app, name):
- super(ChangePasswordForm, self).__init__(app, name)
-
- self.__errors = self.Errors(app, "errors")
- self.add_attribute(self.__errors)
-
- self.__current = self.Current(app, "current")
- self.add_field(self.__current)
- self.__current.input.size = 20
-
- self.__new0 = self.New0(app, "new0")
- self.add_field(self.__new0)
- self.__new0.input.size = 20
-
- self.__new1 = self.New1(app, "new1")
- self.add_field(self.__new1)
- self.__new1.input.size = 20
-
- def process_cancel(self, session):
- branch = session.branch()
- self.page.account.main.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_submit(self, session):
- curr = self.__current.get(session)
- new0 = self.__new0.get(session)
- new1 = self.__new1.get(session)
-
- errors = self.validate(session)
-
- subject = session.user_session.subject
- crypted = subject.password
-
- if crypt_password(curr, crypted) != crypted:
- msg = "The current password you entered is incorrect"
- self.__errors.get(session).append(msg)
- errors.append(msg)
-
- if new0 != new1:
- msg = "The new passwords do not match"
- self.__errors.get(session).append(msg)
- errors.append(msg)
-
- if not errors:
- subject.password = crypt_password(new0)
- subject.syncUpdate()
-
- self.process_cancel(session)
-
- def render_title(self, session):
- return "Change Password"
-
- def render_form_error(self, session):
- errors = self.__errors.get(session)
-
- if errors:
- return "<ul class=\"errors\" style=\"margin:0;
float:left;\"><li>" + \
- ("</li><li>".join(errors)) + \
- "</li></ul>"
-
- class Current(PasswordField):
- def render_title(self, session):
- return "Current Password"
-
- class New0(PasswordField):
- def render_title(self, session):
- return "New Password"
-
- class New1(PasswordField):
- def render_title(self, session):
- return "Repeat New Password"
-
- class Errors(Attribute):
- def get_default(self, session):
- return list()
Modified: mgmt/trunk/cumin/python/cumin/account/main.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/account/main.strings 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/account/main.strings 2009-06-17 20:20:11 UTC (rev 3457)
@@ -99,7 +99,7 @@
[AccountTab.html]
<ul class="actions">
- <a class="nav" href="{change_password_href}">Change
Password</a>
+ <li>{change_password}</li>
</ul>
[MyGridJobs.html]
Modified: mgmt/trunk/cumin/python/cumin/account/user.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/account/user.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/account/user.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -48,3 +48,58 @@
count += 1
log.info("Expired %i user sessions", count)
+
+class ChangePasswordForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(ChangePasswordForm, self).__init__(app, name)
+
+ self.task = task
+
+ self.__current = self.Current(app, "current")
+ self.add_field(self.__current)
+ self.__current.input.size = 20
+
+ self.__new0 = self.New0(app, "new0")
+ self.add_field(self.__new0)
+ self.__new0.input.size = 20
+
+ self.__new1 = self.New1(app, "new1")
+ self.add_field(self.__new1)
+ self.__new1.input.size = 20
+
+ def process_submit(self, session):
+ curr = self.__current.get(session)
+ new0 = self.__new0.get(session)
+ new1 = self.__new1.get(session)
+
+ subject = session.user_session.subject
+ crypted = subject.password
+
+ if crypt_password(curr, crypted) != crypted:
+ error = FormError("The password is incorrect", self.__current)
+ self.errors.add(session, error)
+
+ if new0 != new1:
+ error = FormError("The new passwords do not match")
+ self.errors.add(session, error)
+
+ self.check(session)
+
+ if not self.errors.get(session):
+ self.task.invoke(session, subject, new0)
+ self.task.exit_with_redirect(session, subject)
+
+ def render_title(self, session):
+ return "Change password"
+
+ class Current(PasswordField):
+ def render_title(self, session):
+ return "Current password"
+
+ class New0(PasswordField):
+ def render_title(self, session):
+ return "New password"
+
+ class New1(PasswordField):
+ def render_title(self, session):
+ return "Repeat new password"
Modified: mgmt/trunk/cumin/python/cumin/grid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/grid/main.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/grid/main.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -8,6 +8,17 @@
strings = StringCatalog(__file__)
+class GridModule(object):
+ def __init__(self):
+ self.frame = None
+
+ def init(self, app):
+ self.frame = GridFrame(app, "grid")
+ app.main_page.main.grid = self.frame
+ app.main_page.main.add_tab(self.frame)
+
+module = GridModule()
+
class GridFrame(CuminFrame):
def __init__(self, app, name):
super(GridFrame, self).__init__(app, name)
Modified: mgmt/trunk/cumin/python/cumin/inventory/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/inventory/main.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/inventory/main.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -8,6 +8,17 @@
strings = StringCatalog(__file__)
+class InventoryModule(object):
+ def __init__(self):
+ self.frame = None
+
+ def init(self, app):
+ self.frame = InventoryFrame(app, "inventory")
+ app.main_page.main.inventory = self.frame
+ app.main_page.main.add_tab(self.frame)
+
+module = InventoryModule()
+
class InventoryFrame(CuminFrame):
def __init__(self, app, name):
super(InventoryFrame, self).__init__(app, name)
Modified: mgmt/trunk/cumin/python/cumin/messaging/binding.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/binding.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/binding.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -5,14 +5,95 @@
from wooly.parameters import DictParameter
from wooly.resources import StringCatalog
from cumin.util import sorted_by
-from cumin.widgets import SubmitSwitch
+from cumin.widgets import *
+from cumin.modelwidgets import *
from cumin.formats import *
-from exchange import ExchangeInfo
+import main
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.messaging.exchange")
+class BindingSet(CuminSelectionTable):
+ def __init__(self, app, name):
+ item = BindingParameter(app, "item")
+ super(BindingSet, self).__init__(app, name, item)
+
+ col = self.QNameColumn(app, "q_id")
+ col.visible = False
+ self.add_column(col)
+
+ col = self.ENameColumn(app, "e_id")
+ col.visible = False
+ self.add_column(col)
+
+ col = self.KeyColumn(app, "key")
+ self.add_column(col)
+
+ col = self.RateColumn(app, "rate")
+ col.alignment = "right"
+ self.add_column(col)
+
+ col = self.MatchedColumn(app, "matched")
+ col.alignment = "right"
+ self.add_column(col)
+
+ self.phase = PhaseSwitch(app, "phase")
+ self.filters.add_child(self.phase)
+
+ task = main.module.binding_set_remove
+ button = TaskButton(app, "remove", task, self.selection)
+ self.buttons.add_child(button)
+
+ class QNameColumn(SqlTableColumn):
+ def render_title(self, session, data):
+ return "Queue"
+
+ def render_content(self, session, data):
+ queue = Queue.get(data["q_id"])
+ href = self.page.main.messaging.broker.queue.get_href \
+ (session, queue)
+ return fmt_link(href, fmt_shorten(queue.name))
+
+ class ENameColumn(SqlTableColumn):
+ def render_title(self, session, data):
+ return "Exchange"
+
+ def render_content(self, session, data):
+ exchange = Exchange.get(data["e_id"])
+ href = self.page.main.messaging.broker.exchange.get_href \
+ (session, exchange)
+
+ if exchange.name:
+ name = fmt_shorten(exchange.name)
+ else:
+ name = "<em>Default</em>"
+
+ return fmt_link(href, name)
+
+ class KeyColumn(SqlTableColumn):
+ def render_title(self, session, data):
+ return "Key"
+
+ def render_value(self, session, value):
+ return fmt_shorten(value)
+
+ class RateColumn(ItemTableColumn):
+ def render_title(self, session, data):
+ return "Message Rate"
+
+ def render_content(self, session, data):
+ binding = Binding.get(data["id"])
+ return self.app.model.binding.msgMatched.rate_html(binding)
+
+ class MatchedColumn(ItemTableColumn):
+ def render_title(self, session, data):
+ return "Messages Matched"
+
+ def render_content(self, session, data):
+ binding = Binding.get(data["id"])
+ return self.app.model.binding.msgMatched.value(binding)
+
class ExchangeInput(Widget):
def __init__(self, app, name):
super(ExchangeInput, self).__init__(app, name)
@@ -416,3 +497,14 @@
form_binding_info[this_exchange]["arguments"] = arguments
return form_binding_info
+
+class BindingSetTaskForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(BindingSetTaskForm, self).__init__(app, name, task)
+
+ item = BindingParameter(app, "item")
+
+ self.object = ListParameter(app, "binding", item)
+ self.add_parameter(self.object)
+
+from exchange import ExchangeInfo
Modified: mgmt/trunk/cumin/python/cumin/messaging/binding.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/binding.strings 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/binding.strings 2009-06-17 20:20:11 UTC (rev
3457)
@@ -1,3 +1,21 @@
+[BindingSet.sql]
+select
+ b.id,
+ b.exchange_id as e_id,
+ b.queue_id as q_id,
+ b.binding_key as key
+from binding as b
+left outer join binding_stats as c on c.id = b.stats_curr_id
+{sql_where}
+{sql_orderby}
+{sql_limit}
+
+[BindingSet.count_sql]
+select count(*)
+from binding as b
+left outer join binding_stats as c on c.id = b.stats_curr_id
+{sql_where}
+
[ExchangeInput.name_html]
<td>
<input type="checkbox" id="{id}.{exchange_id}"
name="{name_path}"
@@ -137,23 +155,28 @@
}
[ExchangeKeysField.html]
-<div class="field">
- <div class="rfloat">{phase}</div>
- <div class="title">{title}</div>
- <div class="rclear"> </div>
+<tr>
+ <th>
+ <div class="title">{title}</div>
+ <div class="help">{help}</div>
+ </th>
+ <td>
+ <div class="rfloat">{phase}</div>
+ <div class="rclear"> </div>
- <div class="inputs">
- <table class="mobjects" id="exchange_types">
- <thead>
- <tr>
- <th colspan="2"><label
class="exchange_name">Exchange Name</label></th>
- <th class="exchange_type">Exchange Type</th>
- <th>Binding Key</th>
- </tr>
- </thead>
- <tbody>
- {exchanges}
- </tbody>
- </table>
- </div>
-</div>
+ <div class="inputs">
+ <table class="mobjects" id="exchange_types">
+ <thead>
+ <tr>
+ <th colspan="2"><label
class="exchange_name">Exchange Name</label></th>
+ <th class="exchange_type">Exchange Type</th>
+ <th>Binding Key</th>
+ </tr>
+ </thead>
+ <tbody>
+ {exchanges}
+ </tbody>
+ </table>
+ </div>
+ </td>
+</tr>
Modified: mgmt/trunk/cumin/python/cumin/messaging/broker.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/broker.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/broker.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -14,11 +14,14 @@
from brokerlink import *
from client import *
+from brokerlink import LinkSet
+
strings = StringCatalog(__file__)
-class NewBrokerSet(CuminClassTable):
+class BrokerSet(CuminSelectionTable):
def __init__(self, app, name):
- super(NewBrokerSet, self).__init__(app, name, app.model.broker)
+ item = BrokerGroupParameter(app, "item")
+ super(BrokerSet, self).__init__(app, name, item)
self.group = BrokerGroupParameter(app, "group")
self.add_parameter(self.group)
@@ -33,6 +36,10 @@
col = self.ClusterColumn(app, "cluster")
self.add_column(col)
+ task = main.module.broker_set_engroup
+ button = TaskButton(app, "engroup", task, self.selection)
+ self.buttons.add_child(button)
+
def render_title(self, session):
count = self.get_item_count(session)
return "Brokers %s" % fmt_count(count)
@@ -122,47 +129,17 @@
self.view = BrokerView(app, "view", self.vhost)
self.add_mode(self.view)
- self.edit = BrokerEdit(app, "edit")
- self.add_mode(self.edit)
-
self.queue = QueueFrame(app, "queue")
self.add_mode(self.queue)
- self.queues_purge = QueueSetPurge(app, "queuespurge")
- self.add_mode(self.queues_purge)
-
- self.queues_remove = QueueSetRemove(app, "queuesremove")
- self.add_mode(self.queues_remove)
-
- self.queue_add = QueueAdd(app, "queueadd", self.vhost)
- self.add_mode(self.queue_add)
-
self.exchange = ExchangeFrame(app, "exchange")
self.add_mode(self.exchange)
- self.exchange_add = ExchangeAdd(app, "exchangeadd", self.vhost)
- self.add_mode(self.exchange_add)
-
- self.exchanges_remove = ExchangeSetRemove(app, "exchangesremove")
- self.add_mode(self.exchanges_remove)
-
- self.bindings_remove = BindingSetRemove(app, "bindingsremove")
- self.add_mode(self.bindings_remove)
-
- self.link = PeerFrame(app, "link")
- self.add_mode(self.link)
-
- self.link_add = BrokerLinkAdd(app, "linkadd", self.vhost)
- self.add_mode(self.link_add)
-
- self.links_close = BrokerSetClose(app, "linksclose")
- self.add_mode(self.links_close)
-
self.connection = ConnectionFrame(app, "conn")
self.add_mode(self.connection)
- self.connections_close = ConnectionSetClose(app, "connsclose")
- self.add_mode(self.connections_close)
+ self.link = LinkFrame(app, "link")
+ self.add_mode(self.link)
class VhostAttribute(Attribute):
def get_default(self, session):
@@ -222,7 +199,7 @@
tabs.add_tab(self.BrokerQueueTab(app, "queues", self.vhost))
tabs.add_tab(ExchangeSet(app, "exchanges", self.vhost))
tabs.add_tab(ConnectionSet(app, "conns", self.vhost))
- tabs.add_tab(PeerSet(app, "peers", self.vhost))
+ tabs.add_tab(LinkSet(app, "links", self.vhost))
tabs.add_tab(BrokerAccessControl(app, "access", self.vhost))
tabs.add_tab(BrokerClustering(app, "cluster", self.vhost))
tabs.add_tab(self.BrokerDetailsTab(app, "details", self.vhost))
@@ -416,7 +393,7 @@
self.group_tmpl = Template(self, "group_html")
- self.brokers = NewBrokerSet(app, "brokers")
+ self.brokers = BrokerSet(app, "brokers")
self.add_child(self.brokers)
def render_title(self, session, *args):
@@ -694,11 +671,15 @@
for group in reg.groups:
self.groups.get(session).append(group)
-class BrokerSetEngroup(CuminSetActionForm):
- def __init__(self, app, name):
- param = BrokerParameter(app, "item")
+class BrokerSetEngroupForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(BrokerSetEngroupForm, self).__init__(app, name, task)
- super(BrokerSetEngroup, self).__init__ \
- (app, name, app.model.broker.engroup_set, param)
+ item = BrokerParameter(app, "item")
+ self.object = ListParameter(app, "broker", item)
+ self.add_parameter(self.object)
+# def process_submit(self, session):
+# pass
+
from brokergroup import BrokerGroupCheckboxField
Modified: mgmt/trunk/cumin/python/cumin/messaging/broker.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/broker.strings 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/broker.strings 2009-06-17 20:20:11 UTC (rev
3457)
@@ -1,50 +1,4 @@
[BrokerSet.sql]
-select br.id, br.name, c.cluster_name as cluster
-from broker_registration as br
-left outer join broker as b on b.registration_id = br.id
-left outer join cluster as c on c.broker_id = b.id
-{sql_where}
-{sql_orderby}
-{sql_limit}
-
-[BrokerSet.count_sql]
-select count(*)
-from broker_registration as br
-{sql_where}
-
-[BrokerSet.css]
-div.sactions button.unregister {
- margin-right: 2em;
-}
-
-[BrokerSet.html]
-<form id="{id}" method="post" action="?">
- <!-- <select
onchange="document.getElementById('{id}.submit').submit()"> -->
-
- <div class="sactions">
- <h2>Act on Selection:</h2>
- {unregister}
-
- <h2>Add to Group:</h2>
- {groups} {groupify}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
-[NewBrokerSet.sql]
select
b.id,
b.qmf_scope_id,
@@ -57,7 +11,7 @@
{sql_orderby}
{sql_limit}
-[NewBrokerSet.count_sql]
+[BrokerSet.count_sql]
select count(*)
from broker as b
{sql_where}
Modified: mgmt/trunk/cumin/python/cumin/messaging/brokergroup.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/brokergroup.py 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/brokergroup.py 2009-06-17 20:20:11 UTC (rev
3457)
@@ -9,8 +9,10 @@
from cumin.formats import *
from cumin.util import *
-from broker import NewBrokerSet
+import main
+from broker import BrokerSet
+
strings = StringCatalog(__file__)
class BrokerGroupSet(CuminClassTable):
@@ -22,6 +24,10 @@
col = CuminClassNameColumn(app, "name", cls)
self.add_column(col)
+ self.add = TaskLink \
+ (self.app, "add", main.module.broker_group_add, None)
+ self.add_child(self.add)
+
class BrokerGroupInputSet(CheckboxInputSet):
def __init__(self, app, name):
super(BrokerGroupInputSet, self).__init__(app, name, None)
@@ -66,128 +72,71 @@
self.view = BrokerGroupView(app, "view", self.object)
self.add_child(self.view)
- self.add = BrokerGroupAdd(app, "add")
- self.add_child(self.add)
-
- self.edit = BrokerGroupEdit(app, "edit")
- self.add_child(self.edit)
-
- self.remove = BrokerGroupRemove(app, "remove")
- self.add_child(self.remove)
-
- def render_title(self, session, group):
- if group:
- return super(BrokerGroupFrame, self).render_title(session, group)
- else:
- return "Broker Group"
-
- def render_href(self, session, group):
- if group:
- return super(BrokerGroupFrame, self).render_href(session, group)
-
-class BrokerGroupStatus(CuminStatus):
- pass
-
class BrokerGroupView(CuminView):
def __init__(self, app, name, group):
super(BrokerGroupView, self).__init__(app, name)
self.group = group
- status = BrokerGroupStatus(app, "status")
- self.add_child(status)
-
self.__tabs = TabbedModeSet(app, "tabs")
self.add_child(self.__tabs)
- brokers = NewBrokerSet(app, "brokers")
+ brokers = BrokerSet(app, "brokers")
brokers.group = self.group
self.__tabs.add_tab(brokers)
self.__tabs.add_tab(CuminDetails(app, "details"))
class BrokerGroupForm(CuminFieldForm):
- def __init__(self, app, name):
+ def __init__(self, app, name, task):
super(BrokerGroupForm, self).__init__(app, name)
+ self.task = task
+
self.group_name = UniqueNameField(app, "name", BrokerGroup)
self.add_field(self.group_name)
- def init(self):
- super(BrokerGroupForm, self).init()
-
- self.group_name.set_object_attr(self.frame.object)
-
-class BrokerGroupAdd(BrokerGroupForm):
- def process_cancel(self, session):
- branch = session.branch()
- self.page.main.messaging.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
+class BrokerGroupAddForm(BrokerGroupForm):
def process_submit(self, session):
- errors = self.validate(session)
+ self.check(session)
- if errors:
- pass
- else:
- args = {"name": self.group_name.get(session)}
- method = self.app.model.broker_group.add
- method.invoke(None, args)
+ if not self.errors.get(session):
+ name = self.group_name.get(session)
- self.process_cancel(session)
+ self.task.invoke(session, None, name)
+ self.task.exit_with_redirect(session, None)
def render_title(self, session):
- return "Add Group"
+ return self.task.get_title(session)
-class BrokerGroupEdit(BrokerGroupForm):
- def get_args(self, session):
- return self.frame.get_args(session)
+class BrokerGroupEditForm(BrokerGroupForm):
+ def __init__(self, app, name, task):
+ super(BrokerGroupEditForm, self).__init__(app, name, task)
- def process_cancel(self, session, group):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ self.group = BrokerGroupParameter(app, "group")
+ self.add_parameter(self.group)
- def process_submit(self, session, group):
- errors = self.validate(session)
+ def process_submit(self, session):
+ self.check(session)
- if errors:
- pass
- else:
- args = {"name": self.group_name.get(session)}
- method = self.app.model.broker_group.edit
- method.invoke(group, args)
+ if not self.errors.get(session):
+ group = self.group.get(session)
+ name = self.group_name.get(session)
- self.process_cancel(session, group)
+ self.task.invoke(session, group, name)
+ self.task.exit_with_redirect(session, group)
- def process_display(self, session, group):
+ def process_display(self, session):
+ group = self.group.get(session)
self.group_name.set(session, group.name)
- def render_title(self, session, group):
- return "Edit Group '%s'" % group.name
+ def render_title(self, session):
+ group = self.group.get(session)
+ return self.task.get_title(session, group)
-class BrokerGroupRemove(CuminConfirmForm, Frame):
- def get_args(self, session):
- return self.frame.get_args(session)
+class BrokerGroupRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(BrokerGroupRemoveForm, self).__init__(app, name, task)
- def process_cancel(self, session, group):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_submit(self, session, group):
- method = self.app.model.broker_group.remove
- method.invoke(group)
-
- branch = session.branch()
- self.frame.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def render_title(self, session, group):
- return "Remove Broker Group '%s'" % group.name
-
- def render_submit_content(self, session, group):
- return "Yes, Remove Broker Group '%s'" % group.name
-
- def render_cancel_content(self, session, group):
- return "No, Cancel"
+ self.object = BrokerGroupParameter(app, "group")
+ self.add_parameter(self.object)
Modified: mgmt/trunk/cumin/python/cumin/messaging/brokerlink.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/brokerlink.py 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/brokerlink.py 2009-06-17 20:20:11 UTC (rev
3457)
@@ -11,20 +11,17 @@
from queue import *
from exchange import *
+import main
+
strings = StringCatalog(__file__)
-class PeerSet(CuminTable, Form):
+class LinkSet(CuminSelectionTable):
def __init__(self, app, name, vhost):
- super(PeerSet, self).__init__(app, name)
+ item = LinkParameter(app, "item")
+ super(LinkSet, self).__init__(app, name, item)
self.vhost = vhost
- self.ids = FilteredCheckboxIdColumn(app, "id", self,
callback=self.disable_closed)
- self.add_column(self.ids)
-
- #self.ids = CheckboxIdColumn(app, "id")
- #self.add_column(self.ids)
-
col = self.AddressColumn(app, "addr")
self.add_column(col)
self.set_default_column(col)
@@ -44,20 +41,19 @@
#col = self.ToPeerColumn(app, "to_peer")
#self.add_column(col)
- self.__close = self.Close(app, "close")
- self.add_child(self.__close)
+ task = main.module.link_add
+ self.links.add_child(TaskLink(app, "link_add", task, vhost))
- def render_add_broker_link_url(self, session):
- branch = session.branch()
- self.frame.link_add.show(branch)
- return branch.marshal()
+ task = main.module.link_set_remove
+ button = TaskButton(app, "remove", task, self.selection)
+ self.buttons.add_child(button)
def render_title(self, session):
count = self.get_item_count(session)
return "Broker Links %s" % fmt_count(count)
def get_sql_where_constraints(self, session):
- constraints = super(PeerSet, self).get_sql_where_constraints(session)
+ constraints = super(LinkSet, self).get_sql_where_constraints(session)
constraints.append("v.id = %(vhost_id)r")
return constraints
@@ -73,8 +69,8 @@
return "Address"
def render_content(self, session, data):
- peer = Identifiable(data["id"])
- href = self.frame.link.get_href(session, peer)
+ link = Identifiable(data["id"])
+ href = self.frame.link.get_href(session, link)
name = "%s:%i" % (data["host"], data["port"])
return fmt_link(href, fmt_shorten(name))
@@ -108,24 +104,13 @@
def render_value(self, session, value):
return fmt_rate(value)
- class Close(FormButton):
- def render_content(self, session):
- return "Close"
+class RouteSet(CuminSelectionTable):
+ def __init__(self, app, name, link):
+ item = RouteParameter(app, "item")
+ super(RouteSet, self).__init__(app, name, item)
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
+ self.link = link
- href = self.frame.links_close.get_href(session, ids)
- self.page.set_redirect_url(session, href)
-
-class PeerRouteSet(CuminTable, Form):
- def __init__(self, app, name):
- super(PeerRouteSet, self).__init__(app, name)
-
- self.ids = CheckboxIdColumn(app, "id")
- self.add_column(self.ids)
-
#col = self.SourceColumn(app, "source")
#self.add_column(col)
@@ -145,27 +130,24 @@
col = self.ExcludesColumn(app, "excludes")
self.add_column(col)
- self.__remove = self.Remove(app, "remove")
- self.add_child(self.__remove)
+ task = main.module.route_add
+ self.links.add_child(TaskLink(app, "add", task, self.link))
- def get_args(self, session):
- return self.frame.get_args(session)
+ task = main.module.route_set_remove
+ button = TaskButton(app, "remove", task, self.selection)
+ self.buttons.add_child(button)
- def render_title(self, session, link):
- count = self.get_item_count(session, link)
+ def render_title(self, session):
+ count = self.get_item_count(session)
return "Link Routes %s" % fmt_count(count)
- def render_sql_where(self, session, link):
+ def render_sql_where(self, session):
return "where l.id = %(link_id)r and b.qmf_delete_time is null"
- def get_sql_values(self, session, link):
+ def get_sql_values(self, session):
+ link = self.link.get(session)
return {"link_id": link.id}
- def render_add_bridge_url(self, session, route):
- branch = session.branch()
- self.frame.show_bridge_add(branch)
- return branch.marshal()
-
class SourceColumn(SqlTableColumn):
def render_title(self, session, data):
return "Source"
@@ -197,116 +179,56 @@
def render_title(self, session, data):
return "Excludes"
- class Remove(FormButton):
- def render_content(self, session):
- return "Remove"
-
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- frame = self.frame.show_routes_close(branch)
- frame.ids.set(branch, ids)
- self.page.set_redirect_url(session, branch.marshal())
-
-class PeerFrame(CuminFrame):
+class LinkFrame(CuminFrame):
def __init__(self, app, name):
- super(PeerFrame, self).__init__(app, name)
+ super(LinkFrame, self).__init__(app, name)
- self.object = PeerParameter(app, "id")
+ self.object = LinkParameter(app, "id")
self.add_parameter(self.object)
- self.view = PeerView(app, "view")
+ self.view = LinkView(app, "view", self.object)
self.add_mode(self.view)
- self.remove = LinkRemove(app, "remove")
- self.add_mode(self.remove)
+ def show_object(self, session, link):
+ if hasattr(link, "vhost"):
+ self.page.main.messaging.broker.set_object(session, link.vhost)
- self.__bridge_add = BridgeAdd(app, "bridgeadd")
- self.add_mode(self.__bridge_add)
+ return super(LinkFrame, self).show_object(session, link)
- self.__routes_close = PeerRouteSetClose(app, "routesclose")
- self.add_mode(self.__routes_close)
+class LinkRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(LinkRemoveForm, self).__init__(app, name, task)
- def render_title(self, session, peer):
- return super(PeerFrame, self).render_title(session, peer)
+ self.object = LinkParameter(app, "link")
+ self.add_parameter(self.object)
- def show_object(self, session, peer):
- self.page.main.broker.set_object(session, peer.vhost.broker)
- return super(PeerFrame, self).show_object(session, peer)
+class LinkSetRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(LinkSetRemoveForm, self).__init__(app, name, task)
- def show_bridge_add(self, session):
- self.page.set_frame(session, self.__bridge_add)
- return self.__bridge_add.show(session)
+ item = LinkParameter(app, "item")
- def show_routes_close(self, session):
- self.page.set_frame(session, self.__routes_close)
- return self.__routes_close.show(session)
+ self.object = ListParameter(app, "link", item)
+ self.add_parameter(self.object)
-class LinkRemove(CuminConfirmForm):
- def get_args(self, session):
- return self.frame.get_args(session)
+class LinkView(CuminView):
+ def __init__(self, app, name, link):
+ super(LinkView, self).__init__(app, name)
- def process_cancel(self, session, link):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ self.tabs = TabbedModeSet(app, "tabs")
+ self.add_child(self.tabs)
- def process_submit(self, session, link):
- action = self.app.model.link.close
- action.invoke(link)
+ #self.tabs.add_tab(LinkStats(app, "stats"))
- branch = session.branch()
- self.frame.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ self.routes = RouteSet(app, "routes", link)
+ self.tabs.add_tab(self.routes)
- def render_title(self, session, link):
- return "Close Broker Link '%s:%d'" % (link.host, link.port)
+ self.tabs.add_tab(CuminDetails(app, "details"))
- def render_submit_content(self, session, link):
- return "Yes, Close Broker Link"
-
- def render_cancel_content(self, session, link):
- return "No, Cancel"
-
-class PeerStatus(CuminStatus):
- def render_color(self, session, link):
- if link.statsCurr:
- return link.statsCurr.lastError and "red" or "green"
-
- def render_peer_state(self, session, peer):
- if peer.statsCurr:
- return peer.statsCurr.state
-
- def render_peer_error(self, session, peer):
- if peer.statsCurr:
- return peer.statsCurr.lastError
-
-class PeerView(CuminView):
+class LinkStats(TabbedModeSet):
def __init__(self, app, name):
- super(PeerView, self).__init__(app, name)
+ super(LinkStats, self).__init__(app, name)
- status = PeerStatus(app, "status")
- self.add_child(status)
-
- self.__tabs = TabbedModeSet(app, "tabs")
- self.add_child(self.__tabs)
-
- #self.__tabs.add_tab(PeerStats(app, "stats"))
-
- self.__routes = PeerRouteSet(app, "routes")
- self.__tabs.add_tab(self.__routes)
-
- self.__tabs.add_tab(CuminDetails(app, "details"))
-
- def show_routes(self, session):
- return self.__routes.show(session)
-
-class PeerStats(TabbedModeSet):
- def __init__(self, app, name):
- super(PeerStats, self).__init__(app, name)
-
self.add_child(StatSet(app, "io", "io"))
self.add_child(StatSet(app, "general", "general"))
@@ -322,7 +244,7 @@
class ReceiveRouteDropRateChart(StatValueChart):
def __init__(self, app, name):
- super(PeerStats.ReceiveRouteDropRateChart, self).__init__ \
+ super(LinkStats.ReceiveRouteDropRateChart, self).__init__ \
(app, name)
self.stats = ("msgReceives", "msgRoutes",
"msgDrops")
@@ -343,7 +265,7 @@
def do_get_items(self, session, *args):
exchanges = list()
- link = self.frame.frame.get_object(session)
+ link = self.form.link.get(session)
vhost = link.vhost
sortedExchanges = sorted_by(vhost.exchanges)
@@ -384,10 +306,15 @@
def render_title(self, session):
return "Choose an Exchange"
-class BridgeAddForm(CuminFieldForm):
- def __init__(self, app, name):
- super(BridgeAddForm, self).__init__(app, name)
+class RouteAddForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(RouteAddForm, self).__init__(app, name)
+ self.task = task
+
+ self.link = LinkParameter(app, "link")
+ self.add_parameter(self.link)
+
self.exchange = ExchangeRadioField(app, "exchange")
self.add_field(self.exchange)
@@ -417,18 +344,14 @@
self.sync = self.SyncField(app, "sync")
self.more.add_field(self.sync)
- def get_args(self, session):
- return self.frame.get_args(session)
+ def process_display(self, session):
+ link = self.link.get(session)
- def render_title(self, session, link):
- return "Add Route to '%s:%d'" % (link.host, link.port)
-
- def process_display(self, session, *args):
if not self.tag.get(session):
- self.tag.set(session, args[0].qmfBrokerId)
+ self.tag.set(session, link.qmfBrokerId)
if not self.excludes.get(session):
- self.excludes.set(session, "%s:%s" % (args[0].host, args[0].port))
+ self.excludes.set(session, "%s:%s" % (link.host, link.port))
if not self.sync.get(session):
self.sync.set(session, self.sync.get_default(session))
@@ -456,21 +379,15 @@
def render_title_2(self, session):
return "Not dynamic"
-
class BridgeAddHelpField(FormField):
pass
-class BridgeAdd(BridgeAddForm):
- def process_cancel(self, session, *args):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ def process_submit(self, session):
+ self.check(session)
- def process_submit(self, session, link):
- errors = self.validate(session)
- if errors:
- pass
- else:
+ if not self.errors.get(session):
+ link = self.link.get(session)
+
key = self.key.get(session)
tag = self.tag.get(session)
excludes = self.excludes.get(session)
@@ -480,26 +397,27 @@
dynamic = self.dynamic.get(session) == "yes"
sync = self.sync.get(session)
- args = {"durable": durable,
- "exchange": exchange.name,
- "key": key,
- "tag": tag,
- "excludes": excludes,
- "dynamic": dynamic,
- "sync": sync
- }
+ self.task.invoke(session, link, exchange, key, tag,
+ dynamic, sync, excludes)
+ self.task.exit_with_redirect(session, link)
- action = self.app.model.link.bridge
- action.invoke(link, args)
+ def render_title(self, session):
+ link = self.link.get(session)
+ return self.task.get_title(session, link)
- self.process_cancel(session, link)
+class RouteSetRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(RouteSetRemoveForm, self).__init__(app, name, task)
-class BrokerLinkAdd(CuminFieldForm):
- def __init__(self, app, name, vhost):
- super(BrokerLinkAdd, self).__init__(app, name)
+ item = RouteParameter(app, "item")
- self.vhost = vhost
+ self.object = ListParameter(app, "route", item)
+ self.add_parameter(self.object)
+class LinkForm(CuminFieldForm):
+ def __init__(self, app, name):
+ super(LinkForm, self).__init__(app, name)
+
self.host = self.Host(app, "host")
self.add_field(self.host)
@@ -521,11 +439,6 @@
self.transport = self.TransportField(app, "transport")
self.more.add_field(self.transport)
- def render_title(self, session):
- vhost = self.vhost.get(session)
- name = self.app.model.broker.get_object_name(vhost.broker)
- return "Add Broker Link to '%s'" % name
-
class ShowButton(MoreFieldSet):
def render_more_text(self, session):
return "Show Optional Inputs..."
@@ -539,7 +452,7 @@
class PortField(StringField):
def __init__(self, app, name):
- super(BrokerLinkAdd.PortField, self).__init__(app, name)
+ super(LinkForm.PortField, self).__init__(app, name)
self.input.size = 5
self.css_class = "compact first"
@@ -571,7 +484,7 @@
class TransportField(RadioField):
def __init__(self, app, name):
- super(BrokerLinkAdd.TransportField, self).__init__(app, name, None)
+ super(LinkForm.TransportField, self).__init__(app, name, None)
self.param = Parameter(app, "param")
self.param.default = "tcp"
@@ -617,78 +530,35 @@
def render_title_2(self, session):
return "No, do not restore if broker restarts"
- def process_cancel(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+class LinkAddForm(LinkForm):
+ def __init__(self, app, name, task):
+ super(LinkAddForm, self).__init__(app, name)
+ self.task = task
+
+ self.vhost = VhostParameter(app, "vhost")
+ self.add_parameter(self.vhost)
+
+ def render_title(self, session):
+ vhost = self.vhost.get(session)
+ return self.task.get_description(session, vhost)
+
def process_submit(self, session):
- if self.validate(session):
- pass
- else:
+ self.check(session)
+
+ if not self.errors.get(session):
+ vhost = self.vhost.get(session)
+
host = self.host.get(session)
port = self.port.get(session) or 5672
- if port:
- port = int(port)
username = self.username.get(session) or "anonymous"
password = self.password.get(session)
- durable = self.durable.get(session)
+ durable = self.durable.get(session) == "yes"
transport = self.transport.get(session)
- args = {
- "host": host,
- "port": port,
- "durable": durable == "yes",
- "username": username,
- "password": password,
- "transport": transport
- }
+ if port:
+ port = int(port)
- action = self.app.model.broker.add_link
- action.invoke(self.vhost.get(session).broker, args)
-
- # navigate back to main queue frame
- self.process_cancel(session)
-
-class BrokerSetClose(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_item(self, session, id):
- link = Link.get(id)
- action = self.app.model.link.close
- action.invoke(link)
-
- def render_title(self, session):
- return "Close Broker Link"
-
- def render_form_heading(self, session, *args):
- return "Close Link to"
-
- def render_item_content(self, session, id):
- link = Link.get(id)
- return "Broker: %s:%d" % (link.host, link.port)
-
-class PeerRouteSetClose(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_item(self, session, id):
- bridge = Bridge.get(id)
- action = self.app.model.route.remove
- action.invoke(bridge)
-
- def render_title(self, session):
- link = self.parent.get_object(session)
- return "Remove Route from %s:%i" % (link.host, link.port)
-
- def render_form_heading(self, session, *args):
- return "Remove Route"
-
- def render_item_content(self, session, id):
- bridge = Bridge.get(id)
- return "<td>%s</td><td>%s</td>" % (bridge.dest,
bridge.key)
+ self.task.invoke(session, vhost, host, port,
+ durable, username, password, transport)
+ self.task.exit_with_redirect(session, vhost)
Modified: mgmt/trunk/cumin/python/cumin/messaging/brokerlink.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/brokerlink.strings 2009-06-17 19:44:31 UTC
(rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/brokerlink.strings 2009-06-17 20:20:11 UTC
(rev 3457)
@@ -1,4 +1,4 @@
-[PeerSet.sql]
+[LinkSet.sql]
select
l.id,
l.host,
@@ -14,39 +14,13 @@
{sql_orderby}
{sql_limit}
-[PeerSet.count_sql]
+[LinkSet.count_sql]
select count(*)
from link as l
join vhost as v on v.id = l.vhost_id
{sql_where}
-[PeerSet.html]
-<form id="{id}" method="post" action="?">
- <ul class="actions">
- <li><a class="nav" href="{add_broker_link_url}">Add
Broker Link</a></li>
- </ul>
-
- <div class="sactions">
- <h2>Act on Selected Broker Links:</h2>
- {close}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
-[PeerRouteSet.sql]
+[RouteSet.sql]
select
b.id,
b.src,
@@ -65,38 +39,12 @@
{sql_orderby}
{sql_limit}
-[PeerRouteSet.count_sql]
+[RouteSet.count_sql]
select count(*)
from bridge as b
join link as l on l.id = b.link_id
{sql_where}
-[PeerRouteSet.html]
-<form id="{id}" method="post" action="?">
- <ul class="actions">
- <li><a class="nav" href="{add_bridge_url}">Add
Route</a></li>
- </ul>
-
- <div class="sactions">
- <h2>Act on Selected Routes:</h2>
- {remove}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
[ExchangeRadioField.html]
<div class="{form_field_class}">
<div class="rfloat">{phase}</div>
@@ -105,37 +53,6 @@
<div class="inputs">{inputs}</div><div
style="clear:left;"><!-- --></div>
</div>
-[PeerRouteSetClose.html]
-<form id="{id}" class="mform" method="post"
action="?">
- <div class="head">
- <h1>{title}</h1>
- </div>
- <div class="body">
- <span class="legend">{form_heading}</span>
- <table class="mobjects">
- <thead>
- <tr>
- <th>Exchange</th>
- <th>Key</th>
- </tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- {hidden_inputs}
- </div>
- <div class="foot">
- {help}
- {submit}
- {cancel}
- </div>
-</form>
-<script type="text/javascript">
- $("{id}").elements[0].focus();
-</script>
-
-[PeerRouteSetClose.item_html]
-<tr>{item_content}</tr>
-
[BridgeAddHelpField.css]
div#bridge_add_help span.tag1 {
color:red;
@@ -148,7 +65,6 @@
color: #444444;
}
-
[BridgeAddHelpField.html]
<div id="bridge_add_help">
<p>The <strong>Tag</strong> and <strong>Excludes</strong>
are used to prevent a message from routing back
@@ -160,17 +76,3 @@
<em>broker2</em> <==> <em>broker1</em> tag:
<span class="tag1">tag1</span> excludes: <span
class="tag2">tag2</span>
</p>
</div>
-
-[PeerStatus.html]
-<div id="{id}" class="CuminStatus {color}">
- <table>
- <tr>
- <th><strong>State</strong></th>
- <td>{peer_state}</td>
- </tr>
- <tr>
- <th><strong>Last Error</strong></th>
- <td>{peer_error}</td>
- </tr>
- </table>
-</div>
Modified: mgmt/trunk/cumin/python/cumin/messaging/client.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/client.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/client.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -4,24 +4,24 @@
from datetime import datetime
from cumin.stat import *
from cumin.widgets import *
+from cumin.modelwidgets import *
from cumin.parameters import *
from cumin.formats import *
from cumin.util import *
+import main
+
strings = StringCatalog(__file__)
-class ConnectionSet(CuminTable, Form):
+class ConnectionSet(CuminSelectionTable):
def __init__(self, app, name, vhost):
- super(ConnectionSet, self).__init__(app, name)
+ item = ConnectionParameter(app, "item")
+ super(ConnectionSet, self).__init__(app, name, item)
self.vhost = vhost
- self.ids = CheckboxIdColumn(app, "id")
- self.add_column(self.ids)
-
col = self.AddressColumn(app, "addr")
self.add_column(col)
-
self.set_default_column(col)
col = self.SystemConnectionColumn(app, "sysconn")
@@ -44,13 +44,14 @@
self.unit = StateSwitch(app, "unit")
self.unit.add_state("b", "Bytes")
self.unit.add_state("f", "Frames")
- self.add_child(self.unit)
+ self.switches.add_child(self.unit)
- self.__phase = PhaseSwitch(app, "phase")
- self.add_child(self.__phase)
+ self.phase = PhaseSwitch(app, "phase")
+ self.filters.add_child(self.phase)
- self.__close = self.Close(app, "close")
- self.add_child(self.__close)
+ task = main.module.connection_set_close
+ button = TaskButton(app, "close", task, self.selection)
+ self.add_child(button)
def get_unit_plural(self, session):
return self.unit.get(session) == "b" and "Bytes" or
"Frames"
@@ -64,7 +65,7 @@
constraints = list()
constraints.append("l.vhost_id = %(id)r")
- constraints.append(self.__phase.get_sql_constraint(session, vhost))
+ constraints.append(self.phase.get_sql_constraint(session, vhost))
return "where %s" % " and ".join(constraints)
@@ -72,17 +73,6 @@
vhost = self.vhost.get(session)
return {"id": vhost.id}
- class Close(FormButton):
- def render_content(self, session):
- return "Close"
-
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- # XXX Make table a frame to elim this
- self.parent.ids.clear(session)
- href = self.frame.connections_close.get_href(session, ids)
- self.page.set_redirect_url(session, href)
-
class AddressColumn(SqlTableColumn):
def render_title(self, session, data):
return "Address"
@@ -145,117 +135,45 @@
self.object = ConnectionParameter(app, "id")
self.add_parameter(self.object)
- self.view = ConnectionView(app, "view")
+ self.view = ConnectionView(app, "view", self.object)
self.add_mode(self.view)
- self.__close = ConnectionClose(app, "close", self.object)
- self.add_mode(self.__close)
-
- self.__sessions_detach = SessionSetDetach(app, "sessionsdetach")
- self.add_mode(self.__sessions_detach)
-
- self.__sessions_close = SessionSetClose(app, "sessionsclose")
- self.add_mode(self.__sessions_close)
-
def show_object(self, session, conn):
if hasattr(conn, "vhost"):
self.frame.set_object(session, conn.vhost.broker)
return super(ConnectionFrame, self).show_object(session, conn)
- def show_close(self, session):
- return self.__close.show(session)
+class ConnectionCloseForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(ConnectionCloseForm, self).__init__(app, name, task)
- def show_sessions_detach(self, session):
- return self.__sessions_detach.show(session)
+ self.object = ConnectionParameter(app, "conn")
+ self.add_parameter(self.object)
- def show_sessions_close(self, session):
- return self.__sessions_close.show(session)
+class ConnectionSetCloseForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(ConnectionSetCloseForm, self).__init__(app, name, task)
-# XXX get rid of this
-def doit(error, args):
- pass
- #print error, args
- #print "did it!"
+ item = ConnectionParameter(app, "item")
-class ConnectionClose(CuminConfirmForm):
- def __init__(self, app, name, conn):
- super(ConnectionClose, self).__init__(app, name)
+ self.object = ListParameter(app, "conn", item)
+ self.add_parameter(self.object)
- self.conn = conn
-
- def process_cancel(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_submit(self, session):
- conn = self.conn.get(session)
-
- action = self.app.model.connection.close
- action.invoke(conn)
-
- self.process_cancel(session, conn)
-
- def render_title(self, session):
- return "Close Connection '%s'" %
self.conn.get(session).address
-
- def render_submit_content(self, session):
- return "Yes, Close Connection '%s'" %
self.conn.get(session).address
-
- def render_cancel_content(self, session):
- return "No, Cancel"
-
-class ConnectionSetClose(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_item(self, session, id):
- conn = ClientConnection.get(id)
- action = self.app.model.connection.close
- action.invoke(conn)
-
- def render_title(self, session):
- return "Close Connections"
-
- def render_item_content(self, session, id):
- return "Close Connection %s" % ClientConnection.get(id).address
-
-class ConnectionStatus(CuminStatus):
- def render_frames_from(self, session, conn):
- return self.app.model.connection.framesFromClient.rate_html(conn)
-
- def render_frames_to(self, session, conn):
- return self.app.model.connection.framesToClient.rate_html(conn)
-
- def render_bytes_from(self, session, conn):
- return self.app.model.connection.bytesFromClient.rate_html(conn)
-
- def render_bytes_to(self, session, conn):
- return self.app.model.connection.bytesToClient.rate_html(conn)
-
class ConnectionView(CuminView):
- def __init__(self, app, name):
+ def __init__(self, app, name, conn):
super(ConnectionView, self).__init__(app, name)
- status = ConnectionStatus(app, "status")
- self.add_child(status)
+ self.tabs = TabbedModeSet(app, "tabs")
+ self.add_child(self.tabs)
- self.__tabs = TabbedModeSet(app, "tabs")
- self.add_child(self.__tabs)
+ self.tabs.add_tab(ConnectionStats(app, "stats"))
- self.__tabs.add_tab(ConnectionStats(app, "stats"))
+ self.sessions = SessionSet(app, "sessions", conn)
+ self.tabs.add_tab(self.sessions)
- self.__sessions = SessionSet(app, "sessions")
- self.__tabs.add_tab(self.__sessions)
+ self.tabs.add_tab(CuminDetails(app, "details"))
- self.__tabs.add_tab(CuminDetails(app, "details"))
-
- def show_sessions(self, session):
- return self.__sessions.show(session)
-
class ConnectionStats(Widget):
def __init__(self, app, name):
super(ConnectionStats, self).__init__(app, name)
@@ -279,50 +197,24 @@
def render_title(self, session, conn):
return "Bytes Sent and Received"
-class SessionSetDetach(CuminBulkActionForm, Frame):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch).show_sessions(branch)
- self.page.set_redirect_url(session, branch.marshal())
+class SessionSetTaskForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(SessionSetTaskForm, self).__init__(app, name, task)
- def process_item(self, session, id):
- session_ = Session.get(id)
- action = self.app.model.session.detach
- action.invoke(session_)
+ item = SessionParameter(app, "item")
- def render_title(self, session):
- return "Detach Sessions"
+ self.object = ListParameter(app, "session", item)
+ self.add_parameter(self.object)
- def render_item_content(self, session, id):
- return "Detach Session '%s'" % Session.get(id).name
+class SessionSet(CuminSelectionTable):
+ def __init__(self, app, name, conn):
+ item = SessionParameter(app, "item")
+ super(SessionSet, self).__init__(app, name, item)
-class SessionSetClose(CuminBulkActionForm, Frame):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch).show_sessions(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ self.conn = conn
- def process_item(self, session, id):
- session_ = Session.get(id)
- action = self.app.model.session.close
- action.invoke(session_)
-
- def render_title(self, session):
- return "Close Sessions"
-
- def render_item_content(self, session, id):
- return "Close Session '%s'" % Session.get(id).name
-
-class SessionSet(CuminTable, Form):
- def __init__(self, app, name):
- super(SessionSet, self).__init__(app, name)
-
- self.ids = CheckboxIdColumn(app, "id")
- self.add_column(self.ids)
-
col = self.NameColumn(app, "name")
self.add_column(col)
-
self.set_default_column(col)
col = self.ExpiresColumn(app, "expires")
@@ -334,55 +226,29 @@
self.__phase = PhaseSwitch(app, "phase")
self.add_child(self.__phase)
- self.__detach = self.Detach(app, "detach")
- self.add_child(self.__detach)
+ task = main.module.session_set_detach
+ self.buttons.add_child(TaskButton(app, "detach", task,
self.selection))
- self.__close = self.Close(app, "close")
- self.add_child(self.__close)
+ task = main.module.session_set_close
+ self.buttons.add_child(TaskButton(app, "close", task, self.selection))
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, conn):
+ def render_title(self, session):
+ conn = self.conn.get(session)
return "Sessions %s" % fmt_count(conn.sessions.count())
- def render_sql_where(self, session, conn):
+ def render_sql_where(self, session):
+ conn = self.conn.get(session)
+
elems = list()
elems.append("s.client_connection_id = %(id)r")
elems.append(self.__phase.get_sql_constraint(session, conn))
+
return "where %s" % " and ".join(elems)
- def get_sql_values(self, session, conn):
+ def get_sql_values(self, session):
+ conn = self.conn.get(session)
return {"id": conn.id}
- class Detach(FormButton):
- def render_content(self, session):
- return "Detach"
-
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- frame = self.frame.show_sessions_detach(branch)
- frame.ids.set(branch, ids)
- self.page.set_frame(branch, frame)
- self.page.set_redirect_url(session, branch.marshal())
-
- class Close(FormButton):
- def render_content(self, session):
- return "Close"
-
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- frame = self.frame.show_sessions_close(branch)
- frame.ids.set(branch, ids)
- self.page.set_frame(branch, frame)
- self.page.set_redirect_url(session, branch.marshal())
-
class NameColumn(SqlTableColumn):
def render_title(self, session, data):
return "Name"
Modified: mgmt/trunk/cumin/python/cumin/messaging/client.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/client.strings 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/client.strings 2009-06-17 20:20:11 UTC (rev
3457)
@@ -31,53 +31,6 @@
left outer join client_connection_stats as c on c.id = l.stats_curr_id
{sql_where}
-[ConnectionSet.html]
-<form id="{id}" method="post" action="?">
- <div class="rfloat">{phase}</div>
-
- {unit}
-
- <div class="sactions">
- <h2>Act on Selected Connections:</h2>
- {close}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
-[ConnectionStatus.html]
-<div id="{id}" class="CuminStatus {color}">
- <table>
- <tr>
- <th></th>
- <th style="width: 35%;" class="ralign">Frames</th>
- <th style="width: 35%;" class="ralign">Bytes</th>
- </tr>
- <tr>
- <th>Sent</th>
- <td class="ralign">{frames_from}</td>
- <td class="ralign">{bytes_from}</td>
- </tr>
- <tr>
- <th>Received</th>
- <td class="ralign">{frames_to}</td>
- <td class="ralign">{bytes_to}</td>
- </tr>
- </table>
-</div>
-
[ConnectionStats.html]
<table class="twocol">
<tbody>
@@ -110,29 +63,3 @@
from session as s
left outer join session_stats as c on c.id = s.stats_curr_id
{sql_where}
-
-[SessionSet.html]
-<form id="{id}" method="post" action="?">
- <div class="rfloat">{phase}</div>
-
- <ul class="radiotabs"><li> </li></ul>
-
- <div class="sactions">
- <h2>Act on Selected Sessions:</h2>
- {close}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
Modified: mgmt/trunk/cumin/python/cumin/messaging/exchange.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/exchange.py 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/exchange.py 2009-06-17 20:20:11 UTC (rev
3457)
@@ -6,11 +6,16 @@
from wooly.resources import *
from cumin.stat import *
from cumin.model import *
+from cumin.modelwidgets import *
from cumin.widgets import *
from cumin.parameters import *
from cumin.formats import *
from cumin.util import *
+from binding import *
+
+import main
+
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.messaging.exchange")
@@ -34,15 +39,13 @@
def render_item_checked_attr(self, session, exchange):
return exchange is self.param.get(session) and
"checked=\"checked\""
-class ExchangeSet(CuminTable, Form):
+class ExchangeSet(CuminSelectionTable):
def __init__(self, app, name, vhost):
- super(ExchangeSet, self).__init__(app, name)
+ item = ExchangeParameter(app, "item")
+ super(ExchangeSet, self).__init__(app, name, item)
self.vhost = vhost
- self.ids = FilteredCheckboxIdColumn(app, "id", self,
callback=self.disable_exchange)
- self.add_column(self.ids)
-
col = self.NameColumn(app, "name")
self.add_column(col)
self.set_default_column(col)
@@ -68,22 +71,21 @@
self.add_column(col)
self.unit = UnitSwitch(app, "unit")
- self.add_child(self.unit)
+ self.switches.add_child(self.unit)
self.phase = PhaseSwitch(app, "phase")
- self.add_child(self.phase)
+ self.filters.add_child(self.phase)
- self.__remove = self.Remove(app, "remove")
- self.add_child(self.__remove)
+ task = main.module.exchange_add
+ self.links.add_child(TaskLink(app, "exchange_add", task, self.vhost))
+ task = main.module.exchange_set_remove
+ button = TaskButton(app, "remove", task, self.selection)
+ self.buttons.add_child(button)
+
def disable_exchange(self, session, data):
return data["name"] in ExchangeInfo.get_builtins()
- def render_add_exchange_url(self, session):
- branch = session.branch()
- self.frame.exchange_add.show(branch)
- return branch.marshal()
-
def render_title(self, session):
vhost = self.vhost.get(session)
return "Exchanges %s" % fmt_count(vhost.exchanges.count())
@@ -101,18 +103,6 @@
vhost = self.vhost.get(session)
return {"id": vhost.id}
- class Remove(FormButton):
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- self.frame.exchanges_remove.show(branch).ids.set(branch, ids)
- self.page.set_redirect_url(session, branch.marshal())
-
- def render_content(self, session):
- return "Remove"
-
class NameColumn(SqlTableColumn):
def render_title(self, session, data):
return "Name"
@@ -169,24 +159,6 @@
unit = self.parent.unit.get(session)
return unit == "b" and "bdropped" or
"mdropped"
-class ExchangeSetRemove(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_item(self, session, id):
- exchange = Exchange.get(id)
- reg = self.frame.get_object(session)
- action = self.app.model.exchange.remove
- action.invoke(exchange)
-
- def render_title(self, session):
- return "Remove Exchanges"
-
- def render_item_content(self, session, id):
- return "Remove Exchange '%s'" % Exchange.get(id).name
-
class ExchangeFrame(CuminFrame):
def __init__(self, app, name):
super(ExchangeFrame, self).__init__(app, name)
@@ -197,9 +169,6 @@
self.view = ExchangeView(app, "view")
self.add_mode(self.view)
- self.remove = ExchangeRemove(app, "remove")
- self.add_mode(self.remove)
-
def show_object(self, session, exchange):
if isinstance(exchange, SQLObject):
self.page.main.messaging.broker.set_object \
@@ -217,133 +186,70 @@
if exchange:
return super(ExchangeFrame, self).render_href(session, exchange)
+class ExchangeRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(ExchangeRemoveForm, self).__init__(app, name, task)
-class ExchangeRemove(CuminConfirmForm):
- def get_args(self, session):
- return self.frame.get_args(session)
+ self.object = ExchangeParameter(app, "exchange")
+ self.add_parameter(self.object)
- def process_cancel(self, session, exchange):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+class ExchangeSetRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(ExchangeSetRemoveForm, self).__init__(app, name, task)
- def process_submit(self, session, exchange):
- reg = self.frame.frame.get_object(session)
- action = self.app.model.exchange.remove
- action.invoke(exchange)
+ item = ExchangeParameter(app, "item")
- branch = session.branch()
- self.frame.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+ self.object = ListParameter(app, "exchange", item)
+ self.add_parameter(self.object)
- def render_title(self, session, exchange):
- return "Remove Exchange '%s'" % exchange.name
-
- def render_submit_content(self, session, exchange):
- return "Yes, Remove Exchange '%s'" % exchange.name
-
- def render_cancel_content(self, session, exchange):
- return "No, Cancel"
-
-class ExchangeStatus(CuminStatus):
- def render_messages_received(self, session, exchange):
- return self.app.model.exchange.msgReceives.rate_html(exchange)
-
- def render_messages_routed(self, session, exchange):
- return self.app.model.exchange.msgRoutes.rate_html(exchange)
-
- def render_messages_dropped(self, session, exchange):
- return self.app.model.exchange.msgDrops.value(exchange)
-
- def render_bytes_received(self, session, exchange):
- return self.app.model.exchange.byteReceives.rate_html(exchange)
-
- def render_bytes_routed(self, session, exchange):
- return self.app.model.exchange.byteRoutes.rate_html(exchange)
-
- def render_bytes_dropped(self, session, exchange):
- return self.app.model.exchange.byteDrops.value(exchange)
-
class ExchangeView(CuminView):
def __init__(self, app, name):
super(ExchangeView, self).__init__(app, name)
- status = ExchangeStatus(app, "status")
- self.add_child(status)
+ self.tabs = TabbedModeSet(app, "tabs")
+ self.add_child(self.tabs)
- self.__tabs = TabbedModeSet(app, "tabs")
- self.add_child(self.__tabs)
+ self.tabs.add_tab(ExchangeStats(app, "stats"))
- self.__tabs.add_tab(ExchangeStats(app, "stats"))
+ self.bindings = ExchangeBindingSet(app, "bindings")
+ self.tabs.add_tab(self.bindings)
- self.__bindings = ExchangeBindingSet(app, "bindings")
- self.__tabs.add_tab(self.__bindings)
+ self.tabs.add_tab(CuminDetails(app, "details"))
- self.__tabs.add_tab(CuminDetails(app, "details"))
-
- def show_bindings(self, session):
- return self.__bindings.show(session)
-
-class ExchangeBindingSet(BindingSet, Form):
+class ExchangeBindingSet(BindingSet):
def __init__(self, app, name):
super(ExchangeBindingSet, self).__init__(app, name)
- self.__remove = self.Remove(app, "remove")
- self.add_child(self.__remove)
-
self.set_default_column_name("q_id")
def get_visible_columns(self, session):
return self.get_request_visible_columns(session, ["q_id"])
- def render_title(self, session, exchange):
+ def get_sql_values(self, session):
+ exchange = self.frame.object.get(session)
+ return {"id": exchange.id}
+
+ def render_title(self, session):
+ exchange = self.frame.object.get(session)
return "Queue Bindings %s" % \
fmt_count(exchange.bindings.count())
- def render_sql_where(self, session, exchange):
+ def render_sql_where(self, session):
+ exchange = self.frame.object.get(session)
elems = list()
elems.append("b.exchange_id = %(id)r")
elems.append(self.phase.get_sql_constraint(session, exchange))
return "where %s" % " and ".join(elems)
- class Remove(FormButton):
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
+class ExchangeAddForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(ExchangeAddForm, self).__init__(app, name)
- href = self.page.main.messaging.broker.bindings_remove.get_href \
- (session, ids)
- self.page.set_redirect_url(session, href)
+ self.task = task
- def render_content(self, session):
- return "Remove"
+ self.vhost = VhostParameter(app, "vhost")
+ self.add_parameter(self.vhost)
-class BindingSetRemove(CuminBulkActionForm):
- def process_item(self, session, id):
- binding = Binding.get(id)
- action = self.app.model.binding.remove
- action.invoke(binding)
-
- def render_title(self, session):
- return "Remove Binding"
-
- def render_form_heading(self, session, *args):
- return "Remove Binding between:"
-
- def render_item_content(self, session, id):
- binding = Binding.get(id)
- ename = binding.exchange.name or "Default"
- qname = binding.queue.name
- return "Exchange: %s <i>and</i> Queue: %s" % (ename,
qname)
-
-class ExchangeForm(CuminFieldForm):
- def __init__(self, app, name, vhost):
- super(ExchangeForm, self).__init__(app, name)
-
- assert vhost
-
- self.vhost = vhost
-
self.exchange_name = ExchangeNameField(app, "exchange_name")
self.add_field(self.exchange_name)
@@ -362,6 +268,25 @@
self.ive = self.IVEField(app, "ive")
self.more.add_field(self.ive)
+ def process_submit(self, session):
+ self.check(session)
+
+ if not self.errors.get(session):
+ vhost = self.vhost.get(session)
+ name = self.exchange_name.get(session)
+ type = self.exchange_type.get(session)
+ durable = self.durable.get(session) == "yes"
+ sequence = self.sequence.get(session) == "yes"
+ ive = self.ive.get(session) == "yes"
+
+ self.task.invoke(session, vhost, name, type,
+ durable, sequence, ive)
+ self.task.exit_with_redirect(session, vhost)
+
+ def render_title(self, session):
+ vhost = self.vhost.get(session)
+ return self.task.get_title(session, vhost)
+
class SequenceField(TwoOptionRadioField):
def render_title(self, session):
return "Insert Sequence?"
@@ -403,7 +328,8 @@
class ExchangeTypeField(RadioField):
def __init__(self, app, name):
- super(ExchangeForm.ExchangeTypeField, self).__init__(app, name, None)
+ super(ExchangeAddForm.ExchangeTypeField, self).__init__ \
+ (app, name, None)
self.param = Parameter(app, "param")
self.param.default = "direct"
@@ -465,40 +391,6 @@
def render_title(self, session):
return "<em>XML:</em> Route message to queues based on
XML content of the message"
-class ExchangeAdd(ExchangeForm):
- def process_cancel(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_submit(self, session):
- errors = self.validate(session)
-
- if errors:
- pass
- else:
- reg = self.vhost.get(session).broker.registration
-
- exchange = Exchange()
- exchange.name = self.exchange_name.get(session)
- exchange.type = self.exchange_type.get(session)
- exchange.durable = self.durable.get(session) == "yes"
-
- args = {}
- args["reg"] = reg
- args["sequence"] = self.sequence.get(session) == "yes"
- args["ive"] = self.ive.get(session) == "yes"
-
- action = self.app.model.broker.add_exchange
- action.invoke(exchange, args)
-
- self.process_cancel(session)
-
- def render_title(self, session):
- broker = self.vhost.get(session).broker
- title = self.app.model.broker.get_object_title(session, broker)
- return "Add Exchange to %s" % title
-
class ExchangeStats(Widget):
def __init__(self, app, name):
super(ExchangeStats, self).__init__(app, name)
@@ -527,23 +419,6 @@
def render_title(self, session, exchange):
return "Messages Received, Routed, and Dropped"
-class ExchangeProducerSet(ItemSet):
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, exchange):
- return "Producers %s" % \
- fmt_count(self.get_item_count(session, exchange))
-
- def get_item_count(self, session, exchange):
- return exchange.producers.count()
-
- def do_get_items(self, session, exchange):
- return exchange.producers
-
- def render_item_name(self, session, producer):
- return producer.name
-
class ExchangeInfo(object):
@classmethod
def is_builtin(cls, exchange):
Modified: mgmt/trunk/cumin/python/cumin/messaging/exchange.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/exchange.strings 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/exchange.strings 2009-06-17 20:20:11 UTC (rev
3457)
@@ -32,108 +32,12 @@
{sql_orderby}
{sql_limit}
-
[ExchangeSet.count_sql]
select count(*)
from exchange as e
left outer join exchange_stats as c on c.id = e.stats_curr_id
{sql_where}
-[ExchangeSet.css]
-ul.ExchangeSet li:before {
- content: url(resource?name=exchange-20.png);
- vertical-align: -30%;
- padding: 0 0.25em;
-}
-
-[ExchangeSet.html]
-<form id="{id}" method="post" action="?"
update="{id}.table">
- <ul class="actions">
- <li><a class="nav" href="{add_exchange_url}">Add New
Exchange</a></li>
- </ul>
-
- <div class="rfloat">{phase}</div>
- {unit}
-
- <div class="sactions">
- <h2>Act on Selected Exchanges:</h2>
- {remove}
- </div>
-
- <table id="{id}.table" class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
-
- <div>{hidden_inputs}</div>
-</form>
-
-[ExchangeSet.item_html]
-<tr>{cells}</tr>
-
-[ExchangeStatus.html]
-<div id="{id}" class="CuminStatus {color}">
- <table>
- <tr>
- <th></th>
- <th style="width: 35%;"
class="ralign">Messages</th>
- <th style="width: 35%;" class="ralign">Bytes</th>
- </tr>
- <tr>
- <th>Received</th>
- <td class="ralign">{messages_received}</td>
- <td class="ralign">{bytes_received}</td>
- </tr>
- <tr>
- <th>Routed</th>
- <td class="ralign">{messages_routed}</td>
- <td class="ralign">{bytes_routed}</td>
- </tr>
- <tr>
- <th>Dropped</th>
- <td class="ralign">{messages_dropped}</td>
- <td class="ralign">{bytes_dropped}</td>
- </tr>
- </table>
-</div>
-
-[ExchangeBindingSet.html]
-<form id="{id}" method="post" action="?">
-
- <div class="rfloat">{phase}</div>
- <ul class="radiotabs"><li> </li></ul>
-
- <div class="sactions">
- <h2>Act on Selected Bindings:</h2>
- {remove}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
-[ExchangeBindingSet.item_html]
-<tr>{cells}</tr>
-
[ExchangeStats.html]
<table class="twocol">
<tbody>
@@ -152,32 +56,3 @@
</tr>
</tbody>
</table>
-
-[ExchangeProducerSet.html]
-<div class="sactions">
- <h2>Act on Selected Producers:</h2>
- <button>Start</button>
- <button>Stop</button>
- <button>Throttle</button>
-</div>
-
-<table class="mobjects">
- <tr>
- <th><input type="checkbox"/></th>
- <th>Name</th>
- <th class="ralign" colspan="2">Msgs. Produced</th>
- <th class="ralign" colspan="2">Bytes Produced</th>
- </tr>
-
- {items}
-</table>
-
-[ExchangeProducerSet.item_html]
-<tr>
- <td><input type="checkbox"/></td>
- <td>{item_name}</td>
- <td class="ralign">{item_messages_produced_rate}</td>
- <td class="ralign">{item_messages_produced}</td>
- <td class="ralign">{item_bytes_produced_rate}</td>
- <td class="ralign">{item_bytes_produced}</td>
-</tr>
Modified: mgmt/trunk/cumin/python/cumin/messaging/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/main.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/main.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -6,9 +6,70 @@
from broker import *
from brokergroup import *
+from model import *
strings = StringCatalog(__file__)
+class MessagingModule(object):
+ def init(self, app):
+ broker = app.model.broker
+
+ self.broker_set_engroup = BrokerSetEngroupTask(app, broker)
+ self.exchange_add = ExchangeAddTask(app, broker)
+ self.link_add = LinkAddTask(app, broker)
+ self.queue_add = QueueAddTask(app, broker)
+
+ broker_group = app.model.broker_group
+
+ self.broker_group_add = BrokerGroupAddTask(app, broker_group)
+ self.broker_group_edit = BrokerGroupEditTask(app, broker_group)
+ self.broker_group_remove = BrokerGroupRemoveTask(app, broker_group)
+
+ queue = app.model.queue
+
+ self.queue_remove = QueueRemoveTask(app, queue)
+ self.queue_set_remove = QueueSetRemoveTask(app, queue)
+ self.queue_purge = QueuePurgeTask(app, queue)
+ self.queue_set_purge = QueueSetPurgeTask(app, queue)
+ self.binding_add = BindingAddTask(app, queue)
+ self.move_messages = MoveMessagesTask(app, queue)
+
+ exchange = app.model.exchange
+
+ self.exchange_remove = ExchangeRemoveTask(app, exchange)
+ self.exchange_set_remove = ExchangeSetRemoveTask(app, exchange)
+
+ binding = app.model.binding
+
+ self.binding_remove = BindingRemoveTask(app, binding)
+ self.binding_set_remove = BindingSetRemoveTask(app, binding)
+
+ link = app.model.link
+
+ self.link_remove = LinkRemoveTask(app, link)
+ self.link_set_remove = LinkSetRemoveTask(app, link)
+ self.route_add = RouteAddTask(app, link)
+
+ route = app.model.route
+
+ self.route_set_remove = RouteSetRemoveTask(app, route)
+
+ connection = app.model.connection
+
+ self.connection_close = ConnectionCloseTask(app, connection)
+ self.connection_set_close = ConnectionSetCloseTask(app, connection)
+
+ session = app.model.session
+
+ self.session_set_detach = SessionSetDetachTask(app, session)
+ self.session_set_close = SessionSetCloseTask(app, session)
+
+ self.frame = MessagingFrame(app, "messaging")
+ app.main_page.main.messaging = self.frame
+ app.main_page.main.add_tab(self.frame)
+
+module = MessagingModule()
+
class MessagingFrame(CuminFrame):
def __init__(self, app, name):
super(MessagingFrame, self).__init__(app, name)
@@ -22,15 +83,6 @@
self.broker_group = BrokerGroupFrame(app, "group")
self.add_mode(self.broker_group)
- self.brokers_group = BrokerSetEngroup(app, "brokersengroup")
- self.add_mode(self.brokers_group)
-
- action = self.app.model.broker_group.remove_set
- item = BrokerGroupParameter(app, "item")
- self.broker_groups_remove = CuminSetActionForm \
- (app, "groupsremove", action, item)
- self.add_mode(self.broker_groups_remove)
-
def render_title(self, session):
return "Messaging"
Added: mgmt/trunk/cumin/python/cumin/messaging/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/model.py (rev 0)
+++ mgmt/trunk/cumin/python/cumin/messaging/model.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -0,0 +1,484 @@
+from wooly import Session
+
+from cumin.util import *
+
+from cumin.model import Task
+from broker import *
+from brokergroup import *
+from brokerlink import *
+from queue import *
+from exchange import *
+
+class ConnectionCloseTask(Task):
+ def __init__(self, app, cls):
+ super(ConnectionCloseTask, self).__init__(app, cls)
+
+ self.form = ConnectionCloseForm(app, "connection_close", self)
+
+ def get_title(self, session):
+ return "Close"
+
+ def do_enter(self, session, conn):
+ self.form.object.set(session, conn)
+
+ def do_invoke(self, completion, session, conn):
+ # XXX generalize this check and use it for other closes
+
+ session_ids = set()
+
+ for broker in self.app.model.mint.model.mintBrokersByQmfBroker:
+ session_ids.add(broker.getSessionId())
+
+ for sess in conn.sessions:
+ if sess.name in session_ids:
+ raise Exception \
+ ("Cannot close management connection %s" % conn.address)
+
+ conn.close(self.app.model.mint.model, completion)
+
+class ConnectionSetCloseTask(SetTask):
+ def __init__(self, app, cls):
+ super(ConnectionSetCloseTask, self).__init__(app, cls)
+
+ self.form = ConnectionSetCloseForm(app, "connection_set_close", self)
+ self.item_task = ConnectionCloseTask(app, cls)
+
+ def get_title(self, session):
+ return "Close"
+
+ def do_enter(self, session, conns):
+ self.form.object.set(session, conns)
+
+class SessionDetachTask(QmfTask):
+ def get_title(self, session):
+ return "Detach"
+
+ def do_invoke(self, completion, session, sess):
+ sess.detach(self.app.model.mint.model, completion)
+
+class SessionSetDetachTask(SetTask):
+ def __init__(self, app, cls):
+ super(SessionSetDetachTask, self).__init__(app, cls)
+
+ self.form = SessionSetTaskForm(app, "session_set_detach", self)
+ self.item_task = SessionDetachTask(app, cls)
+
+ def do_enter(self, session, sessions):
+ self.form.object.set(session, sessions)
+
+class SessionCloseTask(QmfTask):
+ def get_title(self, session):
+ return "Close"
+
+ def do_invoke(self, completion, session, sess):
+ sess.close(self.app.model.mint.model, completion)
+
+class SessionSetCloseTask(SetTask):
+ def __init__(self, app, cls):
+ super(SessionSetCloseTask, self).__init__(app, cls)
+
+ self.form = SessionSetTaskForm(app, "session_set_close", self)
+ self.item_task = SessionCloseTask(app, cls)
+
+ def do_enter(self, session, sessions):
+ self.form.object.set(session, sessions)
+
+class QueueAddTask(Task):
+ def __init__(self, app, cls):
+ super(QueueAddTask, self).__init__(app, cls)
+
+ self.form = QueueAddForm(app, "queue_add", self)
+
+ def get_title(self, session):
+ return "Add queue"
+
+ def get_description(self, session, vhost):
+ return "Add queue to broker '%s'" % get_vhost_name(vhost)
+
+ def do_enter(self, session, vhost):
+ self.form.vhost.set(session, vhost)
+
+ # XXX need to move logic here
+
+class QueueRemoveTask(Task):
+ def __init__(self, app, cls):
+ super(QueueRemoveTask, self).__init__(app, cls)
+
+ self.form = QueueRemoveForm(app, "queue_remove", self)
+
+ def get_title(self, session):
+ return "Remove"
+
+ def do_enter(self, session, queue):
+ self.form.object.set(session, queue)
+
+ def do_exit(self, session, queue):
+ self.app.main_page.main.messaging.broker.view.show(session)
+
+ def do_invoke(self, session, queue):
+ assert isinstance(queue, Queue)
+
+ session = self.app.model.get_session_by_object(queue)
+ session.queue_delete(queue=queue.name)
+ session.sync()
+
+class QueueSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(QueueSetRemoveTask, self).__init__(app, cls)
+
+ self.form = QueueSetTaskForm(app, "queue_set_remove", self)
+ self.item_task = QueueRemoveTask(app, cls)
+
+ def do_enter(self, session, queues):
+ self.form.object.set(session, queues)
+
+class QueuePurgeTask(QmfTask):
+ def __init__(self, app, cls):
+ super(QueuePurgeTask, self).__init__(app, cls)
+
+ self.form = QueuePurgeForm(app, "queue_purge", self)
+
+ def get_title(self, session):
+ return "Purge"
+
+ def do_enter(self, session, queue):
+ self.form.queue.set(session, queue)
+
+ def do_invoke(self, completion, session, queue, count):
+ """A count of 0 purges all"""
+
+ assert isinstance(queue, Queue)
+
+ queue.purge(self.app.model.mint.model, completion, count)
+
+class QueueSetPurgeTask(SetTask):
+ def __init__(self, app, cls):
+ super(QueueSetPurgeTask, self).__init__(app, cls)
+
+ self.form = QueueSetTaskForm(app, "queue_set_purge", self)
+ self.item_task = QueuePurgeTask(app, cls)
+
+ def do_enter(self, session, queues):
+ self.form.object.set(session, queues)
+
+class BindingAddTask(Task):
+ def __init__(self, app, cls):
+ super(BindingAddTask, self).__init__(app, cls)
+
+ self.form = BindingAddForm(app, "binding_add", self)
+
+ def get_title(self, session):
+ return "Add binding"
+
+ def get_description(self, session, queue):
+ return "Add binding to queue '%s'" % queue.name
+
+ def do_enter(self, session, queue):
+ self.form.queue.set(session, queue)
+
+ def do_invoke(self, queue, exchange, binding_key, arguments):
+ session = self.app.model.get_session_by_object(queue)
+ session.exchange_bind(queue=queue.name, exchange=exchange.name,
+ binding_key=binding_key, arguments=arguments)
+ session.sync()
+
+class BindingRemoveTask(Task):
+ def __init__(self, app, cls):
+ super(BindingRemoveTask, self).__init__(app, cls)
+
+ self.form = BindingRemoveForm(app, "binding_remove", self)
+
+ def get_title(self, session):
+ return "Remove"
+
+ def do_enter(self, session, binding):
+ self.form.binding.set(session, binding)
+
+ def do_invoke(self, binding):
+ assert isinstance(binding, Binding)
+
+ session = self.app.model.get_session_by_object(binding)
+ session.exchange_unbind(queue=binding.queue.name,
+ exchange=binding.exchange.name,
+ binding_key=binding.bindingKey)
+ session.sync()
+
+class BindingSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(BindingSetRemoveTask, self).__init__(app, cls)
+
+ self.form = BindingSetTaskForm(app, "binding_set_remove", self)
+ self.item_task = BindingRemoveTask(app, cls)
+
+ def do_enter(self, session, bindings):
+ self.form.object.set(session, bindings)
+
+class MoveMessagesTask(QmfTask):
+ def __init__(self, app, cls):
+ super(MoveMessagesTask, self).__init__(app, cls)
+
+ self.form = MoveMessagesForm(app, "move_messages", self)
+
+ def get_title(self, session):
+ return "Move messages"
+
+ def do_enter(self, session, queue):
+ self.form.queue.set(session, queue)
+
+ def do_invoke(self, completion, session, queue, dest_queue, count):
+ model = self.app.model.mint.model
+ broker = queue.vhost.broker
+ broker.queueMoveMessages \
+ (model, completion, queue.name, dest_queue.name, count)
+
+class ExchangeAddTask(Task):
+ MSG_SEQUENCE = "qpid.msg_sequence"
+ IVE = "qpid.ive"
+
+ def __init__(self, app, cls):
+ super(ExchangeAddTask, self).__init__(app, cls)
+
+ self.form = ExchangeAddForm(app, "exchange_add", self)
+
+ def get_title(self, session):
+ return "Add exchange"
+
+ def do_enter(self, session, vhost):
+ self.form.vhost.set(session, vhost)
+
+ def do_invoke(self, session, vhost, name, type, durable, sequence, ive):
+ assert isinstance(vhost, Vhost)
+
+ args = dict()
+
+ if sequence:
+ args[self.MSG_SEQUENCE] = 1
+
+ if ive:
+ args[self.IVE] = 1
+
+ session = self.app.model.get_session_by_object(vhost)
+ session.exchange_declare \
+ (exchange=name, type=type, durable=durable, arguments=args)
+ session.sync()
+
+class ExchangeRemoveTask(Task):
+ def __init__(self, app, cls):
+ super(ExchangeRemoveTask, self).__init__(app, cls)
+
+ self.form = ExchangeRemoveForm(app, "exchange_remove", self)
+
+ def get_title(self, session):
+ return "Remove"
+
+ def do_enter(self, session, exchange):
+ self.form.object.set(session, exchange)
+
+ def do_exit(self, session, exchange):
+ self.app.main_page.main.messaging.broker.view.show(session)
+
+ def do_invoke(self, session, exchange):
+ assert isinstance(exchange, Exchange)
+
+ session = self.app.model.get_session_by_object(exchange)
+ session.exchange_delete(exchange=exchange.name)
+ session.sync()
+
+class ExchangeSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(ExchangeSetRemoveTask, self).__init__(app, cls)
+
+ self.form = ExchangeSetRemoveForm(app, "exchange_set_remove", self)
+ self.item_task = ExchangeRemoveTask(app, cls)
+
+ def get_description(self, session, exchanges):
+ count = len(exchanges)
+ return "Remove %i exchange%s" % (count, ess(count))
+
+ def do_enter(self, session, exchanges):
+ self.form.object.set(session, exchanges)
+
+class LinkAddTask(QmfTask):
+ def __init__(self, app, cls):
+ super(LinkAddTask, self).__init__(app, cls)
+
+ self.form = LinkAddForm(app, "link_add", self)
+
+ def get_title(self, session):
+ return "Add broker link"
+
+ def get_description(self, session, vhost):
+ return "Add broker link to vhost '%s'" % get_vhost_name(vhost)
+
+ def do_enter(self, session, vhost):
+ self.form.vhost.set(session, vhost)
+
+ def do_invoke(self, completion, session, vhost,
+ host, port, durable, username, password, transport):
+ broker = vhost.broker
+
+ if username == "anonymous":
+ mech = "ANONYMOUS"
+ else:
+ mech = "PLAIN"
+
+ broker.connect(self.app.model.mint.model, completion,
+ host, port, durable, mech, username, password,
+ transport)
+
+class LinkRemoveTask(Task):
+ def __init__(self, app, cls):
+ super(LinkRemoveTask, self).__init__(app, cls)
+
+ self.form = LinkRemoveForm(app, "link_remove", self)
+
+ def get_title(self, session):
+ return "Remove"
+
+ def do_enter(self, session, link):
+ self.form.object.set(session, link)
+
+ def do_invoke(self, completion, session, link):
+ link.close(self.app.model.mint.model, completion)
+
+class LinkSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(LinkSetRemoveTask, self).__init__(app, cls)
+
+ self.form = LinkSetRemoveForm(app, "link_set_remove", self)
+ self.item_task = LinkRemoveTask(app, cls)
+
+ def do_enter(self, session, links):
+ self.form.object.set(session, links)
+
+class RouteAddTask(QmfTask):
+ def __init__(self, app, cls):
+ super(RouteAddTask, self).__init__(app, cls)
+
+ self.form = RouteAddForm(app, "route_add", self)
+
+ def get_title(self, session):
+ return "Add route"
+
+ def get_description(self, session, link):
+ return "Add route to link '%s:%i'" % (link.host, link.port)
+
+ def do_enter(self, session, link):
+ self.form.link.set(session, link)
+
+ def do_invoke(self, completion, session, link, exchange, key, tag,
+ dynamic, sync, excludes):
+ link.bridge(self.app.model.mint.model, completion,
+ link.durable, exchange.name, exchange.name,
+ key, tag, excludes, False, False, dynamic, sync)
+
+class RouteRemoveTask(QmfTask):
+ def get_title(self, session):
+ return "Remove"
+
+ def do_invoke(self, completion, session, route):
+ route.close(self.app.model.mint.model, completion)
+
+class RouteSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(RouteSetRemoveTask, self).__init__(app, cls)
+
+ self.form = RouteSetRemoveForm(app, "route_set_remove", self)
+ self.item_task = RouteRemoveTask(app, cls)
+
+ def do_enter(self, session, routes):
+ self.form.object.set(session, routes)
+
+class BrokerGroupAddTask(Task):
+ def __init__(self, app, cls):
+ super(BrokerGroupAddTask, self).__init__(app, cls)
+
+ self.form = BrokerGroupAddForm(app, "broker_group_add", self)
+
+ def get_title(self, session):
+ return "Add broker group"
+
+ def do_invoke(self, object, name):
+ group = BrokerGroup(name=name)
+ group.syncUpdate()
+ return group
+
+class BrokerGroupEditTask(Task):
+ def __init__(self, app, cls):
+ super(BrokerGroupEditTask, self).__init__(app, cls)
+
+ self.form = BrokerGroupEditForm(app, "broker_group_edit", self)
+
+ def get_title(self, session):
+ return "Edit"
+
+ def do_enter(self, session, group):
+ self.form.group.set(session, group)
+
+ def do_invoke(self, group, name):
+ assert isinstance(group, BrokerGroup)
+
+ group.set(name=name)
+ group.syncUpdate()
+
+class BrokerGroupRemoveTask(Task):
+ def __init__(self, app, cls):
+ super(BrokerGroupRemoveTask, self).__init__(app, cls)
+
+ self.form = BrokerGroupRemoveForm(app, "broker_group_remove", self)
+
+ def get_title(self, session):
+ return "Remove"
+
+ def do_enter(self, session, group):
+ self.form.object.set(session, group)
+
+ def do_exit(self, session, group):
+ self.app.main_page.main.messaging.view.show(session)
+
+ def do_invoke(self, group):
+ assert isinstance(group, BrokerGroup)
+
+ group.destroySelf()
+ group.syncUpdate()
+
+class BrokerGroupSetRemoveTask(SetTask):
+ def __init__(self, app, cls):
+ super(BrokerGroupSetRemoveTask, self).__init__(app, cls)
+
+ self.form = BrokerGroupSetRemoveForm(app, "broker_groups_remove",
self)
+ self.item_task = BrokerGroupRemoveTask(app, cls)
+
+ def do_enter(self, session, groups):
+ self.form.groups.set(session, groups)
+
+class BrokerEngroupTask(Task):
+ def get_title(self, session):
+ return "Add to groups"
+
+ def do_invoke(self, session, broker):
+ print "XXX engroup", broker
+
+class BrokerSetEngroupTask(SetTask):
+ def __init__(self, app, cls):
+ super(BrokerSetEngroupTask, self).__init__(app, cls)
+
+ self.form = BrokerSetEngroupForm(app, "brokers_engroup", self)
+ self.item_task = BrokerEngroupTask(app, cls)
+
+ def get_description(self, session, brokers):
+ count = len(brokers)
+ return "Place %i broker%s in broker groups" % (count, ess(count))
+
+ def do_enter(self, session, brokers):
+ self.form.object.set(session, brokers)
+
+ def do_invoke(self, brokers):
+ pass
+
+def get_vhost_name(vhost):
+ broker = vhost.broker
+ name = broker.system.nodeName
+ port = broker.port
+
+ return "%s:%i" % (name, port)
Modified: mgmt/trunk/cumin/python/cumin/messaging/queue.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/queue.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/queue.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -10,6 +10,7 @@
from sqlobject.sqlbuilder import LEFTJOINOn
from cumin.stat import *
from cumin.widgets import *
+from cumin.modelwidgets import *
from cumin.parameters import *
from cumin.formats import *
from cumin.util import *
@@ -17,21 +18,20 @@
from binding import *
from exchange import ExchangeInputSet
+import main
+
strings = StringCatalog(__file__)
log = logging.getLogger("cumin.messaging.queue")
-class QueueSet(CuminTable, Form):
+class QueueSet(CuminSelectionTable):
def __init__(self, app, name, vhost):
- super(QueueSet, self).__init__(app, name)
+ item = QueueParameter(app, "item")
+ super(QueueSet, self).__init__(app, name, item)
self.vhost = vhost
- self.ids = CheckboxIdColumn(app, "id")
- self.add_column(self.ids)
-
col = self.NameColumn(app, "name")
self.add_column(col)
-
self.set_default_column(col)
col = self.ConsumersColumn(app, "consumers")
@@ -55,21 +55,21 @@
self.add_column(col)
self.unit = UnitSwitch(app, "unit")
- self.add_child(self.unit)
+ self.switches.add_child(self.unit)
self.phase = PhaseSwitch(app, "phase")
- self.add_child(self.phase)
+ self.filters.add_child(self.phase)
- self.__purge = self.Purge(app, "purge")
- self.add_child(self.__purge)
+ task = main.module.queue_add
+ self.links.add_child(TaskLink(app, "add", task, vhost))
- self.__remove = self.Remove(app, "remove")
- self.add_child(self.__remove)
+ task = main.module.queue_set_purge
+ button = TaskButton(app, "purge", task, self.selection)
+ self.buttons.add_child(button)
- def render_add_queue_url(self, session):
- branch = session.branch()
- self.frame.queue_add.show(branch)
- return branch.marshal()
+ task = main.module.queue_set_remove
+ button = TaskButton(app, "remove", task, self.selection)
+ self.buttons.add_child(button)
def render_title(self, session):
return "Queues %s" % fmt_count(Queue.select().count())
@@ -87,38 +87,13 @@
vhost = self.vhost.get(session)
return {"id": vhost.id}
- class Purge(FormButton):
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- self.frame.queues_purge.show(branch).ids.set(branch, ids)
- self.page.set_redirect_url(session, branch.marshal())
-
- def render_content(self, session):
- return "Purge"
-
- class Remove(FormButton):
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
-
- branch = session.branch()
- self.frame.queues_remove.show(branch).ids.set(branch, ids)
- self.page.set_redirect_url(session, branch.marshal())
-
- def render_content(self, session):
- return "Remove"
-
class NameColumn(ClientTruncateColumn):
def render_title(self, session, data):
return "Name"
def render_content(self, session, data):
queue = Identifiable(data["id"])
- href = self.page.main.messaging.broker.queue.get_href \
- (session, queue)
+ href = main.module.frame.broker.queue.get_href(session, queue)
return fmt_link(href, data["name"],
link_title=data["name"])
class ConsumersColumn(SqlTableColumn):
@@ -203,7 +178,8 @@
self.page.main.messaging.broker.object.set(branch, broker)
self.page.main.messaging.broker.queue.object.set(branch, queue)
self.page.main.messaging.broker.queue.show(branch)
- return fmt_link(branch.marshal(), data["name"],
link_title=data["name"])
+ return fmt_link \
+ (branch.marshal(), data["name"],
link_title=data["name"])
class EnqueuesColumn(TopTableColumn):
def render_title(self, session, data):
@@ -216,21 +192,9 @@
self.object = QueueParameter(app, "id")
self.add_parameter(self.object)
- self.view = QueueView(app, "view")
+ self.view = QueueView(app, "view", self.object)
self.add_mode(self.view)
- self.purge = QueuePurge(app, "purge")
- self.add_mode(self.purge)
-
- self.binding_add = QueueBindingAdd(app, "bindingadd", self.object)
- self.add_mode(self.binding_add)
-
- self.remove = QueueRemove(app, "remove")
- self.add_mode(self.remove)
-
- self.move_messages = QueueMoveMessages(app, "move_messages")
- self.add_mode(self.move_messages)
-
def show_object(self, session, queue):
#XXX self.page.main.messaging.broker.object.set(session, queue.vhost.broker)
return super(QueueFrame, self).show_object(session, queue)
@@ -245,112 +209,72 @@
else:
return "Queue"
-class QueueStatus(CuminStatus):
- def render_consumers(self, session, queue):
- return self.app.model.queue.consumers.value(queue)
-
- def render_messages_enqueued(self, session, queue):
- return self.app.model.queue.msgTotalEnqueues.rate_html(queue)
-
- def render_messages_dequeued(self, session, queue):
- return self.app.model.queue.msgTotalDequeues.rate_html(queue)
-
- def render_message_depth(self, session, queue):
- return self.app.model.queue.msgDepth.value(queue)
-
- def render_message_depth_accel(self, session, queue):
- return self.app.model.queue.msgDepth.rate_html(queue)
-
- def render_bytes_enqueued(self, session, queue):
- return self.app.model.queue.byteTotalEnqueues.rate_html(queue)
-
- def render_bytes_dequeued(self, session, queue):
- return self.app.model.queue.byteTotalDequeues.rate_html(queue)
-
- def render_byte_depth(self, session, queue):
- return self.app.model.queue.byteDepth.value(queue)
-
- def render_byte_depth_accel(self, session, queue):
- return self.app.model.queue.byteDepth.rate_html(queue)
-
class QueueView(CuminView):
- def __init__(self, app, name):
+ def __init__(self, app, name, queue):
super(QueueView, self).__init__(app, name)
- #status = QueueStatus(app, "status")
- #self.add_child(status)
+ self.tabs = TabbedModeSet(app, "tabs")
+ self.add_child(self.tabs)
- self.__tabs = TabbedModeSet(app, "tabs")
- self.add_child(self.__tabs)
+ self.tabs.add_tab(QueueStats(app, "stats"))
- self.__tabs.add_tab(QueueStats(app, "stats"))
+ self.bindings = QueueBindingSet(app, "bindings", queue)
+ self.tabs.add_tab(self.bindings)
- self.bindings = QueueBindingSet(app, "bindings")
- self.__tabs.add_tab(self.bindings)
+ self.tabs.add_tab(CuminDetails(app, "details", queue))
- self.details = CuminDetails(app, "details")
- self.__tabs.add_tab(self.details)
-
- def show_bindings(self, session):
- self.bindings.show(session);
-
-class QueueBindingSet(BindingSet, Form):
- def __init__(self, app, name):
+class QueueBindingSet(BindingSet):
+ def __init__(self, app, name, queue):
super(QueueBindingSet, self).__init__(app, name)
- self.__remove = self.Remove(app, "remove")
- self.add_child(self.__remove)
+ self.queue = queue
self.set_default_column_name("e_id")
+ task = main.module.binding_add
+ self.links.add_child(TaskLink(app, "add", task, self.queue))
+
def get_visible_columns(self, session):
return self.get_request_visible_columns(session, ["e_id"])
- def render_add_queue_binding_url(self, session, *args):
- branch = session.branch()
- self.frame.binding_add.show(branch)
- return branch.marshal()
+ def get_sql_values(self, session):
+ queue = self.queue.get(session)
+ return {"id": queue.id}
- def render_sql_where(self, session, queue):
+ def render_sql_where(self, session):
+ queue = self.queue.get(session)
+
elems = list()
elems.append("b.queue_id = %(id)r")
elems.append(self.phase.get_sql_constraint(session, queue))
+
return "where %s" % " and ".join(elems)
- def render_title(self, session, queue):
+ def render_title(self, session):
+ queue = self.queue.get(session)
return "Exchange Bindings %s" % \
fmt_count(queue.bindings.count())
- class Remove(FormButton):
- def process_submit(self, session):
- ids = self.parent.ids.get(session)
- self.parent.ids.clear(session)
+class QueueAddForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(QueueAddForm, self).__init__(app, name)
- href = self.frame.frame.bindings_remove.get_href \
- (session, ids)
- self.page.set_redirect_url(session, href)
+ self.task = task
- def render_content(self, session):
- return "Remove"
+ self.vhost = VhostParameter(app, "vhost")
+ self.add_parameter(self.vhost)
-class QueueForm(CuminFieldForm):
- def __init__(self, app, name, vhost):
- super(QueueForm, self).__init__(app, name)
-
- assert vhost
-
- self.vhost = vhost
-
self.namef = NameField(app, "name")
self.add_field(self.namef)
- self.more = MoreFieldSet(app, "more")
+ self.more = self.AdvancedOptions(app, "more")
self.add_field(self.more)
self.durable = self.QueueDurabilityField(app, "durable")
self.more.add_field(self.durable)
- self.cluster_durable = self.ClusterDurabilityField(app,
"cluster_durable")
+ self.cluster_durable = self.ClusterDurabilityField \
+ (app, "cluster_durable")
self.more.add_field(self.cluster_durable)
self.lvq = self.LVQField(app, "lvq")
@@ -380,20 +304,24 @@
self.add_field(self.bindings)
def validate(self, session, queue_name):
- super_error = super(QueueForm, self).validate(session)
+ super_error = super(QueueAddForm, self).validate(session)
(errors, form_binding_info) = self.bindings.get_binding_errors(session,
queue_name)
return (errors or super_error, form_binding_info)
+ class AdvancedOptions(MoreFieldSet):
+ def render_title(self, session):
+ return "Advanced Options"
+
class QCountField(IntegerField):
def render_title(self, session):
- return "<div style=\"padding-left: 1em;\">Max Queue
Count</div>"
+ return "Max Queue Count"
def render_field_help(self, session):
return "(Maximum in-memory queue size as a number of messages. Applies
if Policy is set.)"
class QSizeField(IntegerField):
def render_title(self, session):
- return "<div style=\"padding-left: 1em;\">Max Queue
Size</div>"
+ return "Max Queue Size"
def render_field_help(self, session):
return "(Maximum in-memory queue size as bytes. Applies if Policy is
set.)"
@@ -466,7 +394,7 @@
class PolicyField(RadioField):
def __init__(self, app, name):
- super(QueueForm.PolicyField, self).__init__(app, name, None)
+ super(QueueAddForm.PolicyField, self).__init__(app, name, None)
self.param = Parameter(app, "param")
self.param.default = "none"
@@ -528,15 +456,6 @@
def render_title(self, session):
return "Ring Strict"
-class QueueAdd(QueueForm):
- def __init__(self, app, name, vhost):
- super(QueueAdd, self).__init__(app, name, vhost)
-
- def process_cancel(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
def process_submit(self, session):
vhost = self.vhost.get(session)
name = self.namef.get(session)
@@ -546,8 +465,7 @@
errors, binding_info = self.validate(session, name)
if not errors:
- action = self.app.model.broker.add_queue
- invoc = action.begin(vhost)
+ invoc = self.task.start(session, vhost)
try:
args = dict()
@@ -570,7 +488,7 @@
args["qpid.optimistic_consume"] = \
self.optimistic.get(session) == "yes"
- qsession = action.get_session_by_object(vhost)
+ qsession = self.app.model.get_session_by_object(vhost)
qsession.queue_declare(queue=name,
durable=durable,
@@ -590,116 +508,71 @@
binding_key=binding_key,
arguments=eargs)
- invoc.status = "OK"
+ self.task.end(invoc)
except Exception, e:
- invoc.status = "failed"
- invoc.exception = e
+ self.task.exception(invoc, e)
- log.exception(e)
+ self.process_return(session)
- # navigate back to main queue frame
- self.process_cancel(session)
-
def render_title(self, session):
- broker = self.vhost.get(session).broker
- title = self.app.model.broker.get_object_title(session, broker)
- return "Add Queue to %s" % title
+ vhost = self.vhost.get(session)
+ return self.task.get_description(session, vhost)
-class QueueRemove(CuminConfirmForm):
- def get_args(self, session):
- return self.frame.get_args(session)
+class QueueRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(QueueRemoveForm, self).__init__(app, name, task)
- def render_title(self, session, queue):
- return "Remove Queue '%s'" % queue.name
+ self.object = QueueParameter(app, "queue")
+ self.add_parameter(self.object)
- def process_submit(self, session, queue):
- action = self.app.model.queue.remove
- action.invoke(queue)
+class QueuePurgeForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(QueuePurgeForm, self).__init__(app, name)
- self.process_cancel(session, queue)
+ self.task = task
- def render_submit_content(self, session, queue):
- return "Yes, Remove Queue '%s'" % queue.name
+ self.queue = QueueParameter(app, "queue")
+ self.add_parameter(self.queue)
- def render_cancel_content(self, session, queue):
- return "No, Cancel"
-
-class QueuePurge(CuminFieldForm):
- def __init__(self, app, name):
- super(QueuePurge, self).__init__(app, name)
-
self.purge_request = MultiplicityField(app, "purge_request")
self.add_field(self.purge_request)
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, queue):
+ def render_title(self, session):
+ queue = self.queue.get(session)
return "Purge Messages from Queue '%s'" % queue.name
- def process_submit(self, session, queue):
+ def process_submit(self, session):
+ queue = self.queue.get(session)
request_amt = self.purge_request.get(session)
- args = dict()
if request_amt == "all":
- args["request"] = 0
+ count = 0
elif request_amt == "top":
- args["request"] = 1
+ count = 1
elif request_amt == "N":
- args["request"] = self.purge_request.top_n.get_n_value(session)
+ count = self.purge_request.top_n.get_n_value(session)
else:
raise Exception("Wrong Value")
- action = self.app.model.queue.purge
- action.invoke(queue, args)
+ self.task.invoke(session, queue, count)
+ self.task.exit_with_redirect(session, queue)
- self.process_cancel(session, queue)
-
- def render_submit_content(self, session, queue):
+ def render_submit_content(self, session):
+ queue = self.queue.get(session)
return "Yes, Purge Messages from Queue '%s'" % queue.name
- def render_cancel_content(self, session, queue):
+ def render_cancel_content(self, session):
return "No, Cancel"
-class QueueSetPurge(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
+class QueueSetTaskForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(QueueSetTaskForm, self).__init__(app, name, task)
- def process_item(self, session, id):
- queue = Queue.get(id)
+ item = QueueParameter(app, "item")
- args = dict()
- args["request"] = 0
+ self.object = ListParameter(app, "queue", item)
+ self.add_parameter(self.object)
- action = self.app.model.queue.purge
- action.invoke(queue, args)
-
- def render_title(self, session):
- return "Purge Queues"
-
- def render_item_content(self, session, id):
- return "Purge Queue '%s'" % Queue.get(id).name
-
-
-class QueueSetRemove(CuminBulkActionForm):
- def process_return(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
- def process_item(self, session, id):
- queue = Queue.get(id)
- action = self.app.model.queue.remove
- action.invoke(queue)
-
- def render_title(self, session):
- return "Remove Queues"
-
- def render_item_content(self, session, id):
- return "Remove Queue '%s'" % Queue.get(id).name
-
class BindSummaryPropertiesField(FormField):
def __init__(self, app, name):
super(BindSummaryPropertiesField, self).__init__(app, name)
@@ -725,95 +598,62 @@
return self.sum_props.render_items(session, *args)
def get_args(self, session):
- return (self.frame.frame.get_object(session),)
+ return (self.form.queue.get(session),)
-class QueueBindingAdd(CuminFieldForm):
- def __init__(self, app, name, queue):
- super(QueueBindingAdd, self).__init__(app, name)
+class BindingAddForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(BindingAddForm, self).__init__(app, name)
- self.queue = queue
+ self.task = task
- self.vhost = self.VhostAttribute(self, "vhost")
+ self.queue = QueueParameter(app, "queue")
+ self.add_parameter(self.queue)
+
+ self.vhost = self.VhostAttribute(app, "vhost")
self.add_attribute(self.vhost)
self.props = BindSummaryPropertiesField(app, "props")
self.add_field(self.props)
- self.bindings = ExchangeKeysField(app, "bindings", self.vhost,
- title="Bind to Exchange:")
+ self.bindings = self.ExchangeBindings(app, "bindings", self.vhost)
self.add_field(self.bindings)
- self.errors = self.Errors(self, "errors")
- self.add_attribute(self.errors)
+ class ExchangeBindings(ExchangeKeysField):
+ def render_title(self, session):
+ return "Exchange Bindings"
class VhostAttribute(Attribute):
- def get_default(self, session):
+ def get(self, session):
return self.widget.queue.get(session).vhost
- def render_form_error(self, session):
- errors = self.errors.get(session)
- if "no_exchanges" in errors:
- return "<ul class=\"errors\" style=\"margin:0;
float:left;\"><li>%s</li></ul>" % \
- "</li><li>".join(errors["no_exchanges"])
-
- def process_cancel(self, session):
- branch = session.branch()
- self.frame.view.show(branch)
- self.page.set_redirect_url(session, branch.marshal())
-
def process_submit(self, session):
queue = self.queue.get(session)
- (errors, form_binding_info) = self.bindings.get_binding_errors(session,
queue.name)
+ errors, form_binding_info = self.bindings.get_binding_errors \
+ (session, queue.name)
if not len(form_binding_info):
- # no exhchanges were selected is not an
- # error that ExchangeKeysField looks for
- errors = self.errors.get(session)
- errs = errors.setdefault("no_exchanges", list())
- errs.append("At least one exchange must be selected")
- errors = True
+ # no exchanges were selected is not an error that
+ # ExchangeKeysField looks for
+ error = FormError("At least one exchange must be selected")
+ self.errors.add(session, error)
- if errors:
- pass
- else:
- reg = self.frame.frame.get_object(session)
- args = {
- "exchange_keys": form_binding_info,
- "reg": reg}
+ if not self.errors.get(session):
+ print "XXX queue binding add", queue, form_binding_info
- action = self.app.model.queue.bind
- action.invoke(queue, args)
+ #self.task.invoke(session, queue, args)
+ self.task.exit_with_redirect(session, queue)
- # navigate back to main queue frame
- self.process_cancel(session)
-
- def render_title(self, session, *args):
+ def render_title(self, session):
queue = self.queue.get(session)
- title = self.app.model.queue.get_object_title(session, queue)
- return "Add Binding to %s" % title
+ return self.task.get_description(session, queue)
- class Errors(Attribute):
- def get_default(self, session):
- return dict()
+class BindingRemoveForm(CuminTaskForm):
+ def __init__(self, app, name, task):
+ super(BindingRemoveForm, self).__init__(app, name, task)
-class QueueBindingRemove(CuminConfirmForm):
- def get_args(self, session):
- return self.frame.get_args(session)
+ self.object = BindingParameter(app, "binding")
+ self.add_parameter(self.object)
- def process_submit(self, session, binding):
- log.info("Removing binding %s", binding)
-
- self.process_cancel(session, binding)
-
- def render_title(self, session, binding):
- return "Remove Binding"
-
- def render_submit_content(self, session, binding):
- return "Yes, Remove Binding"
-
- def render_cancel_content(self, session, binding):
- return "No, Cancel"
-
class QueueStats(TabbedModeSet):
def __init__(self, app, name):
super(QueueStats, self).__init__(app, name)
@@ -963,73 +803,34 @@
def render_title(self, session, queue):
return "Transactional Messages Enqueued and Dequeued"
-class QueueConsumerSet(PaginatedItemSet):
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, queue):
- count = fmt_count(self.get_item_count(session, queue))
- return "Consumers %s" % count
-
- def get_item_count(self, session, queue):
- return queue.consumers.count()
-
- def do_get_items(self, session, queue):
- start, end = self.get_bounds(session)
- return queue.consumers[start:end]
-
- def render_item_name(self, session, consumer):
- return consumer.name
-
- def render_item_messages_consumed(self, session, consumer):
- return self.app.model.consumer.msgsConsumed.value(consumer)
-
- def render_item_messages_consumed_rate(self, session, consumer):
- return self.app.model.consumer.msgsConsumed.rate_html(consumer)
-
- def render_item_bytes_consumed(self, session, consumer):
- return self.app.model.consumer.bytesConsumed.value(consumer)
-
- def render_item_bytes_consumed_rate(self, session, consumer):
- return self.app.model.consumer.bytesConsumed.rate_html(consumer)
-
- def render_item_unacked_messages(self, session, consumer):
- return self.app.model.consumer.unackedMessages.value(consumer)
-
-
class QueueSelectField(FormField):
def __init__(self, app, name, form):
super(QueueSelectField, self).__init__(app, name)
- param = QueueParameter(app, "param")
- self.param = param
- self.add_parameter(param)
+ self.param = QueueParameter(app, "param")
+ self.add_parameter(self.param)
- self.queue_set = self.QueueInputSet(app, "queue_set", param)
+ self.queue_set = self.QueueInputSet(app, "queue_set", self.param)
self.add_child(self.queue_set)
def get(self, session):
return self.param.get(session)
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def render_title(self, session, queue):
+ def render_title(self, session):
return "Select the destination queue"
- def render_inputs(self, session, queue):
+ def render_inputs(self, session):
return self.queue_set.render(session)
class QueueInputSet(RadioInputSet):
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def do_get_items(self, session, queue):
+ def do_get_items(self, session):
+ queue = self.form.queue.get(session)
queue_list_full = sorted_by(list(queue.vhost.queues))
delta = timedelta(minutes=10)
queue_list = []
for _queue in queue_list_full:
- if (_queue.qmfUpdateTime > (datetime.now() - delta)) and (_queue.name
!= queue.name):
+ if (_queue.qmfUpdateTime > (datetime.now() - delta)) \
+ and (_queue.name != queue.name):
queue_list.append(_queue)
return queue_list
@@ -1040,45 +841,40 @@
return queue.name or "<em>Default</em>"
def render_item_checked_attr(self, session, queue):
- return queue is self.param.get(session) and
"checked=\"checked\"" or None
+ return queue is self.param.get(session) \
+ and "checked=\"checked\"" or None
-class QueueMoveMessages(CuminFieldForm):
- def __init__(self, app, name):
- super(QueueMoveMessages, self).__init__(app, name)
+class MoveMessagesForm(CuminFieldForm):
+ def __init__(self, app, name, task):
+ super(MoveMessagesForm, self).__init__(app, name)
- self.move_to = QueueSelectField(app, "move_to", self)
- self.add_field(self.move_to)
+ self.task = task
- self.move_qty = MultiplicityField(app, "move_qty")
- self.add_field(self.move_qty)
+ self.queue = QueueParameter(app, "queue")
+ self.add_parameter(self.queue)
- def get_args(self, session):
- return self.frame.get_args(session)
+ self.dest_queue = QueueSelectField(app, "dest", self)
+ self.add_field(self.dest_queue)
- def render_title(self, session, queue):
- return "Move Messages from Queue '%s'" % queue.name
+ self.count = MultiplicityField(app, "count")
+ self.add_field(self.count)
- def process_submit(self, session, queue):
- request_qty = self.move_qty.get(session)
- args = dict()
- args["destQueue"] = self.move_to.get(session).name
- args["srcQueue"] = queue.name
+ def process_submit(self, session):
+ self.check(session)
- if request_qty == "all":
- args["qty"] = 0
- elif request_qty == "top":
- args["qty"] = 1
- elif request_qty == "N":
- args["qty"] = self.move_qty.top_n.get_n_value(session)
- else:
- raise Exception("Wrong Value")
+ if not self.errors.get(session):
+ queue = self.queue.get(session)
+ dest_queue = self.dest_queue.get(session)
+ scount = self.count.get(session)
- action = self.app.model.queue.move_messages
- action.invoke(queue, args)
- self.process_cancel(session, queue)
+ if scount == "all":
+ count = 0
+ elif scount == "top":
+ count = 1
+ elif scount == "N":
+ count = self.move_qty.top_n.get_n_value(session)
+ else:
+ raise Exception("Wrong Value")
- def render_submit_content(self, session, queue):
- return "Yes, Move Messages from Queue '%s'" % queue.name
-
- def render_cancel_content(self, session, queue):
- return "No, Cancel"
+ self.task.invoke(session, queue, dest_queue, count)
+ self.task.exit_with_redirect(session, queue)
Modified: mgmt/trunk/cumin/python/cumin/messaging/queue.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/messaging/queue.strings 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/messaging/queue.strings 2009-06-17 20:20:11 UTC (rev
3457)
@@ -34,38 +34,6 @@
left outer join queue_stats as c on c.id = q.stats_curr_id
{sql_where}
-[QueueSet.html]
-<form id="{id}" method="post" action="?">
- <ul class="actions">
- <li><a class="nav" href="{add_queue_url}">Add New
Queue</a></li>
- </ul>
- <div class="rfloat">{phase}</div>
- {unit}
-
- <div class="sactions">
- <h2>Act on Selected Queues:</h2>
- {purge} {remove}
- </div>
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- </thead>
- </table>
- <table class="mobjects{extra_class}">
- <thead>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
-
- <div>{hidden_inputs}</div>
-</form>
-
[TopQueueSet.sql]
select
q.id,
@@ -109,37 +77,6 @@
</table>
</div>
-[QueueBindingSet.html]
-<form id="{id}" method="post" action="?">
- <div class="rfloat">{phase}</div>
-
- <ul class="actions">
- <li><a class="nav" href="{add_queue_binding_url}">Add
Binding</a></li>
- </ul>
-
- <div class="sactions">
- <h2>Act on Selected Bindings:</h2>
- {remove}
- </div>
-
- <table class="mobjects">
- <thead>
- <tr>
- <th class="setnav" colspan="{column_count}">
- <div class="rfloat">{page}</div>
- {count}
- </th>
- </tr>
- <tr>{headers}</tr>
- </thead>
- <tbody>{items}</tbody>
- </table>
- <div>{hidden_inputs}</div>
-</form>
-
-[ExchangeBindingSet.item_html]
-<tr>{cells}</tr>
-
[QueueStats.html]
<ul class="radiotabs tabs">{tabs}</ul>
<div class="radiotabs mode">{content}</div>
@@ -216,38 +153,6 @@
</tbody>
</table>
-[QueueConsumerSet.html]
-<div class="sactions">
- <h2>Act on Selected Consumers:</h2>
- <button>Start</button>
- <button>Stop</button>
- <button>Close</button>
- <button>Throttle</button>
-</div>
-
-<table class="mobjects">
- <tr>
- <th><input type="checkbox"/></th>
- <th>Name</th>
- <th class="ralign" colspan="2">Msgs. Consumed</th>
- <th class="ralign" colspan="2">Bytes Consumed</th>
- <th class="ralign">Msgs. Unacked</th>
- </tr>
-
- {items}
-</table>
-
-[QueueConsumerSet.item_html]
-<tr>
- <td><input type="checkbox"/></td>
- <td>{item_name}</td>
- <td class="ralign">{item_messages_consumed_rate}</td>
- <td class="ralign">{item_messages_consumed}</td>
- <td class="ralign">{item_bytes_consumed_rate}</td>
- <td class="ralign">{item_bytes_consumed}</td>
- <td class="ralign">{item_unacked_messages}</td>
-</tr>
-
[BindSummaryPropertiesField.properties_html]
<div class="properties" style="width:80%">
<table class="PropertySet">
Modified: mgmt/trunk/cumin/python/cumin/model.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/model.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/model.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -16,6 +16,8 @@
from parameters import *
from util import *
+import wooly
+
log = logging.getLogger("cumin.model")
class CuminModel(object):
@@ -37,6 +39,9 @@
self.frame = None
+ self.tasks = list()
+ self.task_invocations = list()
+
# Messaging
CuminBroker(self)
@@ -74,6 +79,10 @@
CuminSlot(self)
CuminGrid(self)
+ # Other
+
+ CuminSubject(self)
+
def check(self):
self.mint.check()
@@ -136,6 +145,13 @@
for coll in Collector.select():
return Pool(coll)
+ def get_session_by_object(self, object):
+ assert object
+
+ broker = self.mint.model.mintBrokersById[object.qmfBrokerId]
+
+ return broker.getAmqpSession()
+
class CuminProperty(object):
def __init__(self, cls, name):
self.model = cls.model
@@ -398,17 +414,17 @@
if conn:
cursor = conn.cursor()
- sql = """select max(qmf_update_time) as interval_end,
+ sql = """select max(qmf_update_time) as interval_end,
cast(avg(%s) as integer) as value,
stddev(%s) as dev
from %s
where %s
group by floor(extract(epoch from qmf_update_time) / %i)
order by interval_end desc;""" % (field_name, field_name,
- table_name,
- where,
+ table_name,
+ where,
interval)
-
+
cursor.execute(sql)
return cursor.fetchall()
@@ -536,6 +552,9 @@
self.stats = list()
self.actions = list()
+ self.tasks = list()
+ self.tasks_by_class = dict()
+
self.frame = None
self.model.add_class(self)
@@ -556,7 +575,13 @@
self.actions.append(action)
setattr(self, action.name, action)
+ def add_task(self, task):
+ self.tasks.append(task)
+ self.tasks_by_class[task.__class__] = task
+
def init(self):
+ log.debug("Initializing class %s", self)
+
for prop in self.properties:
prop.init()
@@ -569,6 +594,10 @@
for action in self.actions:
action.init()
+ for task in self.tasks:
+ log.debug("Initializing task %s", task)
+ task.init()
+
def get_title(self, session):
return "Object"
@@ -616,6 +645,9 @@
writer.write("</%s>" % self.cumin_name)
+ def __str__(self):
+ return "%s.%s" % (self.__module__, self.__class__.__name__)
+
class RemoteClass(CuminClass):
def __init__(self, model, name, mint_class, mint_stats_class):
super(RemoteClass, self).__init__(model, name, mint_class)
@@ -683,6 +715,8 @@
stat.category = "general"
def init(self):
+ super(CuminGrid, self).init()
+
self.frame = self.model.frame.grid.pool
def get_title(self, session):
@@ -804,6 +838,8 @@
#action.summary = True
def init(self):
+ super(CuminSystem, self).init()
+
self.frame = self.model.frame.inventory.system
def get_title(self, session):
@@ -893,18 +929,9 @@
stat = self.StatusStat(self, "connection")
stat.category = "status"
- action = self.EngroupSet(self, "engroup_set")
-
- action = self.AddExchange(self, "add_exchange")
- action.summary = True
-
- action = self.AddLink(self, "add_link")
- action.summary = True
-
- action = self.AddQueue(self, "add_queue")
- action.summary = True
-
def init(self):
+ super(CuminBroker, self).init()
+
self.frame = self.model.frame.messaging.broker
def get_icon_href(self, session):
@@ -943,94 +970,6 @@
def rate_text(self, record):
return ""
- class EngroupSet(CuminSetAction):
- def show(self, session, brokers):
- frame = self.model.frame.messaging.brokers_group
- frame.objects.set(session, brokers)
- return frame.show(session)
-
- def get_title(self, session):
- return "Add to Group"
-
- class AddExchange(CuminAction):
- MSG_SEQUENCE = "qpid.msg_sequence"
- IVE = "qpid.ive"
-
- def get_title(self, session):
- return "Add Exchange"
-
- def get_verb(self, session):
- return "Add"
-
- def show(self, session, reg):
- frame = self.cumin_class.show_object(session, reg)
- frame.set_object(session, reg)
- return frame.exchange_add.show(session)
-
- def do_invoke(self, exchange, args, completion):
- declArgs = {}
-
- if args["sequence"]:
- declArgs[self.MSG_SEQUENCE] = 1
- if args["ive"]:
- declArgs[self.IVE] = 1
-
- session = self.get_session_by_object(exchange)
- session.exchange_declare(exchange=exchange.name,
- type=exchange.type,
- durable=exchange.durable,
- arguments=declArgs)
-
- # if the above call fails, an exception is
- # raised and we won't get here
-
- completion("OK")
-
- class AddLink(CuminAction):
- def get_title(self, session):
- return "Add Broker Link"
-
- def get_verb(self, session):
- return "Add"
-
- def show(self, session, reg):
- frame = self.cumin_class.show_object(session, reg)
- frame.set_object(session, reg)
- return frame.link_add.show(session)
-
- def do_invoke(self, broker, args, completion):
- host = args["host"]
- port = args["port"]
- durable = args["durable"]
- username = args["username"]
- password = args["password"]
- transport = args["transport"]
-
- if username == "anonymous":
- authMechanism = "ANONYMOUS"
- else:
- authMechanism = "PLAIN"
-
- broker.connect(self.mint.model, completion, host, port, durable,
- authMechanism, username, password, transport)
-
- class AddQueue(CuminAction):
- def get_title(self, session):
- return "Add Queue"
-
- def get_verb(self, session):
- return "Add"
-
- def get_description(self, session, vhost):
- host = vhost.broker.system.nodeName
- port = vhost.broker.port
- return "Add Queue to %s:%i" % (host, port)
-
- def show(self, session, reg):
- frame = self.cumin_class.show_object(session, reg)
- frame.set_object(session, reg)
- return frame.queue_add.show(session)
-
# XXX "do_" on this doesn't make sense
def do_bind(session, queue_name, binding_info):
for exchange in binding_info:
@@ -1214,84 +1153,17 @@
stat.unit = "byte"
stat.category = "io.durable"
- action = self.Purge(self, "purge")
- action.summary = True
-
- action = self.Remove(self, "remove")
- action.summary = True
-
- action = self.Bind(self, "bind")
- action.summary = True
-
def init(self):
+ super(CuminQueue, self).init()
+
self.frame = self.model.frame.messaging.broker.queue
- action = self.MoveMessages(self, "move_messages")
- action.summary = True
-
def get_title(self, session):
return "Queue"
def get_icon_href(self, session):
return "resource?name=queue-36.png"
- class Purge(CuminAction):
- def show(self, session, queue):
- frame = self.model.frame.messaging.broker
- frame.queue.set_object(session, queue)
- return frame.queue.purge.show(session)
-
- def get_title(self, session):
- return "Purge"
-
- def do_invoke(self, queue, args, completion):
- queue.purge(self.mint.model, completion, args["request"])
-
- class Remove(CuminAction):
- def show(self, session, queue):
- frame = self.model.frame.messaging.broker
- frame.queue.set_object(session, queue)
- return frame.queue.remove.show(session)
-
- def get_title(self, session):
- return "Remove"
-
- def do_invoke(self, queue, args, completion):
- session = self.get_session_by_object(queue)
- session.queue_delete(queue=queue.name)
-
- completion("OK")
-
- class Bind(CuminAction):
- def show(self, session, queue):
- frame = self.model.frame.messaging.broker
- frame.queue.set_object(session, queue)
- return frame.queue.binding_add.show(session)
-
- def get_title(self, session):
- return "Bind"
-
- def do_invoke(self, queue, args, completion):
- session = self.get_session_by_object(queue)
- binding_info = args['exchange_keys']
- do_bind(session, queue.name, binding_info)
-
- completion("OK")
-
- class MoveMessages(CuminAction):
- def show(self, session, queue):
- frame = self.cumin_class.show_object(session, queue)
- return frame.move_messages.show(session)
-
- def get_title(self, session):
- return "Move Messages"
-
- def do_invoke(self, queue, args, completion):
- broker = queue.vhost.broker
- broker.queueMoveMessages(self.mint.model, completion,
- args["srcQueue"],
args["destQueue"],
- args["qty"])
-
class CuminExchange(RemoteClass):
def __init__(self, model):
super(CuminExchange, self).__init__(model, "exchange",
@@ -1353,10 +1225,9 @@
stat.unit = "message"
stat.category = "io"
- action = self.Remove(self, "remove")
- action.summary = True
-
def init(self):
+ super(CuminExchange, self).init()
+
self.frame = self.model.frame.messaging.broker.exchange
def get_title(self, session):
@@ -1373,20 +1244,6 @@
else:
return "Default Exchange"
- class Remove(CuminAction):
- def get_title(self, session):
- return "Remove"
-
- def show(self, session, exchange):
- frame = self.cumin_class.show_object(session, exchange)
- return frame.remove.show(session)
-
- def do_invoke(self, exchange, args, completion):
- session = self.get_session_by_object(exchange)
- session.exchange_delete(exchange=exchange.name)
-
- completion("OK")
-
class CuminBinding(RemoteClass):
def __init__(self, model):
super(CuminBinding, self).__init__(model, "binding",
@@ -1399,39 +1256,16 @@
stat.title = "Msgs. Matched"
stat.unit = "message"
- action = self.Remove(self, "remove")
- action.summary = True
-
def get_title(self, session):
return "Binding"
def get_object_name(self, binding):
return "between %s and %s" % (binding.exchange.name,
binding.queue.name)
- class Remove(CuminAction):
- def get_title(self, session):
- return "Remove"
-
- def show(self, session, binding):
- raise Exception("XXX")
-
- frame = self.cumin_class.show_object(session, binding)
- frame = frame.exchange.show_object(session, binding)
- return frame.remove.show(session)
-
- def do_invoke(self, binding, args, completion):
- session = self.get_session_by_object(binding)
- session.exchange_unbind(queue=binding.queue.name,
- exchange=binding.exchange.name,
- binding_key=binding.bindingKey)
-
- completion("OK")
-
-
class CuminRoute(RemoteClass):
def __init__(self, model):
- super(CuminRoute, self).__init__(model, "route",
- Bridge, BridgeStats)
+ super(CuminRoute, self).__init__ \
+ (model, "route", Bridge, BridgeStats)
prop = CuminProperty(self, "key")
prop.title = "Route Key"
@@ -1448,27 +1282,12 @@
prop = CuminProperty(self, "dest")
prop.title = "Exchange"
- action = self.Remove(self, "remove")
- #action.summary = True
-
def get_title(self, session):
return "Route"
def get_object_name(self, route):
return route.src
- class Remove(CuminAction):
- def get_title(self, session):
- return "Remove"
-
- def show(self, session, peer):
- frame = self.cumin_class.show_object(session, peer)
- frame = frame.show_peer(session, peer)
- return frame.remove.show(session)
-
- def do_invoke(self, bridge, args, completion):
- bridge.close(self.mint.model, completion)
-
class CuminConnection(RemoteClass):
def __init__(self, model):
super(CuminConnection, self).__init__(model, "connection",
@@ -1511,10 +1330,9 @@
stat.unit = "frame"
stat.category = "io"
- action = self.Close(self, "close")
- action.summary = True
-
def init(self):
+ super(CuminConnection, self).init()
+
self.frame = self.model.frame.messaging.broker.connection
def get_title(self, session):
@@ -1526,28 +1344,6 @@
def get_object_name(self, conn):
return conn.address
- class Close(CuminAction):
- def show(self, session, conn):
- frame = self.cumin_class.show_object(session, conn)
- return frame.show_close(session)
-
- def get_title(self, session):
- return "Close"
-
- def do_invoke(self, conn, args, completion):
- session_ids = set()
-
- for broker in self.mint.model.mintBrokersByQmfBroker:
- session_ids.add(broker.getSessionId())
-
- for sess in conn.sessions:
- if sess.name in session_ids:
- raise Exception \
- ("Cannot close management connection %s" % \
- conn.address)
-
- conn.close(self.mint.model, completion)
-
class CuminSession(RemoteClass):
def __init__(self, model):
super(CuminSession, self).__init__(model, "session",
@@ -1575,8 +1371,6 @@
stat.title = "Attached"
stat.category = "general"
- self.Close(self, "close")
- self.Detach(self, "detach")
self.ResetLifespan(self, "resetLifespan")
self.SolicitAck(self, "solicitAck")
@@ -1656,13 +1450,9 @@
stat.unit = "byte"
stat.category = "io"
- action = self.Close(self, "close")
- action.summary = True
-
- action = self.Bridge(self, "bridge")
- action.summary = True
-
def init(self):
+ super(CuminLink, self).init()
+
self.frame = self.model.frame.messaging.broker.link
def get_title(self, session):
@@ -1671,43 +1461,6 @@
def get_object_name(self, link):
return "%s:%d" % (link.host, link.port)
- class Bridge(CuminAction):
- def show(self, session, link):
- frame = self.cumin_class.show_object(session, link)
- frame.set_object(session, link)
- return frame.show_bridge_add(session)
-
- def get_title(self, session):
- return "Add Route"
-
- def get_verb(self, session):
- return "Add Route"
-
- def do_invoke(self, link, args, completion):
- durable = args["durable"]
- src = args["exchange"]
- dest = args["exchange"] # see qpid-route
- key = args["key"]
- tag = args["tag"]
- dynamic = args["dynamic"]
- excludes = args["excludes"]
- sync = args["sync"]
-
- link.bridge(self.mint.model, completion,
- durable, src, dest, key,
- tag, excludes, False, False, dynamic, sync)
-
- class Close(CuminAction):
- def show(self, session, link):
- frame = self.cumin_class.show_object(session, link)
- return frame.remove.show(session)
-
- def get_title(self, session):
- return "Close"
-
- def do_invoke(self, link, args, completion):
- link.close(self.mint.model, completion)
-
class CuminBrokerStoreModule(RemoteClass):
def __init__(self, model):
super(CuminBrokerStoreModule, self).__init__ \
@@ -1852,6 +1605,8 @@
action = self.RemoveSet(self, "remove_set")
def init(self):
+ super(CuminManagementServer, self).init()
+
self.frame = self.model.frame.messaging.broker # XXX
def get_title(self, session):
@@ -1900,22 +1655,9 @@
super(CuminBrokerGroup, self).__init__ \
(model, "broker_group", BrokerGroup)
- action = self.Add(self, "add")
- action.title = "Add"
- action.navigable = False
-
- action = self.Edit(self, "edit")
- action.title = "Edit"
- action.summary = True
-
- action = self.Remove(self, "remove")
- action.title = "Remove"
- action.summary = True
-
- action = self.RemoveSet(self, "remove_set")
- action.title = "Remove"
-
def init(self):
+ super(CuminBrokerGroup, self).init()
+
self.frame = self.model.frame.messaging.broker_group
def get_title(self, session):
@@ -1924,64 +1666,6 @@
def get_icon_href(self, session):
return "resource?name=group-36.png"
- class Add(CuminAction):
- def show(self, session, object):
- frame = self.cumin_class.show_object(session, object)
- return frame.add.show(session)
-
- def do_invoke(self, object, args, completion):
- assert object is None
-
- try:
- object = self.cumin_class.mint_class(**args)
-
- completion("OK")
-
- return object
- except Exception, e:
- log.exception("Action failed")
- completion(e.message or "failed")
-
- class Edit(CuminAction):
- def show(self, session, object):
- frame = self.cumin_class.show_object(session, object)
- return frame.edit.show(session)
-
- def do_invoke(self, object, args, completion):
- try:
- object.set(**args)
- object.syncUpdate()
- completion("OK")
- except Exception, e:
- completion(e.message or "failed")
-
- class Remove(CuminAction):
- def show(self, session, object):
- frame = self.model.frame.messaging.broker_group
- frame.object.set(session, object)
- return frame.remove.show(session)
-
- def do_invoke(self, object, args, completion):
- try:
- object.destroySelf();
- object.syncUpdate()
- completion("OK")
- except Exception, e:
- completion(e.message or "failed")
-
- class RemoveSet(CuminSetAction):
- def show(self, session, groups):
- frame = self.model.frame.messaging.broker_groups_remove
- frame.objects.set(session, groups)
- return frame.show(session)
-
- def do_invoke(self, groups, args, completion):
- for group in groups:
- group.destroySelf()
- group.syncUpdate()
-
- completion("OK")
-
class Pool(object):
def __init__(self, collector):
assert collector
@@ -2019,6 +1703,8 @@
self.status.navigable = False
def init(self):
+ super(CuminPool, self).init()
+
self.frame = self.model.frame.grid.pool
def get_title(self, session):
@@ -2117,6 +1803,8 @@
action.title = "Set Limit"
def init(self):
+ super(CuminLimit, self).init()
+
self.frame = self.model.frame.grid.pool.limit
def get_title(self, session):
@@ -2179,6 +1867,8 @@
action.summary = True
def init(self):
+ super(CuminJobGroup, self).init()
+
self.frame = self.model.frame.grid.pool.job_group
def get_object_title(self, session, group):
@@ -2401,6 +2091,8 @@
action.navigable = False
def init(self):
+ super(CuminJob, self).init()
+
self.frame = self.model.frame.grid.pool.job
def get_title(self, session):
@@ -2627,6 +2319,8 @@
action.navigable = False
def init(self):
+ super(CuminScheduler, self).init()
+
self.frame = self.model.frame.grid.pool.scheduler
def get_title(self, session):
@@ -2671,6 +2365,8 @@
stat.title = "Held Jobs"
def init(self):
+ super(CuminSubmitter, self).init()
+
self.frame = self.model.frame.grid.pool.submitter
def get_title(self, session):
@@ -2727,6 +2423,8 @@
stat.title = "Total Slots"
def init(self):
+ super(CuminCollector, self).init()
+
self.frame = self.model.frame.grid.pool.collector
def get_title(self, session):
@@ -2805,6 +2503,8 @@
action.navigable = False
def init(self):
+ super(CuminNegotiator, self).init()
+
self.frame = self.model.frame.grid.pool.negotiator
def get_title(self, session):
@@ -2854,37 +2554,13 @@
self.lim["timeout"] = True
return self.lim
-class ModelPage(Page):
- def __init__(self, app, name):
- super(ModelPage, self).__init__(app, name)
+class CuminSubject(CuminClass):
+ def __init__(self, model):
+ super(CuminSubject, self).__init__(model, "subject", Subject)
- self.__class = CuminClassParameter(app, "class")
- self.add_parameter(self.__class)
+ def get_title(self, session):
+ return "Subject"
- param = IntegerParameter(app, "param")
- self.add_parameter(param)
-
- self.__ids = ListParameter(app, "id", param)
- self.add_parameter(self.__ids)
-
- def get_content_type(self, session):
- return Page.xml_content_type
-
- def do_render(self, session):
- writer = Writer()
- writer.write(Page.xml_1_0_declaration)
-
- cls = self.__class.get(session)
- objects = list()
-
- if cls:
- for id in self.__ids.get(session):
- objects.append(cls.mint_class.get(id))
-
- self.app.model.write_xml(session, writer, objects)
-
- return writer.to_string()
-
class CallPage(Page):
def __init__(self, app, name):
super(CallPage, self).__init__(app, name)
@@ -2927,3 +2603,185 @@
writer.write("<data>")
writer.write(data)
writer.write("</data>")
+
+class Task(object):
+ def __init__(self, app, cls):
+ self.app = app
+ self.cls = cls
+
+ self.form = None
+
+ self.aggregate = False
+
+ if self.cls:
+ if self.__class__ not in self.cls.tasks_by_class:
+ self.cls.add_task(self)
+
+ # make this take app? XXX
+ def init(self):
+ if self.form:
+ self.app.form_page.modes.add_mode(self.form)
+ else:
+ log.debug("Task %s has no form associated with it", self)
+
+ def get_title(self, session):
+ raise Exception("Not implemented")
+
+ def is_enabled(self, session, object):
+ return True
+
+ def get_description(self, session, object):
+ verb = self.get_title(session)
+
+ if object is None:
+ text = verb
+ else:
+ cls = self.cls.get_title(session)
+ obj = self.cls.get_object_name(object)
+ text = "%s %s '%s'" % (verb, cls, obj)
+
+ return text
+
+ def get_href(self, session, object):
+ return self.enter(session, object).marshal()
+
+ def enter(self, session, object):
+ nsession = wooly.Session(self.app.form_page)
+
+ self.form.return_url.set(nsession, session.marshal())
+ self.form.show(nsession)
+
+ self.do_enter(nsession, object)
+
+ return nsession
+
+ def do_enter(self, session, object):
+ pass
+
+ def exit_with_redirect(self, session, object):
+ osession = self.exit(session, object)
+ self.form.page.set_redirect_url(session, osession.marshal())
+
+ def exit(self, session, object):
+ url = self.form.return_url.get(session)
+ osession = wooly.Session.unmarshal(self.app, url)
+
+ self.do_exit(osession, object)
+
+ return osession
+
+ def do_exit(self, session, object):
+ pass
+
+ def invoke(self, session, object, *args, **kwargs):
+ invoc = self.start(session, object)
+
+ try:
+ result = self.do_invoke(session, object, *args, **kwargs)
+
+ self.end(invoc)
+ except Exception, e:
+ self.exception(invoc, e)
+
+ def do_invoke(self, *args, **kwargs):
+ raise Exception("Not implemented")
+
+ def start(self, session, object):
+ now = datetime.now()
+ subject = session.user_session.subject
+
+ invoc = TaskInvocation(self, subject, object)
+ invoc.status = invoc.PENDING
+ invoc.start_time = now
+ invoc.last_change_time = now
+
+ self.app.model.task_invocations.append(invoc)
+
+ return invoc
+
+ def end(self, invoc):
+ now = datetime.now()
+
+ invoc.status = invoc.OK
+ invoc.end_time = now
+ invoc.last_change_time = now
+
+ def exception(self, invoc, e):
+ now = datetime.now()
+
+ invoc.status = invoc.FAILED
+ invoc.end_time = now
+ invoc.last_change_time = now
+ invoc.exception = e
+
+ log.exception(e)
+
+ def __str__(self):
+ return "%s.%s" % (self.__module__, self.__class__.__name__)
+
+class SetTask(Task):
+ def __init__(self, app, cls):
+ super(SetTask, self).__init__(app, cls)
+
+ self.item_task = None
+ self.aggregate = True
+
+ def init(self):
+ super(SetTask, self).init()
+
+ if not self.item_task:
+ raise Exception("Task %s has no item task" % self)
+
+ def get_title(self, session):
+ return self.item_task.get_title(session)
+
+ def get_description(self, session, objects):
+ verb = self.item_task.get_title(session)
+ cls = self.cls.get_title(session)
+ count = len(objects)
+ return "%s %i %s" % (verb, count, conjugate(cls, count))
+
+ def invoke(self, session, objects, *args, **kwargs):
+ for object in objects:
+ self.item_task.invoke(session, object, *args, **kwargs)
+
+class QmfTask(Task):
+ def invoke(self, session, object, *args, **kwargs):
+ invoc = self.start(session, object)
+
+ def completion(status_code, output_args):
+ invoc.last_change_time = datetime.now()
+
+ if status_code == 0:
+ invoc.status = invoc.OK
+ else:
+ invoc.status = invoc.FAILED
+
+ invoc.status_code = status_code
+ invoc.output_args = output_args
+
+ try:
+ self.do_invoke(completion, session, object, *args, **kwargs)
+ except Exception, e:
+ self.exception(invoc, e)
+
+ def do_invoke(self, completion, session, object, *args, **kwargs):
+ raise Exception("Not implemented")
+
+class TaskInvocation(object):
+ PENDING = "pending"
+ FAILED = "failed"
+ OK = "ok"
+
+ def __init__(self, task, subject, object):
+ self.task = task
+ self.subject = subject
+ self.object = object
+ self.start_time = None
+ self.end_time = None
+ self.last_change_time = None
+ self.status = None
+ self.exception = None
+
+ self.status_code = None
+ self.output_args = None
Modified: mgmt/trunk/cumin/python/cumin/modelwidgets.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/modelwidgets.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/modelwidgets.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -1,8 +1,8 @@
from wooly import *
from wooly.forms import *
+from widgets import *
from model import *
-from widgets import *
from util import *
from wooly.widgets import Link
@@ -17,16 +17,14 @@
self.object = object
def process_submit(self, session, *args):
- branch = session.branch()
object = None
if self.object:
object = self.object.get(session)
- self.action.show(branch, object)
+ url = self.action.get_href(session, object)
+ self.page.set_redirect_url(session, url)
- self.page.set_redirect_url(session, branch.marshal())
-
def render_content(self, session, *args):
return self.action.get_title(session)
@@ -179,3 +177,36 @@
href = self.cumin_class.get_object_href_by_id(session, id)
return fmt_link(href, name)
+
+class TaskLink(Link):
+ def __init__(self, app, name, task, param):
+ super(TaskLink, self).__init__(app, name)
+
+ self.task = task
+ self.param = param
+
+ def get(self, session):
+ if self.param:
+ return self.param.get(session)
+
+ def render_href(self, session):
+ return self.task.get_href(session, self.get(session))
+
+ def render_content(self, session):
+ return self.task.get_title(session)
+
+class TaskButton(FormButton):
+ def __init__(self, app, name, task, set_param):
+ super(TaskButton, self).__init__(app, name)
+
+ self.task = task
+ self.set_param = set_param
+
+ def process_submit(self, session):
+ items = self.set_param.get(session)
+
+ href = self.task.get_href(session, items)
+ self.page.set_redirect_url(session, href)
+
+ def render_content(self, session):
+ return self.task.get_title(session)
Modified: mgmt/trunk/cumin/python/cumin/page.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/page.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/page.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -8,18 +8,11 @@
from widgets import *
from util import *
-from messaging.queue import TopQueueSet
-from grid.job import TopJobSet
-from inventory.system import TopSystemSet
+# XXX For the top-N sets; these should go away soon
+import messaging
+import grid
+import inventory
-from messaging import MessagingFrame, MessagingView
-from grid import GridFrame, GridView
-from inventory import InventoryFrame, InventoryView
-
-# We have a wooly.widgets.Link and a mint.Link; we want the former
-from wooly.widgets import Link
-from wooly import Session
-
strings = StringCatalog(__file__)
class MainPage(CuminPage, ModeSet):
@@ -30,9 +23,6 @@
self.add_mode(self.main)
self.set_default_frame(self.main)
- # for form in model actions:
- # seld.add_mode(form)
-
def render_title(self, session):
return "MRG Management"
@@ -43,15 +33,6 @@
self.home = HomeFrame(app, "home")
self.add_tab(self.home)
- self.messaging = MessagingFrame(app, "messaging")
- self.add_tab(self.messaging)
-
- self.grid = GridFrame(app, "grid")
- self.add_tab(self.grid)
-
- self.inventory = InventoryFrame(app, "inventory")
- self.add_tab(self.inventory)
-
class HomeFrame(CuminFrame):
def __init__(self, app, name):
super(HomeFrame, self).__init__(app, name)
@@ -79,9 +60,7 @@
self.add_tab(ManagementServerSet(app, "servers"))
def render_change_password_href(self, session):
- branch = session.branch()
- self.frame.change_password.show(branch)
- return branch.marshal()
+ return self.app.change_password.get_href(session, None)
class Heading(CuminHeading):
def render_title(self, session):
@@ -97,13 +76,13 @@
notice = self.ManagementServerNotice(app, "notice")
self.add_child(notice)
- queues = TopQueueSet(app, "queues")
+ queues = messaging.queue.TopQueueSet(app, "queues")
self.add_child(queues)
- jobs = TopJobSet(app, "jobs")
+ jobs = grid.job.TopJobSet(app, "jobs")
self.add_child(jobs)
- systems = TopSystemSet(app, "systems")
+ systems = inventory.system.TopSystemSet(app, "systems")
self.add_child(systems)
def render_title(self, session):
Modified: mgmt/trunk/cumin/python/cumin/parameters.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/parameters.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/parameters.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -1,6 +1,6 @@
from wooly import *
from mint import *
-import model
+import model
class CuminObjectParameter(Parameter):
def __init__(self, app, name, cumin_class):
@@ -19,6 +19,13 @@
def do_marshal(self, cls):
return cls.cumin_name
+class BindingParameter(Parameter):
+ def do_unmarshal(self, string):
+ return Binding.get(int(string))
+
+ def do_marshal(self, binding):
+ return str(binding.id)
+
class BrokerGroupParameter(Parameter):
def do_unmarshal(self, string):
if string == "__none__":
@@ -97,6 +104,16 @@
def get_id(self):
return self.id
+class LinkParameter(Parameter):
+ def do_unmarshal(self, string):
+ return Link.get(int(string))
+
+ def do_marshal(self, link):
+ return str(link.id)
+
+class PeerParameter(LinkParameter):
+ pass
+
class LimitParameter(Parameter):
def do_unmarshal(self, string):
return Limit(string)
@@ -104,13 +121,10 @@
def do_marshal(self, limit):
return limit.id
-class PeerParameter(Parameter):
- def do_unmarshal(self, string):
- return Link.get(int(string))
+# XXX marked for death
+class PeerParameter(LinkParameter):
+ pass
- def do_marshal(self, peer):
- return str(peer.id)
-
class PoolParameter(Parameter):
def do_unmarshal(self, string):
for coll in Collector.selectBy(Pool=string):
@@ -128,6 +142,13 @@
def do_marshal(self, queue):
return str(queue.id)
+class RouteParameter(Parameter):
+ def do_unmarshal(self, string):
+ return Bridge.get(int(string))
+
+ def do_marshal(self, route):
+ return str(route.id)
+
class SchedulerParameter(Parameter):
def do_unmarshal(self, string):
return Scheduler.get(int(string))
@@ -145,7 +166,7 @@
class SlotParameter(Parameter):
def do_unmarshal(self, string):
return Slot.get(int(string))
-
+
def do_marshal(self, slot):
return str(slot.id)
@@ -156,6 +177,13 @@
def do_marshal(self, sub):
return str(sub.id)
+class VhostParameter(Parameter):
+ def do_unmarshal(self, string):
+ return Vhost.get(int(string))
+
+ def do_marshal(self, vhost):
+ return str(vhost.id)
+
class CollectorParameter(Parameter):
def do_unmarshal(self, string):
return Collector.get(int(string))
Modified: mgmt/trunk/cumin/python/cumin/usergrid/main.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/usergrid/main.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/usergrid/main.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -1,14 +1,25 @@
from wooly import *
+from wooly.widgets import *
from cumin.widgets import *
from cumin.util import *
from submission import *
-from wooly.widgets import *
+from wooly.widgets import Link
strings = StringCatalog(__file__)
+class UserGridModule(object):
+ def init(self, app):
+ app.user_grid_page = MainPage(app, "usergrid.html")
+ app.add_page(app.user_grid_page)
+
+ app.form_page.submission_add = SubmissionForm(app, "submissionadd")
+ app.form_page.modes.add_mode(app.form_page.submission_add)
+
+module = UserGridModule()
+
class MainPage(CuminPage, ModeSet):
def __init__(self, app, name):
super(MainPage, self).__init__(app, name)
@@ -57,8 +68,12 @@
def render_content(self, session):
return "Create New Submission"
- def edit_session(self, session):
- self.page.submission_add.show(session)
+ def render_href(self, session):
+ form = self.app.form_page.submission_add
+ sess = Session(self.app.form_page)
+ form.show(sess)
+ form.return_url.set(session, session.marshal())
+ return sess.marshal()
class TemplateFrame(Widget):
def render_title(self, session):
Modified: mgmt/trunk/cumin/python/cumin/usergrid/submission.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/usergrid/submission.py 2009-06-17 19:44:31 UTC (rev
3456)
+++ mgmt/trunk/cumin/python/cumin/usergrid/submission.py 2009-06-17 20:20:11 UTC (rev
3457)
@@ -7,7 +7,7 @@
#strings = StringCatalog(__file__)
log = logging.getLogger("cumin.usergrid.submission")
-class SubmissionForm(CuminFieldForm):
+class SubmissionForm(FieldSubmitForm):
def __init__(self, app, name):
super(SubmissionForm, self).__init__(app, name)
@@ -98,3 +98,10 @@
class UseCloud(CheckboxFieldOption):
def render_title(self, session):
return "Use cloud"
+
+class SubmissionAdd(SubmissionForm):
+ def __init__(self, app, name):
+ super(SubmissionAdd, self).__init__(app, name)
+
+ def process_submit(self, session):
+ pass
Modified: mgmt/trunk/cumin/python/cumin/util.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/util.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/util.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -16,6 +16,16 @@
def ess(num, ending="s"):
return num != 1 and ending or ""
+def plural(noun):
+ # XXX handle exceptions here
+ return "%ss" % noun
+
+def conjugate(noun, count):
+ if count != 1:
+ noun = plural(noun)
+
+ return noun
+
def nvl(expr1, expr2):
if expr1 == None:
return expr2
@@ -44,7 +54,7 @@
def is_active(obj):
delTime = obj._get_qmfDeleteTime()
- if not delTime:
+ if not delTime and obj.statsCurr:
updateTime = obj.statsCurr.qmfUpdateTime
delta = timedelta(minutes=10)
# mirroring logic in widgets/PhaseSwitch.get_sql_constraint
Modified: mgmt/trunk/cumin/python/cumin/widgets.py
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.py 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/widgets.py 2009-06-17 20:20:11 UTC (rev 3457)
@@ -55,6 +55,9 @@
self.__frame_tmpl = Template(self, "frame_html")
+ self.tasks = TaskInvocationSet(app, "tasks")
+ self.add_child(self.tasks)
+
self.actions = ActionInvocationSet(app, "actions")
self.add_child(self.actions)
@@ -62,6 +65,7 @@
self.add_child(self.heartbeat)
def do_process(self, session, *args):
+ self.tasks.process(session)
self.actions.process(session)
self.heartbeat.process(session)
@@ -149,7 +153,7 @@
cls = self.app.model.get_class_by_object(obj)
if cls:
- return fmt_shorten(cls.get_object_title(session, obj), 16, 4)
+ return cls.get_object_title(session, obj)
class CuminView(Widget):
def __init__(self, app, name):
@@ -188,89 +192,93 @@
args = frame.get_args(session)
return frame.render_title(session, *args)
-class FormHelp(Widget):
+class BackgroundInclude(Widget):
def __init__(self, app, name):
- super(FormHelp, self).__init__(app, name)
+ super(BackgroundInclude, self).__init__(app, name)
-class CuminForm(Form):
- def __init__(self, app, name):
- super(CuminForm, self).__init__(app, name)
+ self.data = None
+ self.type = None
- self.__cancel = self.Cancel(app, "cancel")
- self.__cancel.set_tab_index(201)
- self.add_child(self.__cancel)
+ def render_data(self, session):
+ return self.data
- self.__submit = self.Submit(app, "submit")
- self.__submit.set_tab_index(200)
- self.add_child(self.__submit)
+ def render_type(self, session):
+ return self.type
- self.__help = self.Help(app, "help")
- self.add_child(self.__help)
+class CuminFormPage(HtmlPage):
+ def __init__(self, app, name):
+ super(CuminFormPage, self).__init__(app, name)
- def submit(self, session):
- self.__submit.set(session, True)
+ background = self.Background(app, "background")
+ background.type = "text/html"
+ self.add_child(background)
- def cancel(self, session):
- self.__cancel.set(session, True)
+ self.modes = ModeSet(app, "modes")
+ self.add_child(self.modes)
- def get_modal(self, session):
- return True
+ # XXX look into this
+ # for form in model tasks:
+ # self.add_mode(form)
- def do_process(self, session, *args):
- self.page.set_modal(session, self.get_modal(session))
+ class Background(BackgroundInclude):
+ def render_data(self, session):
+ form = self.parent.modes.mode.get(session)
+ url = form.return_url.get(session)
+ return url
- if self.__cancel.get(session):
- self.__cancel.set(session, False)
+class CuminTaskForm(SubmitForm, Frame):
+ def __init__(self, app, name, task):
+ super(CuminTaskForm, self).__init__(app, name)
- self.process_cancel(session, *args)
- elif self.__submit.get(session):
- self.__submit.set(session, False)
+ self.task = task
+ self.object = None
- self.process_submit(session, *args)
- else:
- self.process_display(session, *args)
+ def init(self):
+ super(CuminTaskForm, self).init()
- def process_cancel(self, session, *args):
- self.page.set_redirect_url(session, self.get_origin(session))
+ assert isinstance(self.object, Parameter)
- def process_submit(self, session, *args):
- pass
+ def process_submit(self, session):
+ object = self.object.get(session)
- def process_display(self, session, *args):
- pass
+ self.task.invoke(session, object)
+ self.task.exit_with_redirect(session, object)
- def render_cancel_content(self, session, *args):
- return "Cancel"
+ def render_submit_content(self, session):
+ return self.task.get_title(session)
- def render_submit_content(self, session, *args):
- return "Submit"
+ def render_title(self, session):
+ return "Confirm"
- def render_form_error(self, session, *args):
- pass
+ def render_content(self, session):
+ object = self.object.get(session)
+ return "%s?" % self.task.get_description(session, object)
- class Cancel(FormButton):
- def render_class(self, session, *args):
- return "cancel"
+class FormHelp(Widget):
+ def __init__(self, app, name):
+ super(FormHelp, self).__init__(app, name)
- def render_content(self, session, *args):
- cargs = self.parent.get_args(session)
- return self.parent.render_cancel_content(session, *cargs)
+class CuminForm(SubmitForm):
+ def __init__(self, app, name):
+ super(CuminForm, self).__init__(app, name)
- class Submit(FormButton):
- def render_class(self, session, *args):
- return "submit"
+ self.help = self.Help(app, "help")
+ self.add_child(self.help)
- def render_content(self, session, *args):
- cargs = self.parent.get_args(session)
- return self.parent.render_submit_content(session, *cargs)
+ def get_modal(self, session):
+ return True
+ def render_form_error(self, session, *args):
+ pass
+
class Help(FormHelp):
def render_help_href(self, session, *args):
return "resource?name=help.html#%s" % self.path
-class CuminFieldForm(CuminForm, FieldForm, Frame):
- def render_body(self, session, *args):
- return self.render_fields(session, *args)
+class CuminFieldForm(FieldSubmitForm, Frame):
+ def validate(self, session):
+ self.check(session)
+ return self.errors.get(session)
class CuminConfirmForm(CuminForm):
def __init__(self, app, name):
@@ -514,16 +522,32 @@
x.get_enabled(session, object))
for x in cls.actions if x.navigable and not x.aggregate]
+class CuminTasks(ActionSet):
+ def __init__(self, app, name, object):
+ super(CuminTasks, self).__init__(app, name)
+
+ self.object = object
+
+ def do_get_items(self, session):
+ if self.object:
+ object = self.object.get(session)
+ cls = self.app.model.get_class_by_object(object)
+
+ return [(x.get_href(session, object),
+ x.get_title(session, object),
+ True)
+ for x in cls.tasks if not x.aggregate]
+
class CuminDetails(Widget):
- def __init__(self, app, name):
+ # XXX make the object arg mandatory
+
+ def __init__(self, app, name, object=None):
super(CuminDetails, self).__init__(app, name)
- props = CuminProperties(app, "properties")
- self.add_child(props)
+ self.add_child(CuminProperties(app, "properties"))
+ self.add_child(CuminActions(app, "actions"))
+ self.add_child(CuminTasks(app, "tasks", object))
- actions = CuminActions(app, "actions")
- self.add_child(actions)
-
def render_title(self, session):
return "Details"
@@ -544,6 +568,9 @@
actions = self.SummaryActions(app, "actions")
self.add_child(actions)
+ tasks = self.SummaryTasks(app, "tasks")
+ self.add_child(tasks)
+
def get_args(self, session):
return self.frame.get_args(session)
@@ -571,6 +598,16 @@
return [(x.get_href(session, object), x.get_title(session),
x.get_enabled(session, object))
for x in cls.actions if x.summary and x.navigable]
+ class SummaryTasks(CuminActions):
+ def do_get_items(self, session, object):
+ cls = self.app.model.get_class_by_object(object)
+ if cls:
+ return [(x.get_href(session, object),
+ x.get_title(session),
+ x.is_enabled(session, object))
+ for x in cls.tasks
+ if not x.aggregate and x.form]
+
class StateSwitch(ItemSet):
def __init__(self, app, name):
super(StateSwitch, self).__init__(app, name)
@@ -747,7 +784,7 @@
class TruncatableTable(SqlTable):
def render_extra_class(self, session, *args):
""" if any columns are truncate, table needs a fixed layout
"""
- return True in [True for x in self.columns
+ return True in [True for x in self.columns
if isinstance(x, ClientTruncateColumn)] and " truncate"
or ""
class TopTable(TruncatableTable):
@@ -832,6 +869,24 @@
return constraints
+class CuminSelectionTable(CuminTableWithControls, Form):
+ def __init__(self, app, name, item_param):
+ super(CuminSelectionTable, self).__init__(app, name)
+
+ self.selection = ListParameter(app, "item", item_param)
+ self.add_parameter(self.selection)
+
+ self.checkboxes = CheckboxColumn(app, "id", self.selection)
+ self.add_column(self.checkboxes)
+
+ self.buttons = WidgetSet(app, "buttons")
+ self.buttons.html_class = "buttons"
+ self.add_child(self.buttons)
+
+ self.links = WidgetSet(app, "links")
+ self.links.html_class = "actions" # XXX fix this
+ self.add_child(self.links)
+
class NullSortColumn(SqlTableColumn):
def get_order_by_sql(self, session):
key = self.get_column_key(session)
@@ -893,90 +948,6 @@
def render_item_content(self, session, group):
return group.name
-class BindingSet(CuminTable):
- def __init__(self, app, name):
- super(BindingSet, self).__init__(app, name)
-
- self.ids = CheckboxIdColumn(app, "id")
- self.add_column(self.ids)
-
- col = self.QNameColumn(app, "q_id")
- col.visible = False
- self.add_column(col)
-
- col = self.ENameColumn(app, "e_id")
- col.visible = False
- self.add_column(col)
-
- col = self.KeyColumn(app, "key")
- self.add_column(col)
-
- col = self.RateColumn(app, "rate")
- col.alignment = "right"
- self.add_column(col)
-
- col = self.MatchedColumn(app, "matched")
- col.alignment = "right"
- self.add_column(col)
-
- self.phase = PhaseSwitch(app, "phase")
- self.add_child(self.phase)
-
- def get_args(self, session):
- return self.frame.get_args(session)
-
- def get_sql_values(self, session, obj):
- return {"id": obj.id}
-
- class QNameColumn(SqlTableColumn):
- def render_title(self, session, data):
- return "Queue"
-
- def render_content(self, session, data):
- queue = Queue.get(data["q_id"])
- href = self.page.main.messaging.broker.queue.get_href \
- (session, queue)
- return fmt_link(href, fmt_shorten(queue.name))
-
- class ENameColumn(SqlTableColumn):
- def render_title(self, session, data):
- return "Exchange"
-
- def render_content(self, session, data):
- exchange = Exchange.get(data["e_id"])
- href = self.page.main.messaging.broker.exchange.get_href \
- (session, exchange)
-
- if exchange.name:
- name = fmt_shorten(exchange.name)
- else:
- name = "<em>Default</em>"
-
- return fmt_link(href, name)
-
- class KeyColumn(SqlTableColumn):
- def render_title(self, session, data):
- return "Key"
-
- def render_value(self, session, value):
- return fmt_shorten(value)
-
- class RateColumn(ItemTableColumn):
- def render_title(self, session, data):
- return "Message Rate"
-
- def render_content(self, session, data):
- binding = Binding.get(data["id"])
- return self.app.model.binding.msgMatched.rate_html(binding)
-
- class MatchedColumn(ItemTableColumn):
- def render_title(self, session, data):
- return "Messages Matched"
-
- def render_content(self, session, data):
- binding = Binding.get(data["id"])
- return self.app.model.binding.msgMatched.value(binding)
-
class CheckboxInputColumn(FormInput, ItemTableColumn):
def __init__(self, app, name, item_param):
super(CheckboxInputColumn, self).__init__(app, name, None)
@@ -996,6 +967,25 @@
return html % (name, id, attr, click)
+class CheckboxColumn(FormInput, SqlTableColumn):
+ def __init__(self, app, name, param):
+ super(CheckboxColumn, self).__init__(app, name, param)
+
+ self.header_class = CheckboxColumnHeader
+
+ def do_render(self, session, data, disabled=False):
+ name = self.param.path
+ id = data[self.get_column_key(session)]
+ attr = id in self.param.get(session) and
"checked=\"checked\"" or ""
+ disa = disabled and "disabled=\"disabled\"" or ""
+ click = self.parent.update_enabled and \
+ "onclick=\"cumin.clickTableCheckbox(this,
'%s')\"" % name or ""
+
+ html = """<td><input type="checkbox"
name="%s" value="%s" %s/></td>"""
+ attrs = " ".join((attr, disa, click))
+
+ return html % (name, str(id), attrs)
+
class CheckboxIdColumn(FormInput, SqlTableColumn):
def __init__(self, app, name):
super(CheckboxIdColumn, self).__init__(app, name, None)
@@ -1034,13 +1024,17 @@
self.param = ListParameter(app, "id", item)
self.add_parameter(self.param)
-class CheckboxIdColumnHeader(ItemTableColumnHeader):
+class CheckboxColumnHeader(ItemTableColumnHeader):
def render_form_id(self, session, *args):
return self.column.form.path
def render_elem_name(self, session, *args):
return self.column.param.path
+ # XXX remove this
+class CheckboxIdColumnHeader(CheckboxColumnHeader):
+ pass
+
class FilteredCheckboxIdColumn(CheckboxIdColumn):
def __init__(self, app, name, form, callback=None):
super(FilteredCheckboxIdColumn, self).__init__(app, name)
@@ -1053,6 +1047,18 @@
return super(FilteredCheckboxIdColumn, self).do_render(session, data,
disabled=disabled)
+class FilteredCheckboxColumn(CheckboxColumn):
+ def __init__(self, app, name, param, callback):
+ super(FilteredCheckboxColumn, self).__init__(app, name, param)
+
+ # call back that returns True if the checkbox is to be disabled
+ self.__callback = callback
+
+ def do_render(self, session, data):
+ disabled = self.__callback and self.__callback(session, data) or False
+ return super(FilteredCheckboxColumn, self).do_render \
+ (session, data, disabled=disabled)
+
class NameField(StringField):
def __init__(self, app, name):
super(NameField, self).__init__(app, name)
@@ -1067,6 +1073,23 @@
def set_required(self, required):
self.required = required
+ def check(self, session):
+ name = self.get(session)
+
+ if name == "" and self.required:
+ self.form.errors.add(session, MissingValueError())
+ else:
+ for char in self.illegal_chars:
+ if char in name:
+ msg = "The name contains illegal characters"
+
+ if self.legal_chars_desc:
+ msg = msg + "; " + self.legal_chars_desc
+
+ self.form.errors.add(session, FormError(msg))
+
+ break
+
def do_validate(self, session, errors):
name = self.get(session)
@@ -1116,6 +1139,25 @@
def set_object_attr(self, attr):
self.__object = attr
+ def check(self, session):
+ super(UniqueNameField, self).check(session)
+
+ name = self.get(session)
+
+ if name:
+ args = {self.__field: name, }
+ results = self.__class.selectBy(**args)
+
+ if self.__object:
+ object = self.__object.get(session)
+
+ if object:
+ results = results.filter(self.__class.q.id != object.id)
+
+ if results.count() > 0:
+ self.form.errors.add(session, DuplicateValueError())
+
+ # XXX get rid of this
def do_validate(self, session, errors):
super(UniqueNameField, self).do_validate(session, errors)
@@ -1269,7 +1311,7 @@
def elem_id(self, session):
return self.render_id(session)
-class MoreFieldSet(FieldForm, FormField):
+class MoreFieldSet(FormFieldSet, FormField):
""" Displays a button that opens and closes a set of fields
Used in a FieldForm as a FormField. Instead of calling
@@ -1316,3 +1358,32 @@
class Wait(Widget):
pass
+class TaskInvocationSet(ItemSet):
+ def __init__(self, app, name):
+ super(TaskInvocationSet, self).__init__(app, name)
+
+ self.html_class = TaskInvocationSet.__name__
+ self.update_enabled = True
+
+ def do_get_items(self, session):
+ now = secs(datetime.now())
+
+ invocs = sorted_by(self.app.model.task_invocations,
"last_change_time")
+ invocs = [x for x in invocs if now - secs(x.last_change_time) < 10]
+
+ return invocs
+
+ def do_render(self, session):
+ items = self.get_items(session)
+
+ if items:
+ return super(TaskInvocationSet, self).do_render(session)
+
+ def render_item_content(self, session, item):
+ description = item.task.get_description(session, item.object)
+ status = item.status
+ exc = str(item.exception)
+ code = str(item.status_code)
+ outs = str(item.output_args)
+
+ return " | ".join((description, status, exc, code, outs))
Modified: mgmt/trunk/cumin/python/cumin/widgets.strings
===================================================================
--- mgmt/trunk/cumin/python/cumin/widgets.strings 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/python/cumin/widgets.strings 2009-06-17 20:20:11 UTC (rev 3457)
@@ -1,24 +1,7 @@
-[BindingSet.sql]
-select
- b.id,
- b.exchange_id as e_id,
- b.queue_id as q_id,
- b.binding_key as key
-from binding as b
-left outer join binding_stats as c on c.id = b.stats_curr_id
-{sql_where}
-{sql_orderby}
-{sql_limit}
-
-[BindingSet.count_sql]
-select count(*)
-from binding as b
-left outer join binding_stats as c on c.id = b.stats_curr_id
-{sql_where}
-
[CuminMainView.css]
#head {
padding: 0;
+ margin: 0;
min-height: 2.75em;
background: #f9f9ff url("resource?name=shade.png") repeat-x scroll bottom
center;
}
@@ -30,6 +13,7 @@
#tabs {
padding: 0 0 0 2em;
+ margin: 0;
position: relative;
top: 1.175em;
}
@@ -79,6 +63,7 @@
z-index: 1;
min-height: 20em;
}
+
#messages {
-moz-border-radius: 0.35em;
border: 1px solid #886;
@@ -174,10 +159,14 @@
</div>
<div id="body">
-<div id="messages" style="display: {action_display};"><p
title="close"
onclick="cumin.hideActions()">x</p>{actions}</div>
+ {tasks}
+
+ <div id="messages" style="display: {action_display};"><p
title="close"
onclick="cumin.hideActions()">x</p>{actions}</div>
+
{heartbeat}
-{content}</div>
+ {content}
+</div>
<div id="foot"/>
@@ -387,6 +376,8 @@
<td>
<h2>Actions</h2>
{actions}
+ <h2>Tasks</h2>
+ {tasks}
</td>
</tr>
</tbody>
@@ -410,7 +401,7 @@
[CuminSummary.css]
div.CuminSummary {
- width: 36em;
+ width: 50em;
margin: 0 0 2em 0;
min-height: 6em;
}
@@ -434,7 +425,7 @@
div.CuminSummary div.actions {
font-size: 0.9em;
- width: 16em;
+ width: 20em;
float: right;
}
@@ -453,6 +444,7 @@
<div class="actions">
{actions}
+ {tasks}
</div>
<div class="properties">
@@ -596,11 +588,29 @@
<th {class_attr}>{content}</th>
[CuminTable.css]
-table.mobjects th.setnav {
- font-size: 0.9em;
+div.CuminTable th.setnav {
+ font-size: 0.9em;
}
-table.mobjects td {
+div.CuminTable ul.switches,
+div.CuminTable ul.filters,
+div.CuminTable ul.buttons {
+ list-style: none;
+ display: inline;
+ padding: 0;
+ margin: 0;
+}
+
+div.CuminTable ul.filters {
+ float: right;
+}
+
+div.CuminTable ul.buttons li {
+ margin: 0 0.4em 0 0;
+ display: inline;
+}
+
+table.CuminTable td {
text-overflow:ellipsis;
}
@@ -615,13 +625,13 @@
}
[CuminTable.javascript]
- wooly.addPageUpdateListener( cumin.restoreTableCheckboxes );
+wooly.addPageUpdateListener(cumin.restoreTableCheckboxes);
[CuminTable.html]
-<table id="{id}" class="mobjects{extra_class}">
+<table id="{id}" class="CuminTable mobjects {extra_class}">
<thead>
<tr>
- <th class="setnav">
+ <th class="setnav" colspan="{column_count}">
<div class="rfloat">{page}</div>
{count}
</th>
@@ -632,11 +642,11 @@
</table>
[CuminTableWithControls.html]
-<div class="CuminTable">
+<div id="{id}" class="CuminTable {extra_class}">
+ {filters}
+
{switches}
- {filters}
-
<table class="mobjects">
<thead>
<tr>
@@ -654,6 +664,40 @@
</table>
</div>
+[CuminSelectionTable.html]
+<div id="{id}" class="CuminTable {extra_class}">
+ {links}
+
+ {filters}
+
+ {switches}
+
+ <form method="post" action="?">
+ <div class="sactions">
+ <h2>Act on selection:</h2>
+ {buttons}
+ </div>
+
+ <table class="mobjects">
+ <thead>
+ <tr>
+ <th class="setnav" colspan="{column_count}">
+ <div class="rfloat">{page}</div>
+
+ {count}
+ </th>
+ </tr>
+
+ <tr>{headers}</tr>
+ </thead>
+
+ <tbody>{items}</tbody>
+ </table>
+
+ <div>{hidden_inputs}</div>
+ </form>
+</div>
+
[TableHeader.css]
th.selected a {
color: black;
@@ -667,12 +711,15 @@
[TableHeader.item_html]
<th class="{item_class}"><a
href="{item_href}">{item_content}</a></th>
-[CheckboxIdColumnHeader.css]
+[CheckboxColumn.html]
+<td><input type="checkbox" name="{name}"
+
+[CheckboxColumnHeader.css]
th.chk_box {
width: 2em;
}
-[CheckboxIdColumnHeader.javascript]
+[CheckboxColumnHeader.javascript]
function checkAll(control_id, form_id, elem_name) {
control = document.getElementById(control_id)
form = document.getElementById(form_id);
@@ -687,7 +734,7 @@
}
}
-[CheckboxIdColumnHeader.html]
+[CheckboxColumnHeader.html]
<th class="chk_box"><input id="{id}"
type="checkbox" name="all"
onclick="cumin.clickTableCheckbox(this, 'all'); checkAll('{id}',
'{form_id}', '{elem_name}')" value="all"/></th>
@@ -698,6 +745,36 @@
<input type="text" name="{arg_name}"
value="{arg_value}" /> messages
</div>
+[BackgroundInclude.css]
+object.BackgroundInclude {
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ position: absolute;
+ top: 0;
+ z-index: -1;
+}
+
+[BackgroundInclude.html]
+<object class="BackgroundInclude" data="{data}"
type="{type}"/>
+
+[CuminFormPage.css]
+body {
+ background-color: #000;
+ z-index: 0;
+}
+
+body > object.BackgroundInclude {
+ opacity: 0.2;
+}
+
+body > form {
+ z-index: 1;
+ width: 48em;
+ margin: 6em auto;
+ background-color: #fff;
+}
+
[FormHelp.javascript]
function help_window(href) {
var left = screen.availWidth / 2;
@@ -743,49 +820,57 @@
[MoreFieldSet.html]
-<div class="more_field_set">
- <ul class="actions">
- <li>
- <a class="nav" href="#"
onclick="toggle_more_fieldset(); return false;"><span
id="button_{id}">{state_text}</span></a>
- </li>
- </ul>{open}
- <div id="{id}" class="more_inputs"
style="display:{open_display};">
- {inputs}
- </div>
-</div><!-- end of "more_field_set" -->
-<script type="text/javascript">
- function toggle_more_fieldset() {
- var oDiv = document.getElementById("{id}");
- var oButton = document.getElementById("button_{id}");
- var oState = document.forms[0].elements["{open_path}"];
+<tr>
+ <th>
+ <div class="title">{title}</div>
+ <div class="help">{help}</div>
+ </th>
+ <td>
+ <div class="more_field_set">
+ <ul class="actions">
+ <li>
+ <a class="nav" href="#"
onclick="toggle_more_fieldset(); return false;"><span
id="button_{id}">{state_text}</span></a>
+ </li>
+ </ul>{open}
+ <div id="{id}" class="more_inputs"
style="display:{open_display};">
+ {inputs}
+ </div>
+ </div><!-- end of "more_field_set" -->
+ <script type="text/javascript">
+ function toggle_more_fieldset() {
+ var oDiv = document.getElementById("{id}");
+ var oButton = document.getElementById("button_{id}");
+ var oState = document.forms[0].elements["{open_path}"];
- if (oDiv) {
- if (oDiv.style.display == "none") {
- oDiv.style.display = "block";
+ if (oDiv) {
+ if (oDiv.style.display == "none") {
+ oDiv.style.display = "block";
- if (oButton) {
- oButton.innerHTML = "{less_text}";
- }
+ if (oButton) {
+ oButton.innerHTML = "{less_text}";
+ }
- if (oState) {
- oState.value = "t";
- }
- } else {
- oDiv.style.display = "none";
+ if (oState) {
+ oState.value = "t";
+ }
+ } else {
+ oDiv.style.display = "none";
- if (oButton) {
- oButton.innerHTML = "{more_text}";
- }
+ if (oButton) {
+ oButton.innerHTML = "{more_text}";
+ }
- if (oState) {
- oState.value = "f";
+ if (oState) {
+ oState.value = "f";
+ }
+
+ document.forms[0].submit();
}
-
- document.forms[0].submit();
}
}
- }
-</script>
+ </script>
+ </td>
+</tr>
[StartStopStatus.css]
div.status_time {
@@ -831,3 +916,12 @@
[Wait.html]
<div class="loading"
style="visibility:visible;"><span>Loading...</span></div>
+[TaskInvocationSet.css]
+ul.TaskInvocationSet {
+ background-color: #fe0;
+ padding: 1em 2em;
+ -moz-border-radius: 0.5em;
+ -webkit-border-radius: 0.5em;
+ margin: 0.5em auto 1em auto;
+ width: 80%;
+}
Modified: mgmt/trunk/cumin/resources/app.css
===================================================================
--- mgmt/trunk/cumin/resources/app.css 2009-06-17 19:44:31 UTC (rev 3456)
+++ mgmt/trunk/cumin/resources/app.css 2009-06-17 20:20:11 UTC (rev 3457)
@@ -6,16 +6,6 @@
background-color: #f7f7f7;
}
-ul {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-
-ul > ul {
- padding: 1em;
-}
-
h2 {
margin: 0;
}
@@ -52,9 +42,11 @@
ul.actions li {
display: inline;
}
+
ul.actions.disabled a {
color: #666666;
}
+
ul.actions.disabled li a.nav:before {
color: #666666;
}
@@ -62,6 +54,7 @@
ul.actions.disabled a:hover {
background-color: #f7f7f7;
}
+
a.nav:before {
content: "\00BB \0020";
font-weight: bold;
@@ -114,6 +107,7 @@
color: #bbb;
border: 1px solid #ddd;
}
+
button.disabled:hover {
background-color: #f7f7f7;
}
@@ -355,6 +349,12 @@
content: "";
}
+ul.slist {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
ul.slist a:before {
content: url(resource?name=radio-button.png);
vertical-align: -10%;