Browse Source

Support discovering services using metadata exchange.

pull/6/merge
Matt Ward 14 years ago
parent
commit
f411289491
  1. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  2. 94
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs
  3. 90
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryClient.cs
  4. 57
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryEventArgs.cs

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -280,6 +280,8 @@ @@ -280,6 +280,8 @@
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\MetadataFile.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\MetadataSource.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ProjectWithServiceReferences.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceDiscoveryClient.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceDiscoveryEventArgs.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceFileGenerator.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceFileName.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\ServiceReference\ServiceReferenceFileSystem.cs" />

94
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/AddServiceReferenceViewModel.cs

@ -43,9 +43,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -43,9 +43,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
ServiceItem myItem;
Uri discoveryUri;
ServiceDescriptionCollection serviceDescriptionCollection = new ServiceDescriptionCollection();
CredentialCache credentialCache = new CredentialCache();
WebServiceDiscoveryClientProtocol discoveryClientProtocol;
ServiceReferenceDiscoveryClient serviceReferenceDiscoveryClient;
delegate DiscoveryDocument DiscoverAnyAsync(string url);
delegate void DiscoveredWebServicesHandler(DiscoveryClientProtocol protocol);
@ -121,13 +121,32 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -121,13 +121,32 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
AsyncCallback callback = new AsyncCallback(DiscoveryCompleted);
discoveryClientProtocol.Credentials = credential;
IAsyncResult result = asyncDelegate.BeginInvoke(uri.AbsoluteUri, callback, new AsyncDiscoveryState(discoveryClientProtocol, uri, credential));
serviceReferenceDiscoveryClient.DiscoveryComplete += ServiceReferenceDiscoveryComplete;
serviceReferenceDiscoveryClient.Discover(uri);
}
void ServiceReferenceDiscoveryComplete(object sender, ServiceReferenceDiscoveryEventArgs e)
{
if (Object.ReferenceEquals(serviceReferenceDiscoveryClient, sender)) {
if (e.HasError) {
OnWebServiceDiscoveryError(e.Error);
} else {
DiscoveredWebServices(e.Services);
}
}
}
void OnWebServiceDiscoveryError(Exception ex)
{
ServiceDescriptionMessage = ex.Message;
ICSharpCode.Core.LoggingService.Debug("DiscoveryCompleted: " + ex.ToString());
}
/// <summary>
/// Called after an asynchronous web services search has
/// completed.
/// </summary>
///
void DiscoveryCompleted(IAsyncResult result)
{
AsyncDiscoveryState state = (AsyncDiscoveryState)result.AsyncState;
@ -144,20 +163,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -144,20 +163,9 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
try {
DiscoverAnyAsync asyncDelegate = (DiscoverAnyAsync)((AsyncResult)result).AsyncDelegate;
DiscoveryDocument handlerdoc = asyncDelegate.EndInvoke(result);
if (!state.Credential.IsDefaultAuthenticationType) {
AddCredential(state.Uri, state.Credential);
}
handler(protocol);
} catch (Exception ex) {
if (protocol.IsAuthenticationRequired) {
HttpAuthenticationHeader authHeader = protocol.GetAuthenticationHeader();
AuthenticationHandler authHandler = new AuthenticationHandler(AuthenticateUser);
// trouble Invoke(authHandler, new object[] {state.Uri, authHeader.AuthenticationType});
} else {
ServiceDescriptionMessage = ex.Message;
ICSharpCode.Core.LoggingService.Error("DiscoveryCompleted", ex);
// trouble Invoke(handler, new object[] {null});
}
OnWebServiceDiscoveryError(ex);
}
}
}
@ -180,47 +188,30 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -180,47 +188,30 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
discoveryClientProtocol.Dispose();
}
discoveryClientProtocol = new WebServiceDiscoveryClientProtocol();
serviceReferenceDiscoveryClient = new ServiceReferenceDiscoveryClient();
}
}
void AuthenticateUser(Uri uri, string authenticationType)
{
DiscoveryNetworkCredential credential = (DiscoveryNetworkCredential)credentialCache.GetCredential(uri, authenticationType);
if (credential != null) {
StartDiscovery(uri, credential);
} else {
using (UserCredentialsDialog credentialsForm = new UserCredentialsDialog(uri.ToString(), authenticationType)) {
// if (DialogResult.OK == credentialsForm.ShowDialog(WorkbenchSingleton.MainWin32Window)) {
// StartDiscovery(uri, credentialsForm.Credential);
// }
}
}
}
void AddCredential(Uri uri, DiscoveryNetworkCredential credential)
void DiscoveredWebServices(DiscoveryClientProtocol protocol)
{
NetworkCredential matchedCredential = credentialCache.GetCredential(uri, credential.AuthenticationType);
if (matchedCredential != null) {
credentialCache.Remove(uri, credential.AuthenticationType);
if (protocol != null) {
ServiceDescriptionCollection services = ServiceReferenceHelper.GetServiceDescriptions(protocol);
DiscoveredWebServices(services);
}
credentialCache.Add(uri, credential.AuthenticationType, credential);
}
void DiscoveredWebServices(DiscoveryClientProtocol protocol)
void DiscoveredWebServices(ServiceDescriptionCollection services)
{
if (protocol != null) {
serviceDescriptionCollection = ServiceReferenceHelper.GetServiceDescriptions(protocol);
ServiceDescriptionMessage = String.Format(
"{0} service(s) found at address {1}",
serviceDescriptionCollection.Count,
discoveryUri);
if (serviceDescriptionCollection.Count > 0) {
AddUrlToHistory(discoveryUri);
}
DefaultNameSpace = GetDefaultNamespace();
FillItems(serviceDescriptionCollection);
string referenceName = ServiceReferenceHelper.GetReferenceName(discoveryUri);
ServiceDescriptionMessage = String.Format(
"{0} service(s) found at address {1}",
services.Count,
discoveryUri);
if (services.Count > 0) {
AddUrlToHistory(discoveryUri);
}
DefaultNameSpace = GetDefaultNamespace();
FillItems(services);
string referenceName = ServiceReferenceHelper.GetReferenceName(discoveryUri);
}
void AddUrlToHistory(Uri discoveryUri)
@ -312,14 +303,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -312,14 +303,13 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
void UpdateListView()
{
ServiceDescription desc = null;
TwoValues.Clear();
if(ServiceItem.Tag is ServiceDescription) {
desc = (ServiceDescription)ServiceItem.Tag;
if (ServiceItem.Tag is ServiceDescription) {
ServiceDescription desc = (ServiceDescription)ServiceItem.Tag;
var tv = new ImageAndDescription(PresentationResourceService.GetBitmapSource("Icons.16x16.Interface"),
desc.RetrievalUrl);
TwoValues.Add(tv);
} else if(ServiceItem.Tag is PortType) {
} else if (ServiceItem.Tag is PortType) {
PortType portType = (PortType)ServiceItem.Tag;
foreach (Operation op in portType.Operations) {
TwoValues.Add(new ImageAndDescription(PresentationResourceService.GetBitmapSource("Icons.16x16.Method"),
@ -330,7 +320,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -330,7 +320,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
void FillItems(ServiceDescriptionCollection descriptions)
{
foreach(ServiceDescription element in descriptions) {
foreach (ServiceDescription element in descriptions) {
Add(element);
}
}
@ -342,7 +332,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference @@ -342,7 +332,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Dialogs.ReferenceDialog.ServiceReference
var rootNode = new ServiceItem(null, name);
rootNode.Tag = description;
foreach(Service service in description.Services) {
foreach (Service service in description.Services) {
var serviceNode = new ServiceItem(null, service.Name);
serviceNode.Tag = service;
items.Add(serviceNode);

90
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryClient.cs

@ -0,0 +1,90 @@ @@ -0,0 +1,90 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ServiceModel.Description;
namespace ICSharpCode.SharpDevelop.Gui
{
public class ServiceReferenceDiscoveryClient
{
const int DiscoveryClientsUsed = 2;
Uri discoveryUrl;
BackgroundWorker mexDiscoveryBackgroundWorker = new BackgroundWorker();
BackgroundWorker mexRelativePathDiscoveryBackgroundWorker = new BackgroundWorker();
List<Exception> errors = new List<Exception>();
public ServiceReferenceDiscoveryClient()
{
}
public event EventHandler<ServiceReferenceDiscoveryEventArgs> DiscoveryComplete;
protected virtual void OnDiscoveryComplete(ServiceReferenceDiscoveryEventArgs e)
{
if (DiscoveryComplete != null) {
DiscoveryComplete(this, e);
}
}
public void Discover(Uri url)
{
this.discoveryUrl = url;
DiscoverMexMetadata();
}
void DiscoverMexMetadata()
{
DiscoverMexMetadata(mexDiscoveryBackgroundWorker, discoveryUrl);
DiscoverMexMetadata(mexRelativePathDiscoveryBackgroundWorker, GetRelativeUrl("mex"));
}
Uri GetRelativeUrl(string relativeUrl)
{
return new Uri(GetDiscoveryUrlWithTrailingSlash(), relativeUrl);
}
Uri GetDiscoveryUrlWithTrailingSlash()
{
if (discoveryUrl.AbsoluteUri.EndsWith("/")) {
return discoveryUrl;
}
return new Uri(discoveryUrl.AbsoluteUri + "/");
}
void DiscoverMexMetadata(BackgroundWorker worker, Uri url)
{
worker.DoWork += DiscoverMexMetadata;
worker.RunWorkerCompleted += DiscoveryCompleted;
worker.RunWorkerAsync(url);
}
void DiscoverMexMetadata(object sender, DoWorkEventArgs e)
{
Uri url = (Uri)e.Argument;
var client = new MetadataExchangeClient(url, MetadataExchangeClientMode.MetadataExchange);
MetadataSet metadata = client.GetMetadata();
e.Result = new ServiceReferenceDiscoveryEventArgs(metadata);
}
void DiscoveryCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null) {
OnDiscoveryError(e.Error);
} else {
OnDiscoveryComplete((ServiceReferenceDiscoveryEventArgs)e.Result);
}
}
void OnDiscoveryError(Exception ex)
{
errors.Add(ex);
if (errors.Count == DiscoveryClientsUsed) {
OnDiscoveryComplete(new ServiceReferenceDiscoveryEventArgs(errors));
}
}
}
}

57
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/ServiceReference/ServiceReferenceDiscoveryEventArgs.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using System.ServiceModel.Description;
using System.Text;
using System.Web.Services.Description;
using WebServices = System.Web.Services.Description;
namespace ICSharpCode.SharpDevelop.Gui
{
public class ServiceReferenceDiscoveryEventArgs : EventArgs
{
ServiceDescriptionCollection services = new ServiceDescriptionCollection();
public ServiceReferenceDiscoveryEventArgs(IEnumerable<Exception> errors)
{
GenerateAggregateError(errors);
}
void GenerateAggregateError(IEnumerable<Exception> errors)
{
var message = new StringBuilder();
foreach (Exception ex in errors) {
message.AppendLine(ex.Message);
message.AppendLine();
}
Error = new AggregateException(message.ToString(), errors);
}
public ServiceReferenceDiscoveryEventArgs(MetadataSet metadata)
{
GetServices(metadata);
}
void GetServices(MetadataSet metadata)
{
foreach (MetadataSection section in metadata.MetadataSections) {
var service = section.Metadata as WebServices.ServiceDescription;
if (service != null) {
Services.Add(service);
}
}
}
public ServiceDescriptionCollection Services {
get { return services; }
}
public Exception Error { get; private set; }
public bool HasError {
get { return Error != null; }
}
}
}
Loading…
Cancel
Save