using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Xml.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Channels;
#if BIZTALKSERVICES
using System.ServiceBus;
#endif
namespace dasBlog.Storage{
[DataContract(Namespace = Names.DataContractNamespace)]
public sealed class PathSegmentName : IEquatable<PathSegmentName>
{
[DataContract(Namespace = Names.DataContractNamespace)]
public enum Roles
{
[EnumMember]
Posts,
[EnumMember]
Comments,
[EnumMember]
Pictures,
[EnumMember]
Media,
[EnumMember]
Annotations,
[EnumMember]
Persons,
[EnumMember]
Tags,
[EnumMember]
Trackings,
[EnumMember]
Ratings,
[EnumMember]
Events,
[EnumMember]
Custom
}
[DataMember]
public Roles Role { get; set; }
[DataMember]
public string Value { get; set; }
public PathSegmentName()
{
}
public PathSegmentName(Roles nodeType)
{
if (nodeType == Roles.Custom)
throw new InvalidOperationException("Can't define custom node types with this constructor");
Role = nodeType;
Value = RoleToString(nodeType);
}
public PathSegmentName(string name)
{
Role = RoleFromString(name);
Value = name;
}
public override bool Equals(object obj)
{
PathSegmentName that = (PathSegmentName)obj;
return Role == that.Role && Value == that.Value;
}
public override int GetHashCode()
{
return base.GetHashCode() ^ Value.GetHashCode();
}
public override string ToString()
{
return Value;
}
public static string RoleToString(Roles nodeType)
{
switch (nodeType)
{
case Roles.Annotations:
return Properties.Resources.StorageNodeTypeAnnotations;
case Roles.Comments:
return Properties.Resources.StorageNodeTypeComments;
case Roles.Media:
return Properties.Resources.StorageNodeTypeMedia;
case Roles.Persons:
return Properties.Resources.StorageNodeTypePersons;
case Roles.Pictures:
return Properties.Resources.StorageNodeTypePictures;
case Roles.Posts:
return Properties.Resources.StorageNodeTypePosts;
case Roles.Tags:
return Properties.Resources.StorageNodeTypeTags;
case Roles.Trackings:
return Properties.Resources.StorageNodeTypeTrackings;
case Roles.Ratings:
return Properties.Resources.StorageNodeTypeRatings;
case Roles.Events:
return Properties.Resources.StorageNodeTypeEvents;
default:
return null;
}
}
public static Roles RoleFromString(string name)
{
if (name == Properties.Resources.StorageNodeTypeAnnotations)
return (Roles.Annotations);
else if (name == Properties.Resources.StorageNodeTypeComments)
return (Roles.Comments);
else if (name == Properties.Resources.StorageNodeTypeMedia)
return (Roles.Media);
else if (name == Properties.Resources.StorageNodeTypePersons)
return (Roles.Persons);
else if (name == Properties.Resources.StorageNodeTypePictures)
return (Roles.Pictures);
else if (name == Properties.Resources.StorageNodeTypePosts)
return (Roles.Posts);
else if (name == Properties.Resources.StorageNodeTypeTags)
return (Roles.Tags);
else if (name == Properties.Resources.StorageNodeTypeTrackings)
return (Roles.Trackings);
else if (name == Properties.Resources.StorageNodeTypeRatings)
return (Roles.Ratings);
else if (name == Properties.Resources.StorageNodeTypeEvents)
return (Roles.Events);
else
return Roles.Custom;
}
public static readonly PathSegmentName Posts = new PathSegmentName(Roles.Posts);
public static readonly PathSegmentName Comments = new PathSegmentName(Roles.Comments);
public static readonly PathSegmentName Pictures = new PathSegmentName(Roles.Pictures);
public static readonly PathSegmentName Media = new PathSegmentName(Roles.Media);
public static readonly PathSegmentName Annotations = new PathSegmentName(Roles.Annotations);
public static readonly PathSegmentName Persons = new PathSegmentName(Roles.Persons);
public static readonly PathSegmentName Tags = new PathSegmentName(Roles.Tags);
public static readonly PathSegmentName Trackings = new PathSegmentName(Roles.Trackings);
public static readonly PathSegmentName Ratings = new PathSegmentName(Roles.Ratings);
public static readonly PathSegmentName Events = new PathSegmentName(Roles.Events);
#region IEquatable<NodeName> Members
public bool Equals(PathSegmentName other)
{
return Role == other.Role && Value == other.Value;
}
#endregion
public static bool operator ==(PathSegmentName a, PathSegmentName b)
{
return a.Equals(b);
}
public static bool operator !=(PathSegmentName a, PathSegmentName b)
{
return !a.Equals(b);
}
}
[DataContract(Namespace = Names.DataContractNamespace)]
public sealed class NodeDescription
{
[DataMember]
public PathMappings Paths { get; set; }
[DataMember]
public EndpointReferenceType EndpointReference { get; set; }
private IStorageNode _storageNode;
private bool _isBound=false;
public NodeDescription()
{
Paths = new PathMappings();
}
public NodeDescription(IStorageNode node)
: this()
{
_storageNode = node;
}
public NodeDescription(PathMappings childMappings)
: this()
{
this.Paths = childMappings;
}
public NodeDescription(PathMappings childMappings, IStorageNode node)
: this(childMappings)
{
_storageNode = node;
}
internal IStorageNode GetStorageNode()
{
return _storageNode;
}
internal void SetStorageNode(IStorageNode node)
{
_storageNode = node;
}
internal void BindNode()
{
if (_isBound) return;
_isBound = true;
if (_storageNode == null && this.EndpointReference != null)
{
var endpointRef = this.EndpointReference;
ContractDescription mexDescription = EndpointContractDescription<IMetadataExchange>.Description;
ContractDescription stgDescription = EndpointContractDescription<IStorageNode>.Description;
ContractDescription stmDescription = EndpointContractDescription<IStreamStorageNode>.Description;
var endpointAddress = endpointRef.ToEndpointAddress();
if (endpointRef.PortType.Value.Name == mexDescription.Name &&
endpointRef.PortType.Value.Namespace == mexDescription.Namespace)
{
MetadataExchangeClient client = new MetadataExchangeClient(GetBindingFromEndpoint(endpointAddress.Uri));
WsdlImporter importer = new WsdlImporter(client.GetMetadata(endpointAddress));
var eps = importer.ImportAllEndpoints();
foreach (ServiceEndpoint endpoint in
eps.Where((s) =>
s.Contract.Name == Names.IStorageNodeName &&
s.Contract.Namespace == Names.IStorageNodeNamespace))
{
ChannelFactory<IStorageNodeChannel> factory = new ChannelFactory<IStorageNodeChannel>(endpoint.Binding, endpoint.Address);
endpoint.Behaviors.Add(new SimpleAuthenticationBehavior());
var channel = factory.CreateChannel();
SetStorageNode(channel);
}
}
else if (endpointRef.PortType.Value.Name == stgDescription.Name &&
endpointRef.PortType.Value.Namespace == stgDescription.Namespace)
{
ChannelFactory<IStorageNodeChannel> factory = new ChannelFactory<IStorageNodeChannel>(GetBindingFromEndpoint(endpointAddress.Uri), endpointAddress);
factory.Endpoint.Behaviors.Add(new SimpleAuthenticationBehavior());
var channel = factory.CreateChannel();
SetStorageNode(channel);
}
else if (endpointRef.PortType.Value.Name == stmDescription.Name &&
endpointRef.PortType.Value.Namespace == stmDescription.Namespace)
{
ChannelFactory<IStreamStorageNodeChannel> factory = new ChannelFactory<IStreamStorageNodeChannel>(GetBindingFromEndpoint(endpointAddress.Uri), endpointRef.ToEndpointAddress());
factory.Endpoint.Behaviors.Add(new SimpleAuthenticationBehavior());
var channel = factory.CreateChannel();
SetStorageNode(channel);
}
}
foreach (PathMapping mapping in this.Paths)
{
mapping.Node.BindNode();
}
}
private static Binding GetBindingFromEndpoint(Uri endpointAddress)
{
Binding binding;
switch (endpointAddress.Scheme)
{
#if BIZTALKSERVICES
case "sb":
binding = new RelayBinding(RelayConnectionMode.HybridDuplexSession);
break;
#endif
default:
case "http":
case "https":
binding = new BasicHttpBinding();
break;
}
return binding;
}
}
}
|