Skip to content

Commit

Permalink
better SOAP fault handling. timeout for soap requests
Browse files Browse the repository at this point in the history
  • Loading branch information
goenning committed Nov 3, 2014
1 parent 8723274 commit 9f35e4f
Show file tree
Hide file tree
Showing 14 changed files with 177 additions and 16 deletions.
4 changes: 2 additions & 2 deletions src/base/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.1")]
[assembly: AssemblyFileVersion("2.0.1")]
[assembly: AssemblyVersion("2.0.2")]
[assembly: AssemblyFileVersion("2.0.2")]
1 change: 1 addition & 0 deletions src/base/SapRfcConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public abstract class SapRfcConnection : IDisposable
protected abstract RfcStructureMapper GetStructureMapper();
public abstract RfcPreparedFunction PrepareFunction(string functionName);
public abstract void Dispose();
public abstract void SetTimeout(int timeout);

public RfcResult ExecuteFunction(string functionName)
{
Expand Down
18 changes: 15 additions & 3 deletions src/plain/PlainSapRfcConnection.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using SAP.Middleware.Connector;
using System;

namespace SharpSapRfc.Plain
{
Expand Down Expand Up @@ -31,9 +32,15 @@ private void EnsureConnectionIsOpen()
{
if (!_isOpen)
{
this._destination = RfcDestinationManager.GetDestination(_destinationName);
this._repository = this._destination.Repository;
this._isOpen = true;
try {
this._destination = RfcDestinationManager.GetDestination(_destinationName);
this._repository = this._destination.Repository;
this._isOpen = true;
}
catch (Exception ex)
{
throw new SharpRfcException("Could not connect to SAP.", ex);
}
}
}

Expand All @@ -58,5 +65,10 @@ protected override RfcStructureMapper GetStructureMapper()
{
return this._structureMapper;
}

public override void SetTimeout(int timeout)
{
//there is no timeout for plain rfc
}
}
}
4 changes: 2 additions & 2 deletions src/plain/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.0")]
[assembly: AssemblyFileVersion("2.0.0")]
[assembly: AssemblyVersion("2.0.2")]
[assembly: AssemblyFileVersion("2.0.2")]
16 changes: 14 additions & 2 deletions src/soap/Configuration/SapSoapRfcDestinationElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,28 @@ public string Client
get { return this["client"] as string; }
}

[ConfigurationProperty("user", IsRequired = false)]
[ConfigurationProperty("user", IsRequired = true)]
public string User
{
get { return this["user"] as string; }
}

[ConfigurationProperty("password", IsRequired = false)]
[ConfigurationProperty("password", IsRequired = true)]
public string Password
{
get { return this["password"] as string; }
}

[ConfigurationProperty("timeout", IsRequired = false, DefaultValue=30000)]
public int Timeout
{
get { return (int)this["timeout"]; }
set { this["timeout"] = value; }
}

public override bool IsReadOnly()
{
return false;
}
}
}
4 changes: 2 additions & 2 deletions src/soap/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.0.1")]
[assembly: AssemblyFileVersion("2.0.1")]
[assembly: AssemblyVersion("2.0.2")]
[assembly: AssemblyFileVersion("2.0.2")]
10 changes: 10 additions & 0 deletions src/soap/SoapRfcPreparedFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,16 @@ public override RfcResult Execute()
throw new SharpRfcException(errorMessage);
}

var soapFaultTag = responseXml.GetElementsByTagName("SOAP-ENV:Fault");
if (soapFaultTag.Count > 0)
{
string faultstring = soapFaultTag[0].SelectSingleNode("faultstring").InnerText;
string detail = soapFaultTag[0].SelectSingleNode("detail").InnerText;
string requestBody = body.InnerXml.ToString();
string errorMessage = string.Format("Fault: {0} Detail: {1} Request Body: {2}", faultstring, detail, requestBody);
throw new SharpRfcException(errorMessage);
}

throw new Exception("Could not fetch response tag.");
}

Expand Down
4 changes: 4 additions & 0 deletions src/soap/SoapRfcWebClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ private XmlDocument ResponseToXml(HttpWebRequest request)
responseXml.Load(rd);
}

if (ex.Status == WebExceptionStatus.Timeout)
throw new TimeoutException(string.Format("Timeout on function call. Current timeout is {0} milliseconds.", request.Timeout));

if (responseXml.InnerXml.Length == 0)
throw ex;
}
Expand All @@ -78,6 +81,7 @@ private HttpWebRequest CreateRequest(string baseUrl, string functionName, string
request.ContentType = "text/xml; charset=\"UTF-8\"";
request.Accept = "text/xml";
request.Method = httpMethod;
request.Timeout = this.destination.Timeout;
request.KeepAlive = false;
request.PreAuthenticate = true;
request.Credentials = new NetworkCredential(this.destination.User, this.destination.Password);
Expand Down
5 changes: 5 additions & 0 deletions src/soap/SoapSapRfcConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,10 @@ protected override RfcStructureMapper GetStructureMapper()
{
return this._structureMapper;
}

public override void SetTimeout(int timeout)
{
this.Destination.Timeout = timeout;
}
}
}
17 changes: 14 additions & 3 deletions tests/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,27 @@
rfcUrl="http://sap-vm:8000/sap/bc/soap/rfc"
wsdlUrl="http://sap-vm:8000/sap/bc/soap/wsdl"
client="001"
user="bcuser"
password="sapadmin2"/>
user="rfc_super"
password="rfcsuper1"
timeout="5000"/>

<add name="TST_DENY_ACCESS-SOAP"
rfcUrl="http://sap-vm:8000/sap/bc/soap/rfc"
wsdlUrl="http://sap-vm:8000/sap/bc/soap/wsdl"
client="001"
user="rfc_deny"
password="rfcdeny1"
timeout="5000"/>
</destinations>
</sapSoapRfc>

<SAP.Middleware.Connector>
<ClientSettings>
<DestinationConfiguration>
<destinations >
<add NAME="TST" USER="bcuser" PASSWD="sapadmin2" CLIENT="001"
<add NAME="TST" USER="rfc_super" PASSWD="rfcsuper1" CLIENT="001"
LANG="EN" ASHOST="sap-vm" SYSNR="00" />
<add NAME="TST_DENY_ACCESS" USER="rfc_deny" PASSWD="rfcdeny1" CLIENT="001"
LANG="EN" ASHOST="sap-vm" SYSNR="00" />
</destinations>
</DestinationConfiguration>
Expand Down
2 changes: 2 additions & 0 deletions tests/SharpSapRfc.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
<Compile Include="Extension\ImageAssert.cs" />
<Compile Include="Mapper\AbapValueMapperFromRemoteExceptionTestData.cs" />
<Compile Include="Mapper\AbapValueMapperToRemoteTestData.cs" />
<Compile Include="TestCases\AccessDeniedTestCase.cs" />
<Compile Include="TestCases\Soap_AbapValueMapperTestCase.cs" />
<Compile Include="TestCases\Plain_AbapValueMapperTestCase.cs" />
<Compile Include="Metadata\FunctionMetadataTestCase.cs" />
Expand All @@ -135,6 +136,7 @@
<Compile Include="TestCases\SoapConfigurationSectionTestCase.cs" />
<Compile Include="TestCases\StructureTestCase.cs" />
<Compile Include="Model\ZCustomer.cs" />
<Compile Include="TestCases\TimeoutTestCase.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
Expand Down
45 changes: 45 additions & 0 deletions tests/TestCases/AccessDeniedTestCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using SharpSapRfc.Plain;
using SharpSapRfc.Soap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace SharpSapRfc.Test.TestCases
{
public class Soap_AccessDeniedTestCase : AccessDeniedTestCase
{
protected override SapRfcConnection GetConnection()
{
return new SoapSapRfcConnection("TST_DENY_ACCESS-SOAP");
}
}

public class Plain_AccessDeniedTestCase : AccessDeniedTestCase
{
protected override SapRfcConnection GetConnection()
{
return new PlainSapRfcConnection("TST_DENY_ACCESS");
}
}

public abstract class AccessDeniedTestCase
{
protected abstract SapRfcConnection GetConnection();

[Fact]
public void ShouldNotExecuteFunctionBecauseItIsNotAllowed()
{
using (SapRfcConnection conn = this.GetConnection())
{
Assert.Throws<SharpRfcException>(() => {
var result = conn.ExecuteFunction("Z_SSRT_SUM",
new RfcParameter("i_num1", 2),
new RfcParameter("i_num2", 4)
);
});
}
}
}
}
5 changes: 3 additions & 2 deletions tests/TestCases/SoapConfigurationSectionTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ public void ParametersCanBeRead()
Assert.Equal("http://sap-vm:8000/sap/bc/soap/rfc", destination.RfcUrl);
Assert.Equal("http://sap-vm:8000/sap/bc/soap/wsdl", destination.WsdlUrl);
Assert.Equal("001", destination.Client);
Assert.Equal("bcuser", destination.User);
Assert.Equal("sapadmin2", destination.Password);
Assert.Equal("rfc_super", destination.User);
Assert.Equal("rfcsuper1", destination.Password);
Assert.Equal(5000, destination.Timeout);
}
}
}
58 changes: 58 additions & 0 deletions tests/TestCases/TimeoutTestCase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using SharpSapRfc.Plain;
using SharpSapRfc.Soap;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;

namespace SharpSapRfc.Test.TestCases
{
public class Soap_TimeoutTestCase : TimeoutTestCase
{
protected override SapRfcConnection GetConnection()
{
return new SoapSapRfcConnection("TST-SOAP");
}

[Fact]
public void ShouldThrowTimeoutException()
{
using (SapRfcConnection conn = this.GetConnection())
{
Assert.Throws<TimeoutException>(() =>
{
var result = conn.ExecuteFunction("Z_SSRT_LONG_PROCESS", new
{
i_seconds = 6
});
});
}
}
}

public class Plain_TimeoutTestCase : TimeoutTestCase
{
protected override SapRfcConnection GetConnection()
{
return new PlainSapRfcConnection("TST");
}
}

public abstract class TimeoutTestCase
{
protected abstract SapRfcConnection GetConnection();

[Fact]
public void ShouldNotThrowTimeoutException()
{
using (SapRfcConnection conn = this.GetConnection())
{
var result = conn.ExecuteFunction("Z_SSRT_LONG_PROCESS", new
{
i_seconds = 1
});
}
}
}
}

0 comments on commit 9f35e4f

Please sign in to comment.