summaryrefslogtreecommitdiff
path: root/qpid/dotnet/client-010/management/console
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/dotnet/client-010/management/console')
-rw-r--r--qpid/dotnet/client-010/management/console/AbstractConsole.cs45
-rw-r--r--qpid/dotnet/client-010/management/console/Agent.cs75
-rw-r--r--qpid/dotnet/client-010/management/console/Broker.cs351
-rw-r--r--qpid/dotnet/client-010/management/console/BrokerURL.cs71
-rw-r--r--qpid/dotnet/client-010/management/console/ClassKey.cs107
-rw-r--r--qpid/dotnet/client-010/management/console/Console.cs46
-rw-r--r--qpid/dotnet/client-010/management/console/MethodResult.cs67
-rw-r--r--qpid/dotnet/client-010/management/console/ObjectID.cs88
-rw-r--r--qpid/dotnet/client-010/management/console/QMFEvent.cs74
-rw-r--r--qpid/dotnet/client-010/management/console/QMFObject.cs294
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaArgument.cs59
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaClass.cs141
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaMethod.cs66
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaProperty.cs59
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaStatistic.cs54
-rw-r--r--qpid/dotnet/client-010/management/console/SchemaVariable.cs84
-rw-r--r--qpid/dotnet/client-010/management/console/SequenceManager.cs62
-rw-r--r--qpid/dotnet/client-010/management/console/Session.cs796
-rw-r--r--qpid/dotnet/client-010/management/console/Util.cs150
-rw-r--r--qpid/dotnet/client-010/management/console/XMLUtil.cs127
-rw-r--r--qpid/dotnet/client-010/management/console/console.csproj101
-rw-r--r--qpid/dotnet/client-010/management/console/console.sln46
-rw-r--r--qpid/dotnet/client-010/management/console/default.build54
23 files changed, 3017 insertions, 0 deletions
diff --git a/qpid/dotnet/client-010/management/console/AbstractConsole.cs b/qpid/dotnet/client-010/management/console/AbstractConsole.cs
new file mode 100644
index 0000000000..315b2b6d48
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/AbstractConsole.cs
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+ public class AbstractConsole : Console
+ {
+ public AbstractConsole(){}
+ public virtual void NewAgent(Agent agent) {}
+ public virtual void AgentRemoved(Agent agent) {}
+ public virtual void BrokerConnected(Broker broker) {}
+ public virtual void BrokerDisconnected(Broker broker) {}
+ public virtual void BrokerInformation(Broker broker) {}
+ public virtual void NewPackage(String packageName) {}
+ public virtual void NewClass(short kind, ClassKey key) {}
+ public virtual void ObjectProperties(Broker broker, QMFObject obj) {}
+ public virtual void ObjectStatistics(Broker broker, QMFObject obj) {}
+ public virtual void MethodResponse(Broker broker, long seq, MethodResult response) {}
+ public virtual void EventRecieved(Broker broker, QMFEvent anEvent) {}
+ public virtual void HearbeatRecieved(Agent agent, long timestamp) {}
+ public virtual Type TypeMapping(ClassKey key) {
+ return typeof(QMFObject) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Agent.cs b/qpid/dotnet/client-010/management/console/Agent.cs
new file mode 100644
index 0000000000..df544a4dd0
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Agent.cs
@@ -0,0 +1,75 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Local representation of a remote agent which has been found on the bus.
+ */
+ public class Agent
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Agent)) ;
+
+ public Broker Broker {get;set;}
+ public long BrokerBank {get;set;}
+ public long AgentBank {get;set;}
+ public string label {get;set;}
+
+ public Agent(Broker broker, long agentBank, string label)
+ {
+ this.Broker = broker ;
+ this.BrokerBank = broker.BrokerBank() ;
+ this.AgentBank = agentBank ;
+ this.label = label ;
+ }
+
+ public string AgentKey() {
+ return Agent.AgentKey(AgentBank, BrokerBank) ;
+ }
+
+ public string RoutingCode() {
+ return Agent.RoutingCode(AgentBank, BrokerBank) ;
+ }
+
+ public static string AgentKey(long AgentBank, long BrokerBank) {
+ return String.Format("{0}:{1}", AgentBank, BrokerBank) ;
+ }
+
+ public static string RoutingCode(long AgentBank, long BrokerBank) {
+ return String.Format("agent.{0}.{1}", BrokerBank, AgentBank) ;
+ }
+
+ public static long GetBrokerBank(string routingKey) {
+ string delim = "." ;
+ return long.Parse(routingKey.Split(delim.ToCharArray())[2]) ;
+ }
+
+ public static long GetAgentBank(string routingKey) {
+ string delim = "." ;
+ return long.Parse(routingKey.Split(delim.ToCharArray())[3]) ;
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Broker.cs b/qpid/dotnet/client-010/management/console/Broker.cs
new file mode 100644
index 0000000000..7684da9e12
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Broker.cs
@@ -0,0 +1,351 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using System.Threading ;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport ;
+using org.apache.qpid.transport.codec ;
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Controls all communication with a broker. Works with the session to provide
+ * synhchronous method calls across the asynchronous QMF bus.
+ */
+ public class Broker : IMessageListener
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Broker)) ;
+ public static int SYNC_TIME = 60000 ;
+
+ public BrokerURL url ;
+ public Dictionary<string, Agent> Agents = new Dictionary<string, Agent>() ;
+
+ private IClient client ;
+ private IClientSession clientSession ;
+ //FIXME This second session should not be needed. There is a bug in the underlieing code.
+ private IClientSession outSession ;
+ private int timeout = 50000 ;
+ private string replyName ;
+ private string topicName ;
+ private bool connected = false ;
+ private bool syncInFlight = false ;
+ private bool topicBound = false ;
+ private int reqsOutstanding = 0 ;
+ private org.apache.qpid.console.Session consoleSession ;
+ private object lockObject = new Object() ;
+
+
+ public Broker(org.apache.qpid.console.Session session, BrokerURL url)
+ {
+ log.Debug("Creating a new Broker for url " + url) ;
+ this.url = url;
+ consoleSession = session ;
+ this.TryToConnect() ;
+ }
+
+ ~Broker() {
+ if (connected) {
+ this.Shutdown() ;
+ }
+ }
+
+ public int BrokerBank() {
+ return 1 ;
+ }
+
+ public bool IsConnected() {
+ return connected ;
+ }
+
+ protected void TryToConnect() {
+ reqsOutstanding = 1 ;
+ Agent newAgent = new Agent(this,0,"BrokerAgent") ;
+ Agents.Add(newAgent.AgentKey(), newAgent) ;
+ client = new Client() ;
+ client.Connect(url.Hostname, url.Port, null, url.AuthName, url.AuthPassword) ;
+ clientSession = client.CreateSession(timeout) ;
+ //clientSession.SetAutoSync(false) ;
+ string name = System.Text.Encoding.UTF8.GetString(clientSession.GetName()) ;
+ replyName = "reply-" + name ;
+ topicName = "topic-" + name ;
+ clientSession.SetAutoSync(true) ;
+ Option[] options = new Option[] {Option.EXCLUSIVE, Option.AUTO_DELETE} ;
+
+ // This queue is used for responses to messages which are sent.
+ clientSession.QueueDeclare(replyName,options) ;
+ clientSession.ExchangeBind(replyName,"amq.direct",replyName) ;
+ clientSession.AttachMessageListener(this, "rdest") ;
+ clientSession.MessageSubscribe(replyName,"rdest",MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0,null) ;
+ clientSession.MessageSetFlowMode("rdest", MessageFlowMode.WINDOW);
+ clientSession.MessageFlow("rdest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ clientSession.MessageFlow("rdest", MessageCreditUnit.MESSAGE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+
+ // This queue is used for unsolicited messages sent to this class.
+ clientSession.QueueDeclare(topicName, options) ;
+ clientSession.AttachMessageListener(this, "tdest") ;
+ clientSession.MessageSubscribe(topicName,"tdest",MessageAcceptMode.NONE,MessageAcquireMode.PRE_ACQUIRED,null,0,null) ;
+ clientSession.MessageSetFlowMode("tdest", MessageFlowMode.WINDOW);
+ clientSession.MessageFlow("tdest", MessageCreditUnit.BYTE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+ clientSession.MessageFlow("tdest", MessageCreditUnit.MESSAGE, ClientSession.MESSAGE_FLOW_MAX_BYTES);
+
+ outSession = client.CreateSession(timeout) ;
+ outSession.ExchangeBind(replyName,"amq.direct",replyName) ;
+
+ connected = true ;
+ consoleSession.HandleBrokerConnect(this) ;
+
+
+ IEncoder encoder = CreateEncoder() ;
+ this.SetHeader(encoder, 'B', 0) ;
+ this.Send(encoder) ;
+ }
+
+ public void Shutdown() {
+ if (connected) {
+ this.WaitForStable() ;
+ clientSession.MessageStop("rdest") ;
+ clientSession.MessageStop("tdest") ;
+ clientSession.Close() ;
+ client.Close() ;
+ this.connected = false ;
+ }
+ }
+
+ public void UpdateAgent(QMFObject obj) {
+ long agentBank = (long)obj.GetProperty("agentBank") ;
+ long brokerBank = (long)obj.GetProperty("brokerBank") ;
+ String key = Agent.AgentKey(agentBank, brokerBank) ;
+ if (obj.IsDeleted()) {
+ if (Agents.ContainsKey(key)) {
+ Agent agent = Agents[key] ;
+ Agents.Remove(key) ;
+ consoleSession.HandleAgentRemoved(agent) ;
+ }
+ }
+ else {
+ if (! Agents.ContainsKey(key)) {
+ Agent newAgent = new Agent(this, agentBank, (string)obj.GetProperty("label")) ;
+ Agents.Add(key, newAgent) ;
+ consoleSession.HandleNewAgent(newAgent) ;
+ }
+ }
+ }
+
+ public IEncoder CreateEncoder() {
+ return new MSEncoder(1000) ;
+ }
+
+
+ public IEncoder CreateEncoder(char opcode, long sequence) {
+ return SetHeader(this.CreateEncoder(), opcode, sequence) ;
+ }
+
+ public IEncoder SetHeader(IEncoder enc, char opcode, long sequence) {
+ enc.WriteUint8((short)'A') ;
+ enc.WriteUint8((short)'M') ;
+ enc.WriteUint8((short)'2') ;
+ enc.WriteUint8((short)opcode) ;
+ enc.WriteUint32(sequence) ;
+ return enc ;
+ }
+
+ public Message CreateMessage(IEncoder enc) {
+ return this.CreateMessage(enc, "broker", -1) ;
+ }
+
+ public Message CreateMessage(IEncoder enc, string routingKey) {
+ return this.CreateMessage(enc, routingKey, -1) ;
+ }
+
+ public Message CreateMessage(IEncoder enc, string routingKey, long ttl) {
+ Message msg = new Message() ;
+ msg.Body = ((MSEncoder)enc).Segment() ;
+ msg.DeliveryProperties.SetRoutingKey(routingKey) ;
+ if (-1 != ttl) {
+ msg.DeliveryProperties.SetTtl(ttl) ;
+ }
+ msg.MessageProperties.SetContentType("x-application/qmf") ;
+ msg.MessageProperties.SetReplyTo(new ReplyTo("amq.direct", replyName)) ;
+ return msg ;
+ }
+
+ public void Send(IEncoder enc) {
+ this.Send(this.CreateMessage(enc)) ;
+ }
+
+ public void Send(Message msg) {
+
+ lock (lockObject) {
+ log.Debug(String.Format("Sending message to routing key '{0}'", msg.DeliveryProperties.GetRoutingKey())) ;
+ //log.Debug(System.Text.Encoding.UTF8.GetString(msg.Body.ToArray())) ;
+ outSession.MessageTransfer("qpid.management", msg) ;
+ //clientSession.sync() ;
+ }
+ }
+
+ protected bool CheckHeader(IDecoder decoder, out char opcode, out long sequence) {
+ bool returnValue = false ;
+ opcode = 'x' ;
+ sequence = -1 ;
+ if(decoder.HasRemaining()) {
+ char character = (char) decoder.ReadUint8() ;
+ if (character != 'A') {
+ return returnValue ;
+ }
+ character = (char) decoder.ReadUint8() ;
+ if (character != 'M') {
+ return returnValue ;
+ }
+ character = (char) decoder.ReadUint8() ;
+ if (character != '2') {
+ return returnValue ;
+ }
+ returnValue = true ;
+ opcode = (char) decoder.ReadUint8() ;
+ sequence = decoder.ReadUint32() ;
+ }
+ return returnValue ;
+ }
+
+ public void MessageTransfer(IMessage msg) {
+ MSDecoder decoder = new MSDecoder() ;
+ decoder.Init(msg.Body) ;
+ RangeSet rangeSet = new RangeSet() ;
+ rangeSet.Add(msg.Id) ;
+ char opcode = 'x' ;
+ long seq = -1 ;
+ while (this.CheckHeader(decoder, out opcode, out seq)) {
+ //log.Debug("Message recieved with opcode " + opcode + " and sequence " + seq) ;
+ //log.Debug(System.Text.Encoding.UTF8.GetString(msg.Body.ToArray())) ;
+ switch (opcode) {
+ case 'b':
+ consoleSession.HandleBrokerResponse(this, decoder, seq) ;
+ break ;
+ case 'p':
+ consoleSession.HandlePackageIndicator(this, decoder, seq) ;
+ break ;
+ case 'z':
+ consoleSession.HandleCommandComplete(this, decoder, seq) ;
+ break ;
+ case 'q':
+ consoleSession.HandleClassIndicator(this, decoder, seq) ;
+ break ;
+ case 'm':
+ consoleSession.HandleMethodResponse(this, decoder, seq) ;
+ break ;
+ case 'h':
+ consoleSession.HandleHeartbeatIndicator(this, decoder, seq, msg) ;
+ break ;
+ case 'e':
+ consoleSession.HandleEventIndicator(this, decoder, seq) ;
+ break ;
+ case 's':
+ consoleSession.HandleSchemaResponse(this, decoder, seq) ;
+ break ;
+ case 'c':
+ consoleSession.HandleContentIndicator(this, decoder, seq, true, false) ;
+ break ;
+ case 'i':
+ consoleSession.HandleContentIndicator(this, decoder, seq, false, true) ;
+ break ;
+ case 'g':
+ consoleSession.HandleContentIndicator(this, decoder, seq, true, true) ;
+ break ;
+ default:
+ log.Error("Invalid message type recieved with opcode " + opcode) ;
+ break ;
+ }
+ }
+ lock (lockObject) {
+ outSession.MessageAccept(rangeSet) ;
+ }
+ }
+
+ public void IncrementOutstanding() {
+ lock (lockObject) {
+ this.reqsOutstanding += 1 ;
+ }
+ }
+
+ public void DecrementOutstanding() {
+ lock (lockObject) {
+ this.reqsOutstanding -= 1 ;
+ if ((reqsOutstanding == 0) & !topicBound) {
+ foreach (string key in consoleSession.BindingKeys()) {
+ //this.clientSession.ExchangeBind(topicName, "qpid.mannagement", key) ;
+ log.Debug("Setting Topic Binding " + key) ;
+ this.outSession.ExchangeBind(topicName, "qpid.management", key) ;
+ }
+ topicBound = true ;
+ }
+ if ((reqsOutstanding == 0) & syncInFlight) {
+ syncInFlight = false ;
+ Monitor.PulseAll(lockObject) ;
+ }
+ }
+ }
+
+ public void WaitForStable() {
+ lock (lockObject) {
+ if (connected) {
+ DateTime start = DateTime.Now ;
+ syncInFlight = true ;
+ while (reqsOutstanding != 0) {
+ log.Debug("Waiting to recieve messages") ;
+ Monitor.Wait(lockObject,SYNC_TIME) ;
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > SYNC_TIME) {
+ throw new Exception("Timeout waiting for Broker to Sync") ;
+ }
+ }
+ }
+ }
+ }
+
+ public void SetSyncInFlight(bool inFlight) {
+ lock(lockObject) {
+ syncInFlight = inFlight ;
+ Monitor.PulseAll(lockObject) ;
+ }
+ }
+
+ public bool GetSyncInFlight() {
+ return syncInFlight ;
+ }
+
+ public void WaitForSync(int timeout) {
+ lock(lockObject) {
+ DateTime start = DateTime.Now ;
+ while (syncInFlight) {
+ Monitor.Wait(lockObject,timeout) ;
+ }
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > timeout) {
+ throw new Exception("Timeout waiting for Broker to Sync") ;
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/BrokerURL.cs b/qpid/dotnet/client-010/management/console/BrokerURL.cs
new file mode 100644
index 0000000000..77318e4295
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/BrokerURL.cs
@@ -0,0 +1,71 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * URL which defines the connection to the broker to hook up to the QMF
+ * Bus.
+ */
+ public class BrokerURL
+ {
+ public string Hostname {get;set;}
+ public int Port {get;set;}
+ public string AuthName {get;set;}
+ public string AuthPassword {get;set;}
+ public string AuthMechanism {get;set;}
+ protected bool ssl = false ;
+
+ public BrokerURL(string str)
+ {
+ Uri uri = new Uri(str) ;
+ this.Hostname = uri.Host ;
+ if (uri.Scheme.Equals("amqp")) {
+ Port=5672 ;
+ } else {
+ ssl = true ;
+ Port=5673 ;
+ }
+
+ //FIXME Make this more robust
+ this.AuthName = "guest" ;
+ this.AuthPassword = "guest" ;
+ this.AuthMechanism = "PLAIN" ;
+ }
+
+ public string GetURI() {
+ return Hostname ;
+ }
+
+ public override string ToString ()
+ {
+ if (ssl) {
+ return String.Format("amqps://{0}:{1}", Hostname, Port) ;
+ } else {
+ return String.Format("amqp://{0}:{1}", Hostname, Port) ;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/ClassKey.cs b/qpid/dotnet/client-010/management/console/ClassKey.cs
new file mode 100644
index 0000000000..a3aba2761a
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/ClassKey.cs
@@ -0,0 +1,107 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Globalization ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Identifies a specific class and version on the bus.
+ */
+ public class ClassKey
+ {
+ public string PackageName { get; set; }
+ public string ClassName { get; set; }
+ public long[] Hash = new long[4] ;
+
+ public ClassKey(String keyString) {
+ string delims = ":()" ;
+ string[] parts = keyString.Split(delims.ToCharArray()) ;
+ if (parts.Length < 3) {
+ throw new Exception("Invalid class key format. Format should be package:class(bytes)") ;
+ }
+ PackageName = parts[0] ;
+ ClassName = parts[1] ;
+ delims = "-" ;
+ string[] bytes = parts[2].Split(delims.ToCharArray()) ;
+ if (bytes.Length != 4) {
+ throw new Exception("Invalid class key format. Bytes should be in the format HEX-HEX-HEX-HEX") ;
+ }
+ Hash[0] = long.Parse(bytes[0], NumberStyles.HexNumber) ;
+ Hash[1] = long.Parse(bytes[1], NumberStyles.HexNumber) ;
+ Hash[2] = long.Parse(bytes[2], NumberStyles.HexNumber) ;
+ Hash[3] = long.Parse(bytes[3], NumberStyles.HexNumber) ;
+ }
+
+ public ClassKey(IDecoder dec) {
+ PackageName = dec.ReadStr8() ;
+ ClassName = dec.ReadStr8() ;
+ Hash[0] = dec.ReadUint32() ;
+ Hash[1] = dec.ReadUint32() ;
+ Hash[2] = dec.ReadUint32() ;
+ Hash[3] = dec.ReadUint32() ;
+
+ }
+
+ public string GetKeyString() {
+ string hashString = GetHashString() ;
+ return String.Format("{0}:{1}({2})", PackageName, ClassName, hashString) ;
+ }
+
+ public string GetHashString() {
+ return String.Format("{0:x8}-{1:x8}-{2:x8}-{3:x8}", (long) Hash[0],Hash[1], Hash[2],Hash[3]) ;
+ }
+
+ public void encode(IEncoder enc) {
+ enc.WriteStr8(PackageName) ;
+ enc.WriteStr8(ClassName) ;
+ enc.WriteUint32(Hash[0]) ;
+ enc.WriteUint32(Hash[1]) ;
+ enc.WriteUint32(Hash[2]) ;
+ enc.WriteUint32(Hash[3]) ;
+ }
+
+ override public string ToString() {
+ return String.Format("ClassKey: {0}", GetKeyString()) ;
+ }
+
+ public override int GetHashCode ()
+ {
+ return GetKeyString().GetHashCode() ;
+ }
+
+ public override bool Equals (object obj)
+ {
+ if (obj.GetType().Equals(this.GetType())) {
+ ClassKey other = (ClassKey) obj ;
+ return (other.GetKeyString().Equals(this.GetKeyString())) ;
+ }
+ else {
+ return false ;
+ }
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Console.cs b/qpid/dotnet/client-010/management/console/Console.cs
new file mode 100644
index 0000000000..8ff201c676
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Console.cs
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+
+namespace org.apache.qpid.console
+{
+ /**
+ * Callbacks which are exposed by the Session. Clients should create anm implementaiton of this
+ * for more fine grained interaction with the bus.
+ */
+ public interface Console
+ {
+ void NewAgent(Agent agent) ;
+ void AgentRemoved(Agent agent) ;
+ void BrokerConnected(Broker broker) ;
+ void BrokerDisconnected(Broker broker) ;
+ void BrokerInformation(Broker broker) ;
+ void NewPackage(String packageName) ;
+ void NewClass(short kind, ClassKey key) ;
+ void ObjectProperties(Broker broker, QMFObject obj) ;
+ void ObjectStatistics(Broker broker, QMFObject obj) ;
+ void MethodResponse(Broker broker, long seq, MethodResult response) ;
+ void EventRecieved(Broker broker, QMFEvent anEvent) ;
+ void HearbeatRecieved(Agent agent, long timestamp) ;
+ Type TypeMapping(ClassKey key) ;
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/MethodResult.cs b/qpid/dotnet/client-010/management/console/MethodResult.cs
new file mode 100644
index 0000000000..7215f5dcbc
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/MethodResult.cs
@@ -0,0 +1,67 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+
+namespace org.apache.qpid.console
+{
+ /**
+ * The result on invoking a method on a managed object
+ */
+ public class MethodResult
+ {
+
+ public long ReturnCode {get;set;}
+ public string Text {get;set;}
+ protected Dictionary<string, object> ReturnValues ;
+
+ public MethodResult(long aCode, string aMsg, Dictionary<string, object> args)
+ {
+ ReturnCode = aCode ;
+ Text = aMsg ;
+ ReturnValues = args ;
+ }
+
+ public object GetReturnValue(string name) {
+ object returnValue = null ;
+ if (ReturnValues.ContainsKey(name)) {
+ returnValue = ReturnValues[name] ;
+ }
+ return returnValue ;
+ }
+
+ public Dictionary<string, object> GetReturnValues() {
+ return ReturnValues ;
+ }
+
+ public override string ToString()
+ {
+ string returnString = "" ;
+ foreach (KeyValuePair<string, object> pair in ReturnValues) {
+ returnString = returnString + String.Format("(Key: '{0}' Value: '{1}')", pair.Key, pair.Value) ;
+ }
+
+ return string.Format("MethodResult: ReturnCode={0}, Text={1} Values=[{2}]", ReturnCode, Text, returnString);
+ }
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/ObjectID.cs b/qpid/dotnet/client-010/management/console/ObjectID.cs
new file mode 100644
index 0000000000..9532c8e64c
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/ObjectID.cs
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Uniquely identifies an object on the bus.
+ */
+ public class ObjectID
+ {
+
+ protected long first ;
+ protected long second ;
+
+ public ObjectID() {
+ }
+
+ public ObjectID(IDecoder dec)
+ {
+ first = (long)dec.ReadUint64() ;
+ second = (long)dec.ReadUint64() ;
+ }
+
+ public ObjectID(long first, long second) {
+ this.first = first ;
+ this.second = second ;
+ }
+
+ public long Flags() {
+ return (long) ((ulong)this.first & 0xF000000000000000) >> 60 ;
+ }
+
+ public long Sequence() {
+ return (long)((ulong)this.first & 0x0FFF000000000000) >> 48 ;
+ }
+
+ public long BrokerBank() {
+ return (long)((ulong)this.first & 0x0000FFFFF0000000) >> 28 ;
+ }
+
+ public long AgentBank() {
+ return (this.first & 0x000000000FFFFFFF) ;
+ }
+
+ public long Object() {
+ return second ;
+ }
+
+ public bool IsDurable() {
+ return Sequence() == 0 ;
+ }
+
+ public void encode(IEncoder enc) {
+ enc.WriteUint64((long)first) ;
+ enc.WriteUint64((long)second) ;
+ }
+
+ override public string ToString() {
+ return "" + Flags() + "-" + Sequence() + "-" + BrokerBank() + "-" + AgentBank() + "-" + Object() ;
+ }
+
+ public string RoutingCode() {
+ return Agent.RoutingCode((long)AgentBank(), (long)BrokerBank()) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/QMFEvent.cs b/qpid/dotnet/client-010/management/console/QMFEvent.cs
new file mode 100644
index 0000000000..73e1a34c43
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/QMFEvent.cs
@@ -0,0 +1,74 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.transport.codec ;
+
+
+namespace org.apache.qpid.console
+{
+ public enum EventSeverity : short {
+ EMER = 0 ,
+ ALERT = 1 ,
+ CRIT = 2 ,
+ ERROR = 3 ,
+ WARN = 4 ,
+ NOTIC = 5 ,
+ INFO = 6 ,
+ DEBUG = 7
+ }
+
+ /**
+ * An event raised by an agent on the bus.
+ */
+ public class QMFEvent
+ {
+ public Session Session { get;set; }
+ public ClassKey ClassKey {get;set;}
+ //FIXME time?
+ public long Timestamp {get;set;}
+ public EventSeverity Severity {get;set;}
+ public Dictionary<string, object> Arguments {get;set;}
+
+ public QMFEvent(Session session, IDecoder dec)
+ {
+ Session = session ;
+ ClassKey = new ClassKey(dec) ;
+ Timestamp = dec.ReadInt64() ;
+ Severity = (EventSeverity) dec.ReadUint8() ;
+ SchemaClass sClass = Session.GetSchema(ClassKey) ;
+ Arguments = new Dictionary<string, object>() ;
+
+ if (sClass != null) {
+ foreach (SchemaArgument arg in sClass.Arguments) {
+ Arguments[arg.Name] = Session.DecodeValue(dec, arg.Type) ;
+ }
+ }
+ }
+
+ public object GetArgument(string argName) {
+ object returnValue = null ;
+ Arguments.TryGetValue(argName, out returnValue) ;
+ return returnValue ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/QMFObject.cs b/qpid/dotnet/client-010/management/console/QMFObject.cs
new file mode 100644
index 0000000000..905422efd9
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/QMFObject.cs
@@ -0,0 +1,294 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using log4net ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * An object which is returned from an agent by the Session. It can have
+ * methods, properties, and statistics.
+ */
+ public class QMFObject
+ {
+
+ public static ILog log = LogManager.GetLogger(typeof(QMFObject)) ;
+
+ public Session Session {get;set;}
+ protected SchemaClass _Schema ;
+ virtual public SchemaClass Schema {get {return _Schema;} set {_Schema=value;}}
+ bool Managed ;
+ public DateTime CurrentTime {get;set;}
+ public DateTime CreateTime {get;set;}
+ public DateTime DeleteTime {get;set;}
+ public ObjectID ObjectID {get;set;}
+ public Dictionary<string, object> Properties = new Dictionary<string, object>() ;
+ public Dictionary<string, object> Statistics = new Dictionary<string, object>() ;
+
+
+ // This constructor is the "naked" constructor which creates
+ // an object without a session or a schema. It is used by
+ // subclasses which are auto generated
+ public QMFObject() {
+ }
+
+ public QMFObject(QMFObject source) {
+ this.Session = source.Session ;
+ this.Schema = source.Schema ;
+ this.Managed = source.Managed ;
+ this.CurrentTime = source.CurrentTime ;
+ this.CreateTime = source.CreateTime ;
+ this.DeleteTime = source.DeleteTime ;
+ this.ObjectID = source.ObjectID ;
+ this.Properties = source.Properties ;
+ this.Statistics = source.Statistics ;
+ }
+
+ // This constructor is used by a session make object call to
+ // create a blank object from a schema.
+ public QMFObject(Session session, SchemaClass schema, bool hasProperties, bool hasStats , bool isManaged) {
+ Session = session ;
+ Schema = schema ;
+ Managed = isManaged ;
+
+ if (hasProperties) {
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ object propValue = null ;
+ if (!prop.Optional) {
+ propValue = Util.DefaultValue(prop.Type) ;
+ }
+ this.SetProperty(prop.Name, propValue) ;
+ }
+ }
+
+ if (hasStats) {
+ foreach (SchemaStatistic stat in Schema.Statistics) {
+ SetStatistic(stat.Name, Util.DefaultValue(stat.Type)) ;
+ }
+ }
+ }
+
+ // This constructor is used by the session to create an object based on a data
+ // stream by the agent.
+ public QMFObject(Session session, SchemaClass schema, IDecoder dec, bool hasProperties, bool hasStats , bool isManaged)
+ {
+ Session = session ;
+ Schema = schema ;
+ Managed = isManaged ;
+
+ if (Managed) {
+ // FIXME DateTime or Uint64??
+ CurrentTime = new DateTime(dec.ReadDatetime()) ;
+ CreateTime = new DateTime(dec.ReadDatetime()) ;
+ DeleteTime = new DateTime(dec.ReadDatetime()) ;
+ ObjectID = new ObjectID(dec) ;
+ }
+
+ if (hasProperties) {
+ List<string> excluded = ProcessPresenceMasks(dec, Schema) ;
+
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (excluded.Contains(prop.Name)) {
+ log.Debug(String.Format("Setting Property Default {0}", prop.Name)) ;
+ safeAddProperty(prop.Name, null) ;
+ } else {
+ //log.Debug(String.Format("Setting Property {0}", prop.Name)) ;
+ safeAddProperty(prop.Name, session.DecodeValue(dec, prop.Type)) ;
+ }
+ }
+ }
+
+ if (hasStats) {
+ foreach (SchemaStatistic stat in Schema.GetAllStatistics()) {
+ //log.Debug(String.Format("Setting Statistic {0}", stat.Name)) ;
+ Statistics.Add(stat.Name, session.DecodeValue(dec, stat.Type)) ;
+ }
+ }
+
+ }
+
+ protected List<string> ProcessPresenceMasks(IDecoder dec, SchemaClass schema) {
+ List<string> excludes = new List<string> () ;
+ short bit = 0 ;
+ short mask = 0 ;
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (prop.Optional) {
+ //log.Debug(String.Format("Property named {0} is optional", prop.Name)) ;
+ if (bit == 0) {
+ mask=dec.ReadUint8() ;
+ bit = 1 ;
+ }
+
+ if ((mask & bit) == 0) {
+ //log.Debug(String.Format("Property named {0} is not present", prop.Name)) ;
+ excludes.Add(prop.Name) ;
+ }
+ bit *= 2 ;
+ if (bit == 256) {
+ bit = 0 ;
+ }
+ }
+ }
+ return excludes ;
+ }
+
+ protected List<SchemaMethod> getMethods() {
+ return Schema.GetAllMethods() ;
+ }
+
+ public object GetProperty(string attributeName) {
+ //FIXME any object refs?
+ object returnValue = null ;
+ Properties.TryGetValue(attributeName, out returnValue) ;
+ return returnValue ;
+ }
+
+ protected void SetStatistic(string attributeName, object newValue) {
+ Statistics.Remove(attributeName) ;
+ Statistics.Add(attributeName, newValue) ;
+ }
+
+ public void SetProperty(string attributeName, object newValue) {
+ Properties.Remove(attributeName) ;
+ Properties.Add(attributeName, newValue) ;
+ }
+
+ public bool IsDeleted() {
+ return !DeleteTime.Equals(new DateTime(0)) ;
+ }
+
+ public string RoutingKey() {
+ return ObjectID.RoutingCode() ;
+ }
+
+ public long AgentBank() {
+ return ObjectID.AgentBank() ;
+ }
+
+ public long BrokerBank() {
+ return ObjectID.BrokerBank() ;
+ }
+
+ override public string ToString() {
+ string propertyString = "" ;
+ foreach (KeyValuePair<string, object> pair in Properties) {
+ propertyString = propertyString + String.Format("(Name: '{0}' Value: '{1}')", pair.Key, pair.Value) ;
+ }
+
+ string statsString = "" ;
+ foreach (KeyValuePair<string, object> sPair in Statistics) {
+ statsString = statsString + String.Format("(Name: '{0}' Value: '{1}')", sPair.Key, sPair.Value) ;
+ }
+ if (Managed) {
+ return String.Format("Managed QMFObject {0}:{1}({2}) Properties: [{3}] Statistics: [{4}])", Schema.PackageName, Schema.ClassName, ObjectID, propertyString, statsString) ;
+ } else {
+ return String.Format("QMFObject {0}:{1} Properties: [{2}] Statistics: [{3}]", Schema.PackageName, Schema.ClassName, propertyString, statsString) ;
+ }
+ }
+
+ public MethodResult InvokeMethod(string name, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), true, Broker.SYNC_TIME ) ;
+ }
+
+ public MethodResult InvokeMethod(string name, int timeToLive, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), true, timeToLive) ;
+ }
+
+ public MethodResult InvokeMethod(string name, bool synchronous, int timeToLive, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), synchronous, timeToLive ) ;
+ }
+
+ public MethodResult InvokeMethod(string name, bool synchronous, params object[] args) {
+ return this.InternalInvokeMethod(name, new List<object>(args), synchronous, Broker.SYNC_TIME) ;
+ }
+
+ protected MethodResult InternalInvokeMethod(string name, List<object> args, bool synchronous, int timeToLive) {
+ if (!Managed) {
+ throw new Exception ("Object is not Managed") ;
+ }
+ if (Schema.GetMethod(name) == null) {
+ throw new Exception (String.Format("Method named '{0}' does not exist", name)) ;
+ }
+ return Session.InvokeMethod(this, name, args, synchronous, timeToLive) ;
+ }
+
+ public void Encode (IEncoder enc) {
+ int mask = 0 ;
+ int bit = 0 ;
+ List<SchemaProperty> propsToEncode = new List<SchemaProperty>() ;
+ log.Debug(String.Format("Encoding class {0}:{1}", Schema.PackageName, Schema.ClassName)) ;
+
+ enc.WriteUint8(20) ;
+ Schema.Key.encode(enc) ;
+
+ foreach (SchemaProperty prop in Schema.GetAllProperties()) {
+ if (prop.Optional) {
+ if (bit == 0) {
+ bit =1 ;
+ }
+ if ((Properties.ContainsKey(prop.Name)) && (Properties[prop.Name] != null)) {
+ mask |= bit ;
+ propsToEncode.Add(prop) ;
+ } else {
+ }
+ bit = bit << 1 ;
+ if (bit == 256) {
+ bit = 0 ;
+ enc.WriteUint8((short)mask) ;
+ mask = 0 ;
+ }
+ } else {
+ propsToEncode.Add(prop) ;
+ }
+ }
+ if (bit != 0) {
+ enc.WriteUint8((short)mask) ;
+ }
+
+ foreach (SchemaProperty prop in propsToEncode) {
+ object obj = Properties[prop.Name] ;
+ //log.Debug(String.Format("Encoding property {0}", prop.Name)) ;
+ Session.EncodeValue(enc, prop.Type, obj) ;
+ }
+ foreach (SchemaStatistic stat in Schema.Statistics) {
+ object obj = Statistics[stat.Name] ;
+ Session.EncodeValue(enc, stat.Type, obj) ;
+ }
+ log.Debug("Done") ;
+
+ }
+
+
+ protected void safeAddProperty(string propName, object value) {
+ if (Properties.ContainsKey(propName)) {
+ Properties[propName] = value ;
+ } else {
+ Properties.Add(propName, value) ;
+ }
+ }
+
+
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaArgument.cs b/qpid/dotnet/client-010/management/console/SchemaArgument.cs
new file mode 100644
index 0000000000..d3ee508b31
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaArgument.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a method parameter to a QMF Object
+ */
+ public class SchemaArgument : SchemaVariable
+ {
+
+ public string Direction {get;set;}
+
+ public SchemaArgument(IDecoder dec, bool methodArg)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ base.PopulateData(map) ;
+
+ if (map.ContainsKey("dir")) {
+ Direction = (string) map["dir"] ;
+ }
+ }
+
+ public bool IsInput() {
+ return Direction.Equals("I") | Direction.Equals("IO") ;
+ }
+
+ public bool IsOutput() {
+ return Direction.Equals("O") | Direction.Equals("IO") ;
+ }
+
+ public bool IsBidirectional() {
+ return Direction.Equals("IO") ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaClass.cs b/qpid/dotnet/client-010/management/console/SchemaClass.cs
new file mode 100644
index 0000000000..320312b61d
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaClass.cs
@@ -0,0 +1,141 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.codec ;
+
+using log4net ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a class to a QMF Object
+ */
+ public class SchemaClass
+ {
+ public static int CLASS_KIND_TABLE = 1 ;
+ public static int CLASS_KIND_EVENT = 2 ;
+
+ public static ILog log = LogManager.GetLogger(typeof(SchemaClass)) ;
+
+
+ public ClassKey Key {get;set;}
+ public ClassKey SuperType {get;set;}
+ public int Kind {get;set;}
+ public List<SchemaMethod> Methods = new List<SchemaMethod>() ;
+ public List<SchemaArgument> Arguments = new List<SchemaArgument>() ;
+ public List<SchemaProperty> Properties = new List<SchemaProperty>() ;
+ public List<SchemaStatistic> Statistics = new List<SchemaStatistic>() ;
+
+ public string ClassName { get { return Key.ClassName;}}
+ public string PackageName { get { return Key.PackageName;}}
+ public string ClassKeyString { get { return Key.GetKeyString();}}
+
+ protected Session Session {get;set;}
+
+ public SchemaClass(int kind, ClassKey key, IDecoder dec, Session session)
+ {
+ log.Debug(String.Format("New schema class {0}", key)) ;
+ Kind = kind ;
+ Session = session ;
+ this.Key = key ;
+ bool hasSupertype = false ;
+
+ if (kind == CLASS_KIND_TABLE) {
+ int propCount = dec.ReadUint16() ;
+ int statCount = dec.ReadUint16() ;
+ int methodCount = dec.ReadUint16() ;
+
+ if (hasSupertype) {
+ SuperType = new ClassKey(dec) ;
+ }
+
+ for(int x = 0 ; x < propCount ; x++) {
+ Properties.Add(new SchemaProperty(dec)) ;
+ }
+ for(int x = 0 ; x < statCount ; x++) {
+ Statistics.Add(new SchemaStatistic(dec)) ;
+ }
+ for(int x = 0 ; x < methodCount ; x++) {
+ Methods.Add(new SchemaMethod(dec)) ;
+ }
+ }
+
+ if (kind == CLASS_KIND_EVENT) {
+ int argCount = dec.ReadUint16() ;
+ if (hasSupertype) {
+ SuperType = new ClassKey(dec) ;
+ }
+ for(int x = 0 ; x < argCount ; x++) {
+ Arguments.Add(new SchemaArgument(dec, false)) ;
+ }
+ }
+ }
+
+ public SchemaMethod GetMethod(string name) {
+ SchemaMethod returnValue = null ;
+ foreach(SchemaMethod method in Methods) {
+ if (method.Name.Equals(name)) {
+ returnValue = method ;
+ break ;
+ }
+ }
+ return returnValue ;
+ }
+
+ public List<SchemaProperty> GetAllProperties() {
+ if (SuperType == null) {
+ return Properties ;
+ } else {
+ List<SchemaProperty> allProperties = new List<SchemaProperty>(Properties) ;
+ allProperties.AddRange(Session.GetSchema(SuperType).GetAllProperties()) ;
+ return allProperties ;
+ }
+ }
+
+ public List<SchemaStatistic> GetAllStatistics() {
+ if (SuperType == null) {
+ return Statistics ;
+ } else {
+ List<SchemaStatistic> allStats = new List<SchemaStatistic>(Statistics) ;
+ allStats.AddRange(Session.GetSchema(SuperType).GetAllStatistics()) ;
+ return allStats ;
+ }
+ }
+
+ public List<SchemaMethod> GetAllMethods() {
+ if (SuperType == null) {
+ return Methods ;
+ } else {
+ List<SchemaMethod> allMethods = new List<SchemaMethod>(Methods) ;
+ allMethods.AddRange(Session.GetSchema(SuperType).GetAllMethods()) ;
+ return allMethods ;
+ }
+ }
+
+ public bool HasSuperType() {
+ return SuperType != null ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaMethod.cs b/qpid/dotnet/client-010/management/console/SchemaMethod.cs
new file mode 100644
index 0000000000..0a843262a4
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaMethod.cs
@@ -0,0 +1,66 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of a method to a QMF Object
+ */
+ public class SchemaMethod
+ {
+ public string Name {get;set;}
+ public int ArgCount {get;set;}
+ public int InputArgCount {get;set;}
+ public int OutputArgCount {get;set;}
+ public int BidirectionalArgCount {get;set;}
+ public string Description {get;set;}
+ public List<SchemaArgument> Arguments = new List<SchemaArgument>();
+
+ public SchemaMethod(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ Name = (string) map["name"] ;
+ ArgCount = (int) map["argCount"] ;
+ if (map.ContainsKey("desc")) {
+ Description = (string) map["desc"] ;
+ }
+ for (int x = 0 ; x < ArgCount ; x++) {
+ SchemaArgument arg = new SchemaArgument(dec, true) ;
+ Arguments.Add(arg) ;
+ if (arg.IsInput()) {
+ InputArgCount += 1 ;
+ }
+ if (arg.IsOutput()) {
+ OutputArgCount += 1 ;
+ }
+ if (arg.IsBidirectional()) {
+ BidirectionalArgCount += 1 ;
+ }
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaProperty.cs b/qpid/dotnet/client-010/management/console/SchemaProperty.cs
new file mode 100644
index 0000000000..50d3c62f8d
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaProperty.cs
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of an object property to a QMF Object
+ */
+ public class SchemaProperty : SchemaVariable
+ {
+ public int Access {get;set;}
+ public bool Index {get;set;}
+ public bool Optional {get;set;}
+
+ public SchemaProperty(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ base.PopulateData(map) ;
+ Name = (string) map["name"] ;
+
+ if (map.ContainsKey("optional")) {
+ //System.Console.WriteLine("optional") ;
+ Optional = (int)map["optional"] != 0 ;
+ }
+ if (map.ContainsKey("index")) {
+ //System.Console.WriteLine("index") ;
+ Index = (int)map["index"] != 0 ;
+ }
+ if (map.ContainsKey("access")) {
+ //System.Console.WriteLine("access") ;
+ Access = (int) map["access"] ;
+ }
+
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaStatistic.cs b/qpid/dotnet/client-010/management/console/SchemaStatistic.cs
new file mode 100644
index 0000000000..ff96b98388
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaStatistic.cs
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata that describes the mapping of an object Statistic
+ */
+ public class SchemaStatistic
+ {
+
+ public string Name {get;set;}
+ public short Type {get;set;}
+ public string Description {get;set;}
+ public string Unit {get;set;}
+
+ public SchemaStatistic(IDecoder dec)
+ {
+ Dictionary<string, Object> map = dec.ReadMap() ;
+ Name = (string) map["name"] ;
+ Type = (short) short.Parse(""+map["type"]) ;
+
+ if (map.ContainsKey("unit")) {
+ Unit = (string) map["unit"] ;
+ }
+ if (map.ContainsKey("description")) {
+ Description = (string) map["description"] ;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SchemaVariable.cs b/qpid/dotnet/client-010/management/console/SchemaVariable.cs
new file mode 100644
index 0000000000..50455ab38a
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SchemaVariable.cs
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic ;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Metadata for mapping properties, arguments, and statistics
+ */
+ public abstract class SchemaVariable
+ {
+ public string Name {get;set;}
+ public short Type {get;set;}
+ public string Description {get;set;}
+ public string Unit {get;set;}
+ public int? Min {get;set;}
+ public int? Max {get;set;}
+ public int? MaxLength {get;set;}
+ public string Default {get;set;}
+ public string RefPackage {get;set;}
+ public string RefClass {get;set;}
+
+ public SchemaVariable() {
+ }
+
+ protected void PopulateData(Dictionary<string, Object> map)
+ {
+
+ if (map.ContainsKey("name")) {
+ Name = (string) map["name"] ;
+ }
+ if (map.ContainsKey("type")) {
+ Type = short.Parse((""+ map["type"])) ;
+ }
+
+ if (map.ContainsKey("unit")) {
+ Unit = (string) map["unit"] ;
+ }
+ if (map.ContainsKey("min")) {
+ Min = (int) map["min"] ;
+ }
+ if (map.ContainsKey("max")) {
+ Max = (int) map["max"] ;
+ }
+ if (map.ContainsKey("maxlen")) {
+ MaxLength = (int) map["maxlen"] ;
+ }
+ if (map.ContainsKey("description")) {
+ Description = (string) map["description"] ;
+ }
+ if (map.ContainsKey("refClass")) {
+ RefClass = (string) map["refClass"] ;
+ }
+ if (map.ContainsKey("refPackage")) {
+ RefPackage = (string) map["refPackage"] ;
+ }
+ if (map.ContainsKey("Default")) {
+ Default = (string) map["default"] ;
+ }
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/SequenceManager.cs b/qpid/dotnet/client-010/management/console/SequenceManager.cs
new file mode 100644
index 0000000000..29f1ba26b0
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/SequenceManager.cs
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Threading ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Holds state during asynchronous calls to the broker.
+ */
+ public class SequenceManager
+ {
+ long sequence = 0 ;
+ Dictionary<long, Object> pending = new Dictionary<long, Object>() ;
+ Object lockObject = new Object() ;
+
+ public SequenceManager()
+ {
+ }
+
+ public long Reserve(Object data) {
+ long returnValue = 0 ;
+ lock(lockObject) {
+ returnValue = sequence ;
+ sequence += 1 ;
+ pending.Add(returnValue, data) ;
+ }
+ return returnValue;
+ }
+
+ public Object Release(long seq) {
+ Object returnValue = null ;
+ lock(lockObject) {
+ returnValue = pending[seq] ;
+ pending.Remove(seq) ;
+ }
+
+ return returnValue ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Session.cs b/qpid/dotnet/client-010/management/console/Session.cs
new file mode 100644
index 0000000000..d9c5948e57
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Session.cs
@@ -0,0 +1,796 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO ;
+using System.Reflection ;
+using System.Threading ;
+using log4net ;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+
+ /**
+ * Main Interaction point for interaction with the bus. Can be used to locate objects
+ * on the bus, and invoke messages on them.
+ */
+ public class Session
+ {
+ public static ILog log = LogManager.GetLogger(typeof(Session)) ;
+
+ public static int CONTEXT_SYNC = 1 ;
+ public static int CONTEXT_STARTUP = 2 ;
+ public static int CONTEXT_MULTIGET = 3 ;
+ public static int DEFAULT_GET_WAIT_TIME = 60000 ;
+
+ public bool RecieveObjects = true ;
+ public bool RecieveEvents = true ;
+ public bool RecieveHeartbeat = true ;
+ public bool UserBindings = false ;
+ public Console Console ;
+
+ protected Dictionary<string, Dictionary<string, SchemaClass>> Packages = new Dictionary<string, Dictionary<string, SchemaClass>>() ;
+ protected List<Broker> Brokers = new List<Broker>() ;
+ protected SequenceManager SequenceManager = new SequenceManager() ;
+ protected object LockObject = new Object();
+ protected List<long> SyncSequenceList = new List<long>() ;
+ protected List<QMFObject> GetResult ;
+ protected Object SyncResult ;
+
+ public Session()
+ {
+ }
+
+ public Session(Console console) {
+ Console = console ;
+ }
+
+ public void AddBroker(string url) {
+ BrokerURL brokerurl = GetBrokerURL(url) ;
+ Broker broker = new Broker(this, brokerurl) ;
+ Brokers.Add(broker) ;
+
+ Dictionary<string, object> args = new Dictionary<string, object>() ;
+ args.Add("_class", "agent") ;
+ args.Add("_broker", broker) ;
+ this.GetObjects(args) ;
+ }
+
+ public void RemoveBroker(Broker broker) {
+ if (Brokers.Contains(broker)) {
+ Brokers.Remove(broker) ;
+ }
+
+ broker.Shutdown() ;
+ }
+
+ public void Close() {
+ foreach (Broker broker in Brokers.ToArray()) {
+ this.RemoveBroker(broker) ;
+ }
+ }
+
+ protected BrokerURL GetBrokerURL(string url) {
+ return new BrokerURL(url) ;
+ }
+
+
+ public List<QMFObject> GetObjects(Dictionary<string, object> args) {
+ List<Broker> brokerList = null ;
+ List<Agent> agentList = new List<Agent>() ;
+
+ if (args.ContainsKey("_broker")) {
+ brokerList = new List<Broker>() ;
+ brokerList.Add((Broker)args["_broker"]) ;
+ } else {
+ brokerList = this.Brokers ;
+ }
+
+ foreach (Broker broker in brokerList) {
+ broker.WaitForStable() ;
+ }
+
+ if (args.ContainsKey("_agent")) {
+ Agent agent = (Agent)args["_agent"] ;
+ if (brokerList.Contains(agent.Broker)) {
+ agentList.Add(agent) ;
+ } else {
+ throw new Exception("Agent is not managed by this console or the supplied broker") ;
+ }
+ } else {
+ if (args.ContainsKey("_objectId")) {
+ ObjectID oid = (ObjectID) args["_objectId"] ;
+ foreach (Broker broker in Brokers) {
+ foreach (Agent agent in broker.Agents.Values) {
+ if ((agent.AgentBank == oid.AgentBank()) && (agent.BrokerBank == oid.BrokerBank())) {
+ agentList.Add(agent) ;
+ }
+ }
+ }
+ }
+ else {
+ foreach (Broker broker in brokerList) {
+ foreach (Agent agent in broker.Agents.Values) {
+ if (agent.Broker.IsConnected()) {
+ agentList.Add(agent) ;
+ }
+ }
+ }
+ }
+ }
+
+ GetResult = new List<QMFObject>() ;
+
+ if (agentList.Count > 0) {
+ //FIXME Add a bunch of other suff too
+ foreach (Agent agent in agentList) {
+ Dictionary<string, object> getParameters = new Dictionary<string, object>() ;
+ Broker broker = agent.Broker ;
+ long seq = -1 ;
+ lock(LockObject) {
+ seq = SequenceManager.Reserve(Session.CONTEXT_MULTIGET) ;
+ SyncSequenceList.Add(seq) ;
+ }
+ object packageName = null ;
+ object className = null ;
+ object key = null ;
+ object sClass = null ;
+ object oid = null ;
+ object hash = null ;
+
+ args.TryGetValue("_schema", out sClass) ;
+ args.TryGetValue("_key", out key) ;
+ args.TryGetValue("_class", out className) ;
+ args.TryGetValue("_package", out packageName) ;
+ args.TryGetValue("_objectID", out oid) ;
+ args.TryGetValue("_hash", out hash) ;
+
+ if ((className == null) && (oid == null) && (oid == null)) {
+ throw new Exception("No class supplied, use '_schema', '_key', '_class', or '_objectId' argument") ;
+ }
+
+ if (oid != null) {
+ getParameters.Add("_objectID", oid) ;
+ }
+ else {
+ if (sClass != null) {
+ key = key ?? ((SchemaClass)sClass).Key ;
+ }
+ if (key != null) {
+ ClassKey cKey = (ClassKey)key ;
+ className = className ?? cKey.ClassName ;
+ packageName = packageName ?? cKey.PackageName ;
+ hash = hash ?? cKey.Hash ;
+ }
+
+ if (packageName != null) {
+ getParameters.Add("_package", packageName) ;
+ }
+ if (className != null) {
+ getParameters.Add("_class", className) ;
+ }
+ if (hash != null) {
+ getParameters.Add("_hash", hash) ;
+ }
+ foreach (KeyValuePair<string, object> pair in args) {
+ if (!pair.Key.StartsWith("_")) {
+ getParameters.Add(pair.Key, pair.Value) ;
+ }
+ }
+ }
+
+ IEncoder enc = broker.CreateEncoder('G', seq) ;
+ enc.WriteMap(getParameters) ;
+ string routingKey = String.Format("agent.{0}.{1}", agent.BrokerBank, agent.AgentBank) ;
+ Message msg = broker.CreateMessage(enc, routingKey) ;
+ log.Debug("Get Object Keys: ") ;
+ foreach (string pKey in getParameters.Keys) {
+ log.Debug(String.Format("\tKey: '{0}' Value: '{1}'", pKey, getParameters[pKey])) ;
+ }
+ broker.Send(msg) ;
+ }
+
+ int waittime = DEFAULT_GET_WAIT_TIME ;
+ bool timeout = false ;
+ if (args.ContainsKey("_timeout")) {
+ waittime = (int) args["_timeout"] ;
+ }
+ DateTime start = DateTime.Now ;
+ lock (LockObject) {
+ // FIXME ERROR
+ while (SyncSequenceList.Count > 0){
+ Monitor.Wait(LockObject,waittime) ;
+ TimeSpan duration = DateTime.Now - start;
+ if (duration.TotalMilliseconds > waittime) {
+ foreach (long pendingSeq in SyncSequenceList) {
+ SequenceManager.Release(pendingSeq) ;
+ }
+ SyncSequenceList.Clear() ;
+ timeout = true ;
+ }
+ }
+ }
+
+ //FIXME Add the error logic
+ if ((GetResult.Count == 0) && timeout) {
+ throw new Exception ("Get Request timed out") ;
+ }
+ }
+ return GetResult ;
+ }
+
+ public List<string> GetPackages() {
+ this.WaitForStable() ;
+ List<string> returnValue = new List<string>() ;
+ foreach (String name in Packages.Keys) {
+ returnValue.Add(name) ;
+ }
+
+ return returnValue ;
+ }
+
+ public List<ClassKey> GetClasses(string packageName) {
+ List<ClassKey> returnValue = new List<ClassKey>() ;
+ this.WaitForStable() ;
+
+ if (Packages.ContainsKey(packageName)) {
+ foreach (SchemaClass sClass in Packages[packageName].Values) {
+ returnValue.Add(sClass.Key) ;
+ }
+ }
+
+ return returnValue ;
+ }
+
+ public SchemaClass GetSchema(ClassKey key) {
+ return GetSchema(key, true) ;
+ }
+
+ protected SchemaClass GetSchema(ClassKey key, bool waitForStable) {
+ if (waitForStable) {
+ this.WaitForStable() ;
+ }
+
+ SchemaClass returnValue = null ;
+
+ try {
+ returnValue = Packages[key.PackageName][key.GetKeyString()] ;
+ }
+ catch (KeyNotFoundException) {
+ // eat it
+ }
+
+ return returnValue ;
+ }
+
+
+ protected void WaitForStable() {
+ foreach (Broker broker in Brokers) {
+ broker.WaitForStable() ;
+ }
+ }
+
+
+ public Broker GetBroker(long BrokerBank) {
+ Broker returnValue = null ;
+
+ foreach (Broker broker in Brokers) {
+ if (broker.BrokerBank() == BrokerBank) {
+ returnValue = broker ;
+ break ;
+ }
+ }
+
+ return returnValue ;
+ }
+
+ public MethodResult InvokeMethod(QMFObject obj, string name, List<object> args, bool synchronous, int timeToLive) {
+ Broker aBroker = this.GetBroker(obj.BrokerBank()) ;
+
+ long seq = this.SendMethodRequest(obj, aBroker, name, args, synchronous, timeToLive) ;
+ if (seq != 0) {
+ if (!synchronous) {
+ return null ;
+ }
+ try {
+ aBroker.WaitForSync(timeToLive) ;
+ } catch (Exception e) {
+ SequenceManager.Release(seq) ;
+ throw e ;
+ }
+
+ // FIXME missing error logic in the broker
+ return (MethodResult) SyncResult ;
+ }
+
+ return null ;
+ }
+
+ protected long SendMethodRequest(QMFObject obj, Broker aBroker, string name, List<object> args, bool synchronous, int timeToLive) {
+
+ SchemaMethod method = obj.Schema.GetMethod(name) ;
+ if (args == null) {
+ args = new List<object>() ;
+ }
+
+ long seq = 0 ;
+ if (method != null) {
+ KeyValuePair<SchemaMethod, bool> pair = new KeyValuePair<SchemaMethod, bool>(method, synchronous) ;
+ seq = SequenceManager.Reserve(pair) ;
+ IEncoder enc = aBroker.CreateEncoder('M', seq) ;
+ obj.ObjectID.encode(enc) ;
+ obj.Schema.Key.encode(enc) ;
+ enc.WriteStr8(name) ;
+
+ if (args.Count < method.InputArgCount) {
+ throw new Exception(String.Format("Incorrect number of arguments: expected {0}, got{1}", method.InputArgCount, args.Count)) ;
+ }
+
+ int argIndex = 0 ;
+ foreach (SchemaArgument arg in method.Arguments) {
+ if (arg.IsInput()) {;
+ this.EncodeValue(enc, arg.Type, args[argIndex]) ;
+ argIndex += 1 ;
+ }
+ }
+
+ Message msg = aBroker.CreateMessage(enc,obj.RoutingKey(),timeToLive) ;
+
+ if (synchronous) {
+ aBroker.SetSyncInFlight(true) ;
+ }
+ aBroker.Send(msg) ;
+ }
+ return seq ;
+ }
+
+ public QMFObject MakeObject(ClassKey key) {
+ SchemaClass sClass = this.GetSchema(key) ;
+ if (sClass == null) {
+ throw new Exception("No schema found for class " + key.ToString()) ;
+ }
+
+ return this.CreateQMFObject(sClass, true, true, false) ;
+ }
+
+ public QMFObject MakeObject(String keyString) {
+ return this.MakeObject(new ClassKey(keyString)) ;
+ }
+
+ // Callback Methods
+ public void HandleNewAgent(Agent agent) {
+ if (Console != null) {
+ Console.NewAgent(agent) ;
+ }
+ }
+
+ public void HandleAgentRemoved(Agent agent) {
+ if (Console != null) {
+ Console.AgentRemoved(agent) ;
+ }
+ }
+
+ public void HandleBrokerConnect(Broker broker) {
+ if (Console != null) {
+ Console.BrokerConnected(broker) ;
+ }
+ }
+
+ public void HandleBrokerDisconnect(Broker broker) {
+ if (Console != null) {
+ Console.BrokerDisconnected(broker) ;
+ }
+ }
+
+ public void HandleBrokerResponse(Broker broker, IDecoder decoder, long sequence) {
+ if (Console != null) {
+ Console.BrokerInformation(broker) ;
+ }
+
+ long seq = SequenceManager.Reserve(CONTEXT_STARTUP) ;
+ IEncoder endocder = broker.CreateEncoder('P', seq) ;
+ broker.Send(endocder) ;
+ }
+
+ public void HandlePackageIndicator(Broker broker, IDecoder decoder, long sequence) {
+ string packageName = decoder.ReadStr8() ;
+ bool notify = false ;
+ if (!Packages.ContainsKey(packageName)) {
+ lock (LockObject) {
+ Packages[packageName] = new Dictionary<string, SchemaClass>() ;
+ notify = true ;
+ }
+ }
+
+ if (notify && Console != null) {
+ Console.NewPackage(packageName) ;
+ }
+
+ broker.IncrementOutstanding() ;
+ long seq = SequenceManager.Reserve(Session.CONTEXT_STARTUP) ;
+ IEncoder enc = broker.CreateEncoder('Q', seq) ;
+ enc.WriteStr8(packageName) ;
+ broker.Send(enc) ;
+ }
+
+ public void HandleCommandComplete(Broker broker, IDecoder decoder, long sequence) {
+
+ long code = decoder.ReadUint32() ;
+ string text = decoder.ReadStr8() ;
+ Object context = this.SequenceManager.Release(sequence) ;
+
+ if (context.Equals(CONTEXT_STARTUP)) {
+ broker.DecrementOutstanding() ;
+ } else {
+ if ((context.Equals(CONTEXT_SYNC)) & broker.GetSyncInFlight()) {
+ broker.SetSyncInFlight(false) ;
+ } else {
+ if (context.Equals(CONTEXT_MULTIGET) && SyncSequenceList.Contains(sequence)) {
+ lock(LockObject) {
+ SyncSequenceList.Remove(sequence) ;
+ if (SyncSequenceList.Count == 0) {
+ Monitor.PulseAll(LockObject) ;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void HandleClassIndicator(Broker broker, IDecoder decoder, long sequence) {
+ short kind = decoder.ReadUint8() ;
+ ClassKey classKey = new ClassKey(decoder) ;
+ bool unknown = false ;
+
+
+ lock (LockObject) {
+ if (Packages.ContainsKey(classKey.PackageName)) {
+ if (!Packages[classKey.PackageName].ContainsKey(classKey.GetKeyString())) {
+ unknown = true ;
+ }
+ }
+ }
+
+ if (unknown) {
+ broker.IncrementOutstanding() ;
+ long seq = SequenceManager.Reserve(Session.CONTEXT_STARTUP) ;
+ IEncoder enc = broker.CreateEncoder('S', seq) ;
+ classKey.encode(enc) ;
+ broker.Send(enc) ;
+ }
+ }
+
+ public void HandleMethodResponse(Broker broker, IDecoder decoder, long sequence) {
+ long code = decoder.ReadUint32() ;
+ string text = decoder.ReadStr16() ;
+
+ Dictionary<string, object> outArgs = new Dictionary<string, object>() ;
+ object obj = SequenceManager.Release(sequence) ;
+
+ if (obj == null) {
+ return ;
+ }
+
+ KeyValuePair<SchemaMethod, bool> pair = (KeyValuePair<SchemaMethod, bool>) obj ;
+ if (code == 0) {
+ foreach (SchemaArgument arg in pair.Key.Arguments) {
+ if (arg.IsOutput()) {
+ outArgs.Add(arg.Name, this.DecodeValue(decoder, arg.Type)) ;
+ }
+ }
+ }
+
+ MethodResult result = new MethodResult(code, text, outArgs) ;
+
+ if (pair.Value) {
+ this.SyncResult = result;
+ broker.SetSyncInFlight(false) ;
+ }
+
+ if (Console != null) {
+ Console.MethodResponse(broker, sequence, result) ;
+ }
+ }
+
+ public void HandleHeartbeatIndicator(Broker broker, IDecoder decoder, long sequence, IMessage msg) {
+ if (Console != null) {
+ long brokerBank = 1 ;
+ long agentBank = 0 ;
+ try {
+ string routingKey = msg.DeliveryProperties.GetRoutingKey() ;
+ if (routingKey != null) {
+ agentBank = Agent.GetBrokerBank(routingKey) ;
+ brokerBank = Agent.GetBrokerBank(routingKey) ;
+ }
+ }
+ catch (Exception e) {
+ log.Warn("Internal QPID error", e) ;
+ }
+
+ string agentKey = Agent.AgentKey(agentBank, brokerBank) ;
+ long timestamp = decoder.ReadUint64() ;
+ if (broker.Agents.ContainsKey(agentKey)) {
+ Agent agent = broker.Agents[agentKey] ;
+ Console.HearbeatRecieved(agent, timestamp) ;
+ }
+ }
+
+ }
+
+ public void HandleEventIndicator(Broker broker, IDecoder decoder, long sequence) {
+ if (Console != null) {
+ QMFEvent newEvent = new QMFEvent(this, decoder) ;
+ Console.EventRecieved(broker, newEvent) ;
+ }
+ }
+
+ public void HandleSchemaResponse(Broker broker, IDecoder decoder, long sequence) {
+ short kind = decoder.ReadUint8() ;
+ ClassKey classKey = new ClassKey(decoder) ;
+ SchemaClass sClass = new SchemaClass(kind, classKey, decoder, this) ;
+ lock(LockObject) {
+ Dictionary<string, SchemaClass> classMappings = Packages[sClass.PackageName] ;
+ classMappings.Remove(sClass.ClassKeyString) ;
+ classMappings.Add(sClass.ClassKeyString, sClass) ;
+ }
+
+ SequenceManager.Release(sequence) ;
+ broker.DecrementOutstanding() ;
+ if (Console != null) {
+ this.Console.NewClass(kind, classKey) ;
+ }
+ }
+
+ public void HandleContentIndicator(Broker broker, IDecoder decoder, long sequence, bool hasProperties, bool hasStatistics) {
+
+ ClassKey key = new ClassKey(decoder) ;
+ SchemaClass sClass = null ;;
+ lock (LockObject) {
+ sClass = GetSchema(key, false) ;
+ }
+ if (sClass != null) {
+ QMFObject obj = this.CreateQMFObject(sClass, decoder, hasProperties, hasStatistics, true) ;
+
+ if (key.PackageName.Equals("org.apache.qpid.broker") && key.ClassName.Equals("agent") && hasProperties) {
+ broker.UpdateAgent(obj) ;
+ }
+
+ lock (LockObject) {
+ if (SyncSequenceList.Contains(sequence)) {
+ if (!obj.IsDeleted() && this.SelectMatch(obj)) {
+ GetResult.Add(obj) ;
+ }
+ }
+ }
+
+ if (Console != null) {
+ if (hasProperties) {
+ Console.ObjectProperties(broker, obj) ;
+ }
+ if (hasStatistics) {
+ Console.ObjectStatistics(broker, obj) ;
+ }
+ }
+ }
+ }
+
+ public bool SelectMatch(QMFObject obj) {
+ return true ;
+ }
+
+ public object DecodeValue(IDecoder dec, short type) {
+
+ switch (type) {
+ case 1: return dec.ReadUint8() ; // U8
+ case 2: return dec.ReadUint16() ; // U16
+ case 3: return dec.ReadUint32() ; // U32
+ case 4: return dec.ReadUint64() ; // U64
+ case 6: return dec.ReadStr8() ; // SSTR
+ case 7: return dec.ReadStr16() ; // LSTR
+ case 8: return dec.ReadDatetime() ; // ABSTIME
+ case 9: return dec.ReadUint32() ; // DELTATIME
+ case 10: return new ObjectID(dec) ; // ref
+ case 11: return dec.ReadUint8() != 0 ; // bool
+ case 12: return dec.ReadFloat() ; // float
+ case 13: return dec.ReadDouble() ; // double
+ case 14: return dec.ReadUuid() ; // UUID
+ case 15: return dec.ReadMap() ; // Ftable
+ case 16: return dec.ReadInt8() ; // int8
+ case 17: return dec.ReadInt16() ; // int16
+ case 18: return dec.ReadInt32() ; // int32
+ case 19: return dec.ReadInt64() ; // int64
+ case 20: // Object
+ // Peek into the inner type code, make sure
+ // it is actually an object
+ object returnValue = null ;
+ short innerTypeCode = dec.ReadUint8() ;
+ if (innerTypeCode != 20) {
+ returnValue = this.DecodeValue(dec, innerTypeCode) ;
+ }
+ else {
+ ClassKey classKey = new ClassKey(dec) ;
+ lock(LockObject) {
+ SchemaClass sClass = GetSchema(classKey) ;
+ if (sClass != null) {
+ returnValue = this.CreateQMFObject(sClass, dec, true, true, false) ;
+ }
+ }
+ }
+ return returnValue;
+ case 21: // List
+ {
+ MSDecoder lDec = new MSDecoder();
+ lDec.Init(new MemoryStream(dec.ReadVbin32()));
+ long count = lDec.ReadUint32();
+ List<object> newList = new List<object>();
+ while (count > 0)
+ {
+ short innerType = lDec.ReadUint8();
+ newList.Add(this.DecodeValue(lDec, innerType));
+ count -= 1;
+ }
+ return newList;
+ }
+ case 22: // Array
+ {
+ MSDecoder aDec = new MSDecoder();
+ aDec.Init(new MemoryStream(dec.ReadVbin32()));
+ long cnt = aDec.ReadUint32();
+ short innerType = aDec.ReadUint8();
+ List<object> aList = new List<object>();
+ while (cnt > 0)
+ {
+ aList.Add(this.DecodeValue(aDec, innerType));
+ cnt -= 1;
+ }
+ return aList;
+ }
+ default:
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+ }
+
+
+ public void EncodeValue(IEncoder enc, short type, object val) {
+ try {
+ switch ((int)type) {
+ case 1: enc.WriteUint8((short) val) ; break; // U8
+ case 2: enc.WriteUint16((int) val) ; break; // U16
+ case 3: enc.WriteUint32((long) val) ; break; // U32
+ case 4: enc.WriteUint64((long) val) ; break; // U64
+ case 6: enc.WriteStr8((string) val) ; break; // SSTR
+ case 7: enc.WriteStr16((string) val) ; break; // LSTR
+ case 8: enc.WriteDatetime((long) val); break; // ABSTIME
+ case 9: enc.WriteUint32((long) val); break; // DELTATIME
+ case 10: ((ObjectID)val).encode(enc) ; break; // ref
+ case 11:
+ if ((bool) val) {
+ enc.WriteUint8(1) ;
+ } else {
+ enc.WriteUint8(0) ;
+ }
+ break ;
+ case 12: enc.WriteFloat((float) val); break; // FLOAT
+ case 13: enc.WriteDouble((double) val); break; // DOUBLE
+ case 14: enc.WriteUuid((UUID) val) ; break ; // UUID
+ case 15: enc.WriteMap((Dictionary<string, object>) val) ; break ; // Ftable
+ case 16: enc.WriteInt8((short) val) ; break; // int8
+ case 17: enc.WriteInt16((int) val) ; break; // int16
+ case 18: enc.WriteInt32(long.Parse(""+ val)) ; break; // int32
+ case 19: enc.WriteInt64(long.Parse("" + val)) ; break; // int64
+ case 20: // Object
+ // Check that the object has a session, if not
+ // take ownership of it
+ QMFObject qObj = (QMFObject) val ;
+ if (qObj.Session == null) {
+ qObj.Session = this ;
+ }
+ qObj.Encode(enc) ;
+ break;
+ case 21: // List
+ List<object> items = (List<object>) val ;
+ MSEncoder lEnc = new MSEncoder(1) ;
+ lEnc.Init() ;
+ lEnc.WriteUint32(items.Count) ;
+ foreach (object obj in items) {
+ short innerType = Util.QMFType(obj) ;
+ lEnc.WriteUint8(innerType) ;
+ this.EncodeValue(lEnc,innerType,obj) ;
+ }
+ enc.WriteVbin32(lEnc.Segment().ToArray()) ;
+ break ;
+ case 22: // Array
+ List<object> aItems = (List<object>) val ;
+ MSEncoder aEnc = new MSEncoder(1) ;
+ aEnc.Init() ;
+ long aCount = aItems.Count ;
+ aEnc.WriteUint32(aCount) ;
+ if (aCount > 0) {
+ Object anObj = aItems[0] ;
+ short innerType = Util.QMFType(anObj) ;
+ aEnc.WriteUint8(innerType) ;
+ foreach (object obj in aItems) {
+ this.EncodeValue(aEnc,innerType,obj) ;
+ }
+ }
+ enc.WriteVbin32(aEnc.Segment().ToArray()) ;
+ break ;
+ default:
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+ }
+ catch (System.InvalidCastException e) {
+ string msg = String.Format("Class cast exception for typecode {0}, type {1} ", type, val.GetType()) ;
+ log.Error(msg) ;
+ throw new Exception(msg + type, e) ;
+ }
+ }
+
+ public List<string> BindingKeys() {
+ List<string> bindings = new List<string>() ;
+ bindings.Add("schema.#") ;
+ if (RecieveObjects & RecieveEvents & RecieveHeartbeat & !UserBindings) {
+ bindings.Add("console.#") ;
+ }
+ else {
+ if (RecieveObjects & !UserBindings) {
+ bindings.Add("console.obj.#") ;
+ }
+ else {
+ bindings.Add("console.obj.*.*.org.apache.qpid.broker.agent") ;
+ }
+ if (RecieveEvents) {
+ bindings.Add("console.event.#") ;
+ }
+ if (RecieveHeartbeat) {
+ bindings.Add("console.heartbeat.#") ;
+ }
+ }
+ return bindings ;
+ }
+
+ protected QMFObject CreateQMFObject(SchemaClass schema, bool hasProperties, bool hasStats , bool isManaged) {
+ Type realClass = typeof(QMFObject) ;
+ if (Console != null) {
+ realClass = Console.TypeMapping(schema.Key) ;
+ }
+ Type[] types = new Type[] {typeof(Session), typeof(SchemaClass), typeof(bool), typeof(bool),typeof(bool)} ;
+ object[] args = new object[] {this, schema, hasProperties, hasStats, isManaged} ;
+ ConstructorInfo ci = realClass.GetConstructor(types);
+ return (QMFObject) ci.Invoke(args) ;
+ }
+
+ protected QMFObject CreateQMFObject(SchemaClass schema, IDecoder dec, bool hasProperties, bool hasStats , bool isManaged) {
+ Type realClass = typeof(QMFObject) ;
+ if (Console != null) {
+ realClass = Console.TypeMapping(schema.Key) ;
+ }
+ Type[] types = new Type[] {typeof(Session), typeof(SchemaClass), typeof(IDecoder), typeof(bool), typeof(bool),typeof(bool)} ;
+ object[] args = new object[] {this, schema, dec, hasProperties, hasStats, isManaged} ;
+ ConstructorInfo ci = realClass.GetConstructor(types);
+ return (QMFObject) ci.Invoke(args) ;
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/Util.cs b/qpid/dotnet/client-010/management/console/Util.cs
new file mode 100644
index 0000000000..4a06f4e6af
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/Util.cs
@@ -0,0 +1,150 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.client ;
+using org.apache.qpid.transport.util;
+using org.apache.qpid.transport.codec ;
+
+namespace org.apache.qpid.console
+{
+ public class Util
+ {
+ static Dictionary<Type, short> ENCODINGS = new Dictionary<Type, short>() ;
+
+
+ static Util() {
+ ENCODINGS.Add(typeof(string), 7) ;
+ ENCODINGS.Add(typeof(short), 1) ;
+ //ENCODINGS.Add(typeof(int), 2) ;
+ //ENCODINGS.Add(typeof(long), 3) ;
+ ENCODINGS.Add(typeof(float), 13) ;
+ ENCODINGS.Add(typeof(QMFObject), 20) ;
+ ENCODINGS.Add(typeof(int), 17) ;
+ ENCODINGS.Add(typeof(long), 18) ;
+ ENCODINGS.Add(typeof(System.Collections.Generic.List<>), 21) ;
+ }
+
+ /**
+ * Converts type numbers to schema type names
+ */
+ public static string TypeName(short type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return "uint8" ;
+ case 2: return "uint16" ;
+ case 3: return "uint32" ;
+ case 4: return "uint64" ;
+ case 5: return "bool" ;
+ case 6: return "short-string" ;
+ case 7: return "long-string" ;
+ case 8: return "abs-time" ;
+ case 9: return "delta-time" ;
+ case 10: return "reference" ;
+ case 11: return "boolean" ;
+ case 12: return "float" ;
+ case 13: return "double" ;
+ case 14: return "uuid" ;
+ case 15: return "field-table" ;
+ case 16: return "int8" ;
+ case 17: return "int16" ;
+ case 18: return "int32" ;
+ case 19: return "int64" ;
+ case 20: return "object" ;
+ case 21: return "list" ;
+ case 22: return "array" ;
+ }
+
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+
+ /**
+ * Converts schema numbers to schema access names
+ */
+ public static string AccessName(int type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return "ReadCreate" ;
+ case 2: return "ReadWrite" ;
+ case 3: return "ReadOnly" ;
+ }
+
+ throw new Exception(String.Format("Invalid Access Code: {0}", type)) ;
+ }
+
+ /**
+ * Default values per schema type
+ */
+ public static object DefaultValue(short type) {
+ switch(type) {
+ //case 0: return "UNKNOWN" ;
+ case 1: return 0 ;
+ case 2: return 0 ;
+ case 3: return 0l ;
+ case 4: return 0l ;
+ case 5: return false ;
+ case 6: return "" ;
+ case 7: return "" ;
+ case 8: return 0l ;
+ case 9: return 0l ;
+ case 10: return new ObjectID() ;
+ case 11: return false ;
+ case 12: return 0f ;
+ case 13: return 0d ;
+ case 14: return new UUID(0,0) ;
+ case 15: return new Dictionary<string, object>();
+ case 16: return 0 ;
+ case 17: return 0 ;
+ case 18: return 0l ;
+ case 19: return 0l ;
+ case 20: return null ;
+ case 21: return new List<object>() ;
+ case 22: return new List<object>() ;
+ }
+
+ throw new Exception(String.Format("Invalid Type Code: {0}", type)) ;
+ }
+
+ /**
+ * Returns a QMF type based on C# object type
+ */
+ public static short QMFType(object obj) {
+ if (ENCODINGS.ContainsKey(obj.GetType())) {
+ return ENCODINGS[obj.GetType()] ;
+ } else {
+ throw new Exception (String.Format("Unkown Type of {0}", obj.GetType())) ;
+ }
+ }
+
+ /**
+ * Grabs a friendly string version of bytes.
+ */
+ public static string ByteString(byte[] bytes) {
+ return System.Text.Encoding.UTF8.GetString(bytes) ;
+ }
+
+ protected Util()
+ {
+
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/XMLUtil.cs b/qpid/dotnet/client-010/management/console/XMLUtil.cs
new file mode 100644
index 0000000000..b24ad51747
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/XMLUtil.cs
@@ -0,0 +1,127 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+using System;
+using System.Collections.Generic;
+using org.apache.qpid.client ;
+
+namespace org.apache.qpid.console
+{
+
+
+ public class XMLUtil
+ {
+
+ public static string CommonAttributes(SchemaVariable var) {
+ string returnString = "" ;
+ if (var.Description != null){
+ returnString = returnString + String.Format(" desc='{0}'", var.Description) ;
+ }
+
+ if (var.RefPackage != null){
+ returnString = returnString + String.Format(" refPackage='{0}'", var.RefPackage) ;
+ }
+
+ if (var.RefClass != null){
+ returnString = returnString + String.Format(" refClass='{0}'", var.RefClass) ;
+ }
+
+ if (var.Unit != null){
+ returnString = returnString + String.Format(" unit='{0}'", var.Unit) ;
+ }
+
+ if (var.Min != null){
+ returnString = returnString + String.Format(" min='{0}'", var.Min) ;
+ }
+ if (var.Max != null){
+ returnString = returnString + String.Format(" max='{0}'", var.Max) ;
+ }
+ if (var.MaxLength != null){
+ returnString = returnString + String.Format(" maxLength='{0}'", var.MaxLength) ;
+ }
+
+ return returnString ;
+ }
+
+ public static string SchemaXML(Session sess, string packageName) {
+ string returnValue = String.Format("<schema package='{0}'>\n", packageName) ;
+ foreach (ClassKey key in sess.GetClasses(packageName)) {
+ SchemaClass schema = sess.GetSchema(key) ;
+ if (schema.Kind == 1) {
+ if (schema.SuperType == null)
+ returnValue += String.Format("\t<class name='{0}' hash='{1}'>\n", key.ClassName, key.GetHashString()) ;
+ else
+ returnValue += String.Format("\t<class name='{0}' hash='{1}' extends='{2}'>\n", key.ClassName, key.GetHashString(), schema.SuperType.GetKeyString()) ;
+ foreach (SchemaProperty prop in schema.Properties) {
+ object[] attributes = new object[5] ;
+ attributes[0] = prop.Name ;
+ attributes[1] = Util.TypeName(prop.Type) ;
+ attributes[2] = Util.AccessName(prop.Access) ;
+ attributes[3] = prop.Optional ;
+ attributes[4] = XMLUtil.CommonAttributes(prop);
+ returnValue += String.Format("\t\t<property name='{0}' type='{1}' access='{2}' optional='{3}'{4}/>\n", attributes) ;
+ }
+ foreach (SchemaMethod meth in schema.Methods) {
+ returnValue += String.Format("\t\t<method name='{0}'/>\n", meth.Name) ;
+ foreach (SchemaArgument arg in meth.Arguments) {
+ object[] attributes = new object[4] ;
+ attributes[0] = arg.Name ;
+ attributes[1] = arg.Direction ;
+ attributes[2] = Util.TypeName(arg.Type) ;
+ attributes[3] = XMLUtil.CommonAttributes(arg);
+ returnValue += String.Format("\t\t\t<arg name='{0}' dir='{1}' type='{2}'{3}/>\n", attributes) ;
+ }
+ returnValue += String.Format("\t\t</method>\n") ;
+ }
+ returnValue += String.Format("\t</class>\n") ;
+ } else {
+ returnValue += String.Format("\t<event name='{0}' hash='{1}'>\n", key.ClassName, key.GetHashString()) ;
+ foreach (SchemaArgument arg in schema.Arguments) {
+ object[] attributes = new object[4] ;
+ attributes[0] = arg.Name ;
+ attributes[1] = Util.TypeName(arg.Type) ;
+ attributes[2] = XMLUtil.CommonAttributes(arg);
+ returnValue += String.Format("\t\t\t<arg name='{0}' type='{1}'{2}/>\n", attributes) ;
+ }
+ returnValue += String.Format("\t</event>\n") ;
+ }
+ }
+ returnValue += String.Format("</schema>\n") ;
+
+ return returnValue ;
+ }
+
+ public static string SchemaXML(Session sess, string[] packageNames) {
+ string returnValue = "<schemas>\n" ;
+ foreach (string package in packageNames) {
+ returnValue += XMLUtil.SchemaXML(sess, package) ;
+ returnValue += "\n" ;
+ }
+ returnValue += "</schemas>\n" ;
+ return returnValue ;
+ }
+
+ protected XMLUtil()
+ {
+ }
+ }
+}
diff --git a/qpid/dotnet/client-010/management/console/console.csproj b/qpid/dotnet/client-010/management/console/console.csproj
new file mode 100644
index 0000000000..3cc84e6073
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/console.csproj
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ -
+ - 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.
+ -
+ -->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{E8D2202F-3959-4F29-AA0D-875CD37905CA}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Console</RootNamespace>
+ <AssemblyName>Console</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\lib\log4net\log4net.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="AbstractConsole.cs" />
+ <Compile Include="Agent.cs" />
+ <Compile Include="Broker.cs" />
+ <Compile Include="BrokerURL.cs" />
+ <Compile Include="ClassKey.cs" />
+ <Compile Include="Console.cs" />
+ <Compile Include="MethodResult.cs" />
+ <Compile Include="ObjectID.cs" />
+ <Compile Include="QMFEvent.cs" />
+ <Compile Include="QMFObject.cs" />
+ <Compile Include="SchemaArgument.cs" />
+ <Compile Include="SchemaClass.cs" />
+ <Compile Include="SchemaMethod.cs" />
+ <Compile Include="SchemaProperty.cs" />
+ <Compile Include="SchemaStatistic.cs" />
+ <Compile Include="SchemaVariable.cs" />
+ <Compile Include="SequenceManager.cs" />
+ <Compile Include="Session.cs" />
+ <Compile Include="Util.cs" />
+ <Compile Include="XMLUtil.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\client\Client.csproj">
+ <Project>{B911FFD7-754F-4735-A188-218D5065BE79}</Project>
+ <Name>Client</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Properties\" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
diff --git a/qpid/dotnet/client-010/management/console/console.sln b/qpid/dotnet/client-010/management/console/console.sln
new file mode 100644
index 0000000000..1cfc056302
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/console.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+
+#
+# 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.
+#
+
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console.csproj", "{E8D2202F-3959-4F29-AA0D-875CD37905CA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Client", "..\..\client\Client.csproj", "{B911FFD7-754F-4735-A188-218D5065BE79}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E8D2202F-3959-4F29-AA0D-875CD37905CA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B911FFD7-754F-4735-A188-218D5065BE79}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/qpid/dotnet/client-010/management/console/default.build b/qpid/dotnet/client-010/management/console/default.build
new file mode 100644
index 0000000000..c71e695569
--- /dev/null
+++ b/qpid/dotnet/client-010/management/console/default.build
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!--
+
+ 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.
+
+-->
+
+<project name="qpid.console" default="build">
+ <!--
+ Properties that come from master build file
+ - build.dir: root directory for build
+ - build.debug: true if building debug release
+ - build.defines: variables to define during build
+ -->
+
+ <property name="build.config" value="debug" />
+ <property name="build.debug" value="true" />
+ <property name="build.defines" value="DEBUG;TRACE"/>
+ <property name="base.dir" value="${project::get-base-directory()}/../.." />
+ <property name="build.dir" value="${base.dir}/bin/${framework::get-target-framework()}/${build.config}" />
+
+
+ <target name="build">
+ <csc target="library"
+ define="${build.defines}"
+ debug="${build.debug}"
+ output="${build.dir}/${project::get-name()}.dll">
+
+ <sources>
+ <include name="***.cs" />
+ <exclude name="test/*.cs"/>
+ </sources>
+ <references>
+ <include name="${build.dir}/log4net.dll" />
+ <include name="${build.dir}/qpid.client.dll" />
+ </references>
+ </csc>
+ </target>
+</project>