diff options
Diffstat (limited to 'qpid/dotnet/client-010/management')
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> |