Azure Load test does not report data driven urls - visual-studio

I have a simple load test that basically executes a single webtest on a constant load. That webtest is hooked to an xml file data source that contains urls to my entire site.
When I execute the load test from my local environment, the test summary page reports the individual urls in the "Top 5 slowest pages" i.e. "https://mysite.or/page" . But when I execute the same test from Azure (i.e. changed Test run location to VSTS in .testsettings), the links are reported as "https://{{Enviroment}}{{Sitemap.url.loc}}". This seems to be just a reporting issue and I can validate that azure is correctly invoking the urls from the data source. Why would the tests from Azure not report the url constructed from the datasource?
Load Test Summary: Executed from Local
Same test executed on Azure
Webtest:
<?xml version="1.0" encoding="utf-8"?>
<WebTest Name="GenericSitemap" Id="02954e81-f3a7-4c9c-94f5-3a4304f88361" Owner="" Priority="2147483647" Enabled="True" CssProjectStructure="" CssIteration="" Timeout="0" WorkItemIds="" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010" Description="" CredentialUserName="" CredentialPassword="" PreAuthenticate="True" Proxy="default" StopOnError="False" RecordedResultFile="" ResultsLocale="">
<Items>
<Request Method="GET" Guid="01c37ffa-92db-42e8-9d25-a042dcd0123d" Version="1.1" Url="https://{{Enviroment}}{{Sitemap.url.loc}}" ThinkTime="0" Timeout="300" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8" ExpectedHttpStatusCode="0" ExpectedResponseUrl="https://{{Enviroment}}{{Sitemap.url.loc}}" ReportingName="" IgnoreHttpStatusCode="False" />
</Items>
<DataSources>
<DataSource Name="Sitemap" Provider="Microsoft.VisualStudio.TestTools.DataSource.XML" Connection="|DataDirectory|\..\Data\sitemap.xml">
<Tables>
<DataSourceTable Name="url" SelectColumns="SelectOnlyBoundColumns" AccessMethod="Random" />
</Tables>
</DataSource>
</DataSources>
<ContextParameters>
<ContextParameter Name="Enviroment" Value="mysite.net" />
</ContextParameters>
</WebTest>

Thanks to #AdrianHHH. I got it working by creating a requestPlugin and setting it on the data driven requests.
Here's my plugin:
[DisplayName("Set Request Params")]
[Description("Fix request urls when run from Azure")]
public class SetRequestParams : WebTestRequestPlugin
{
public override void PreRequest(object sender, PreRequestEventArgs e)
{
e.Request.ReportingName = e.Request.Url;
}
}

Related

Sending a PDF file in a REST Message

I am trying figure this out any help appreciated. Thanks in advance
The service is a file passthrough that picks up a PDF and then uses the BPL code below to create the rest wrapper and sends the stream data. I am not grabbing the stream from the inbound correctly, "request.Stream" or "request.StreamFC" always produces the following error.
Here is what is sent and returned in the message..
request:
*
<Stream>
15#%Library.FileCharacterStream
</Stream>
response:
<Stream>
Unable to load xml from message: Data at the root level is invalid. Line 1, position 1.
</Stream>
-I think my issue is I am not using the right class by using "%GlobalStreamCharacter", Or the raw PDF CDATA inbound I am not handling correctly
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
I have tried using different Stream types...File, Binary....but no luck
-The general BPL below
/// BPL Definition
X
Data BPL [ XMLNamespace = "http://www.intersystems.com/bpl" ]
{
<process language='objectscript' request='Ens.StreamContainer' response='Ens.Response'
height='2000' width='2000' >
<context>
.....
.....
....
<code name='Create REST Message' xpos='200' ypos='250' >
<![CDATA[
set context.RESTMessage=##class(EnsLib.HTTP.GenericMessage).%New()
set context.RESTMessage.Stream=##class(%GlobalCharacterStream).%New()
set tSC=context.RESTMessage.Stream.Write(request.StreamFC)
set tSC=context.RESTMessage.HTTPHeaders.SetAt("application/xml","Content-Type")
set tSC=context.RESTMessage.HTTPHeaders.SetAt(context.RESTMessage.Stream.Size,"Content-
Length")
set tSC=context.RESTMessage.HTTPHeaders.SetAt("POST","HttpRequest")
]]>
</code>
You can try this code snippet. I got the answer in the community.
<call name='To application Rest' target='To application REST' async='0'>
<request type='EnsLib.REST.GenericMessage' >
<assign property="callrequest.Stream" value='##class(%Stream.GlobalCharacter).%New()'/>
<assign property="status" value='callrequest.Stream.CopyFrom(request.StreamFC)' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("application/xml", "Content-Type")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt(callrequest.Stream.Size, "Content-Length")' action="set" />
<assign property="status" value='callrequest.HTTPHeaders.SetAt("POST", "HttpRequest")' action="set" />
</request>
</call>

WSO2 websocket + SockJS - Cross origin requests blocked

Since WSO2 5.0 supports WebSockets, I have written a simple app following by tutorials:
WebSocket Transport
Sending a Message from a WebSocket Client to an HTTP Endpoint
Here's my source view output from WSO2:
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://ws.apache.org/ns/synapse">
<registry provider="org.wso2.carbon.mediation.registry.WSO2Registry">
<parameter name="cachableDuration">15000</parameter>
</registry>
<taskManager provider="org.wso2.carbon.mediation.ntask.NTaskTaskManager"/>
<sequence name="fault">
<!-- Log the message at the full log level with the ERROR_MESSAGE and the ERROR_CODE-->
<log level="full">
<property name="MESSAGE" value="Executing default 'fault' sequence"/>
<property expression="get-property('ERROR_CODE')" name="ERROR_CODE"/>
<property expression="get-property('ERROR_MESSAGE')" name="ERROR_MESSAGE"/>
</log>
<!-- Drops the messages by default if there is a fault -->
<drop/>
</sequence>
<sequence name="main">
<in>
<!-- Log all messages passing through -->
<log level="full"/>
<!-- ensure that the default configuration only sends if it is one of samples -->
<!-- Otherwise Synapse would be an open proxy by default (BAD!) -->
<filter regex="http://localhost:9000.*" source="get-property('To')">
<!-- Send the messages where they have been sent (i.e. implicit "To" EPR) -->
<send/>
</filter>
</in>
<out>
<send/>
</out>
<description>The main sequence for the message mediation</description>
</sequence>
<sequence name="outDispatchSeq">
<log level="full"/>
<respond/>
</sequence>
<sequence name="dispatchSeq">
<switch
source="get-property('websocket.source.handshake.present')" xmlns:ns="http://org.apache.synapse/xsd">
<case regex="true">
<drop/>
</case>
<default>
<call/>
<respond/>
</default>
</switch>
</sequence>
<!-- You can add any flat sequences, endpoints, etc.. to this synapse.xml file if you do
*not* want to keep the artifacts in several files -->
<inboundEndpoint name="test" onError="fault" protocol="ws"
sequence="dispatchSeq" suspend="false">
<parameters>
<parameter name="inbound.ws.port">9091</parameter>
<parameter name="ws.client.side.broadcast.level">0</parameter>
<parameter name="ws.outflow.dispatch.sequence">outDispatchSeq</parameter>
<parameter name="ws.outflow.dispatch.fault.sequence">fault</parameter>
</parameters>
</inboundEndpoint>
</definitions>
I was able to successfully test it with Nett client:
C:\work\servers\netty>java -Durl=ws://localhost:9091/websocket -DsubProtocol="synapse(contentType='application/xml')" -cp netty-example-4.1.4.Final.jar;lib/*;. io.netty.example.http.websocketx.client.WebSocketClient
WebSocket Client connected!
However if I try to test it from JavaScript code I am getting error like:
Do you know what is wrong in my code?
This issue occurs because SockJS internally trying to load the URL using XMLHttpRequest, but Chrome does not allow accessing cross origin content unless the protocol is one of the aforementioned protocols (In this case it is ws://). I have tried a similar scenario with Firefox and it works fine since it doesn't have this Chrome specific limitation.
In this scenario since WSO2 ESB exposes a WebSocket interface to invoke the HTTP Endpoint, you can use native HTML5 WebSocket implementation as follows.
var url = 'ws://localhost:9091/websocket';
var ws = new WebSocket(url);
ws.onopen = function() {
// todo
}
ws.onmessage = function(e) {
// todo
}

Spring Webflow - Prevent subflow being accessed directly

I'm using Spring Web Flow in my webapp and i would like to know if there is a general way to prevent some subflows to be accessed directly. These subflows are meant to be accessed just from certain flows, not directly by the url, so in these subflows i would like to check "if i was called from a flow".
is there any mechanisms to achieve it? I was looking at spring security but i couldn't find any useful feature to make this kind of restriction.
Thanks you!
You can check this by using input mapper attribute as shown below. Suppose you have a parent flow which invokes 'subflow-flow'. You need to pass an input value containing the name of the parent flow as:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd">
...
<subflow-state id="subflow-flow" subflow="subflow-flow">
<!--flowInitiatedBy should be different for each different parent flow-->
<input name="flowInitiatedBy" value="'parentFlowName'"/>
<transition on="invalidAccess" to="someViewWithMessage"/>
<transition on="processedSubflow" to="someOtherState"/>
</subflow-state>
...
</flow>
Then in subflow you can retrieve the parentflowname and perform the check in yourAction class. You can define subflow as:
<?xml version="1.0" encoding="UTF-8"?>
<flow xmlns="http://www.springframework.org/schema/webflow"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/webflow
http://www.springframework.org/schema/webflow/spring-webflow-2.0.xsd"
start-state="start">
<input name="flowInitiatedBy" type="java.lang.String"/>
<action-state id="start">
<evaluate expression="yourAction.checkAccessibility(flowRequestContext)"/>
<transition on="invalidAccess" to="verifyWhetherDraftsExists"/>
<transition on="continue" to="continueToState"/>
</action-state>
<!--define other states for continue transition -->
...
<end-state id="invalidAccess"/>
<end-state id="processedSubflow"/>
</flow>
In your action class:
public class YourAction{
...
public String checkAccessibility(RequestContext context){
String flowInitiatedBy = context.getFlowScope().get("flowInitiatedBy");
//flowInitiatedBy will be empty if initiated by url.
if(flowInitiatedBy is empty){
return "invalidAccess";
}else{
// dosomething
return "continue";
}
}
...
}
Hope this helps.
I also wish there was some kind of built-in, simple mechanism. However, I just did this a slightly different way I thought I'd share. That is, since my Subflow knows its own name, I just had the first state in the Flow configuration check whether or not the Flow ID (name) matches that hardcoded name:
<decision-state id="subOnly">
<if test="flowExecutionContext.definition.id == 'thisSubflowFlowName'" then="invalidAccess" else="mySubflowFirstState"/>
</decision-state>
Where "invalidAccess" is an end-state like the prior answer shows.

How to consume wcf service running as windows service in ajax client

I have created a WCF service and it is hosted in windows service. When I have added a web reference to that service to an asp.net web forms project through right client menu in the solution explorer I am able to access the service and add reference to it.
Now I want to access this service through AJAX client (i.e in ASP.NET project through ScriptManager component)and call the service in a timer to get continuous stream of values.
I have never worked on AJAX or web that much, I did not find an suitable example on net on this.
I'm using WSHttpBinding.
I'm posting my code so that you can tell where I'm doing wrong.
WCF Service Library Code:
ITestService.cs code....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace TestServiceLibrary
{
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in App.config.
[ServiceContract(Namespace="TestServiceLibrary")]
public interface ITestService
{
[OperationContract]
[WebGet]
double Add(double n1, double n2);
// TODO: Add your service operations here
}
}
TestService.cs code...............
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace TestServiceLibrary
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in App.config.
public class TestService : ITestService
{
public double Add(double n1, double n2)
{
return n1 + n2;
}
}
}
TestServiceHost.cs (code of console application)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using TestServiceLibrary;
namespace TestServiceHost
{
class Program
{
static void Main(string[] args)
{
ServiceHost myhost = new ServiceHost(typeof(TestService));
myhost.Open();
while (System.Console.ReadKey().Key != System.ConsoleKey.Enter)
{
//System.Threading.Thread.Sleep(100);
}
myhost.Close();
}
}
}
XML Configuration of app.config... same in both wcf service library and wcf service host(console application in this case..)
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true" />
</system.web>
<!-- When deploying the service library project, the content of the config file must be added to the host's
app.config file. System.Configuration does not support config files for libraries. -->
<system.serviceModel>
<services>
<service name="TestServiceLibrary.TestService" behaviorConfiguration="TestServiceLibrary.Service1Behavior">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8731/TestServiceLibrary/TestService/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- Unless fully qualified, address is relative to base address supplied above -->
<endpoint name="TestService_wsHttpBinding" address ="" binding="wsHttpBinding" contract="TestServiceLibrary.ITestService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- The Metadata Exchange endpoint is used by the service to describe itself to clients. -->
<!-- This endpoint does not use a secure binding and should be secured or removed before deployment -->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="TestServiceLibrary.Service1Behavior">
<!-- To avoid disclosing metadata information,
set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="True"/>
<!-- To receive exception details in faults for debugging purposes,
set the value below to true. Set to false before deployment
to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
Web Client (asp.net client, default.aspx) code...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Simple AJAX Service Client Page</title>
<script type="text/javascript">
// <![CDATA[
// This function creates an asynchronous call to the service
function makeCall(operation){
var n1 = document.getElementById("num1").value;
var n2 = document.getElementById("num2").value;
// If user filled out these fields, call the service
if(n1 && n2){
// Instantiate a service proxy
var proxy = new TestServiceLibrary.ITestService();
// Call correct operation on proxy
switch(operation){
case "Add":
proxy.Add(parseFloat(n1), parseFloat(n2), onSuccess, onFail, null);
break;
}
}
}
// This function is called when the result from the service call is received
function onSuccess(mathResult){
document.getElementById("result").value = mathResult;
}
// This function is called if the service call fails
function onFail(){
document.getElementById("result").value = "Error";
}
// ]]>
</script>
</head>
<body>
<h1>
Simple AJAX Service Client Page</h1>
<p>
First Number:
<input type="text" id="num1" /></p>
<p>
Second Number:
<input type="text" id="num2" /></p>
<input id="btnAdd" type="button" onclick="return makeCall('Add');" value="Add" />
<p>
Result:
<input type="text" id="result" /></p>
<form id="mathForm" action="" runat="server">
<asp:ScriptManager ID="ScriptManager" runat="server">
<Services>
<asp:ServiceReference Path="http://localhost:8732/TestServiceLibrary/TestService/" />
</Services>
</asp:ScriptManager>
</form>
</body>
</html>
The error Im getting when accessing the webservice through asp.net in ajax is Microsoft JScript runtime error: 'TestServiceLibrary' is undefined
Please go through this code and help me in finding the problem. Thank you all for your responses.
Looks like the problem is with my service hosting and the endpoint i'm using.
I should modified my service hosting in the console application to use WebServiceHost instead of ServiceHost, then only the ajax clients can talk to my service. Instead of wsHttpBinding, I should use webHttpBinding.
So the code for webHosting is as follows.
using (var host = new WebServiceHost(
typeof(TestService)))
{
// Start listening for messages
host.Open();
Console.WriteLine("Press any key to stop the service.");
Console.ReadKey();
// Close the service
host.Close();
}
The xml configuration of my console is
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<services>
<service
name="TestServiceLibrary.TestService"
behaviorConfiguration="">
<endpoint address="http://localhost:8732/TestService"
binding="webHttpBinding"
bindingConfiguration=""
name="TestService_WebHttp"
contract="TestServiceLibrary.ITestService" />
</service>
</services>
</system.serviceModel>
</configuration>
Now when I did this changes I'm able to call my service through ie using the following url in ie http://localhost:8732/TestService/Add?n1=20&n2=20 and result returned by it is as follows <double xmlns="http://schemas.microsoft.com/2003/10/Serialization/">40</double>
Finally i found the solution to my problem. Im using JSON as way of communicating data and the script for receiving the data is as follows:
<script type="text/javascript">
$("#mybutton").click(function () {
$.getJSON("http://localhost:8732/TestService/Add", null, function (result) {
});
});
</script>
Use some tool like firebug to determine what is happening with the request. WSHttpBinding is secure by default. Check your security settings. Try first with no security to make sure it is not a security issue.
Have you attempted to connect to the service from the AJAX client yet? If so, are you getting any errors?
Without seeing code, there could be a number of things as Chandermani has said.
I've not done AJAX with WCF, but looking over the article Preet recommended, I would suggest checking (if you haven't already) that your AJAX client has the necessary code as per the article.
Are your service operations decorated with [WebGet]?
Do you have the config file for the AJAX client set up properly? Is the service's config file set up properly?

Why does MVC sitemap hide menu items where actions exist on the controller?

I'm using MVC sitemap for MVC3 but having problems with it.
Consider the following sitemap file:
<?xml version="1.0" encoding="utf-8" ?>
<mvcSiteMap xmlns="http://mvcsitemap.codeplex.com/schemas/MvcSiteMap-File-3.0" enableLocalization="true">
<mvcSiteMapNode title="Home" controller="Home" action="Index" changeFrequency="Always" updatePriority="Normal" Description="Test HOME">
<mvcSiteMapNode title="Today" controller="Dashboard" action="Today" />
<mvcSiteMapNode title="Today1" controller="Dashboard" action="Today1" />
<mvcSiteMapNode title="Today2" controller="Dashboard" action="Today2" />
<mvcSiteMapNode title="Today3" controller="Dashboard" action="Today3" />
<mvcSiteMapNode title="Today4" controller="Dashboard" action="Today4" />
</mvcSiteMapNode>
</mvcSiteMap>
When I load my web page up I only get the following options:
Today1, Today2, Today3, Today4
But Today is not displayed. This is an action on a controller whereas the other actions don't exist. Why is it hiding the item which actually exists on the controller? I took off authorization on the controller to rule out it had anything to do with authorization but still same effect.
This is the sitemap config (set in web.config):
<siteMap defaultProvider="MvcSiteMapProvider" enabled="true">
<providers>
<clear />
<add name="MvcSiteMapProvider"
type="MvcSiteMapProvider.DefaultSiteMapProvider, MvcSiteMapProvider"
siteMapFile="~/Mvc.Sitemap"
securityTrimmingEnabled="true"
cacheDuration="5"
enableLocalization="true"
scanAssembliesForSiteMapNodes="false"
includeAssembliesForScan=""
excludeAssembliesForScan=""
attributesToIgnore="visibility"
nodeKeyGenerator="MvcSiteMapProvider.DefaultNodeKeyGenerator, MvcSiteMapProvider"
controllerTypeResolver="MvcSiteMapProvider.DefaultControllerTypeResolver, MvcSiteMapProvider"
actionMethodParameterResolver="MvcSiteMapProvider.DefaultActionMethodParameterResolver, MvcSiteMapProvider"
aclModule="MvcSiteMapProvider.DefaultAclModule, MvcSiteMapProvider"
siteMapNodeUrlResolver="MvcSiteMapProvider.DefaultSiteMapNodeUrlResolver, MvcSiteMapProvider"
siteMapNodeVisibilityProvider="MvcSiteMapProvider.DefaultSiteMapNodeVisibilityProvider, MvcSiteMapProvider"
siteMapProviderEventHandler="MvcSiteMapProvider.DefaultSiteMapProviderEventHandler, MvcSiteMapProvider" />
</providers>
</siteMap>
</system.web>
I find out the problem.
The HttpContext user's InRole() method is used in the MvcSiteMapProvider.DefaultAclModule within the library code.
I am using Forms Authentication which means the InRole will never work as the roles property on the user context is not set (it doesn't know how roles are applied).
I could either write my own aclmodule provider which checks the authentication ticket for the roles stored within the ticket, or alternatively for every authentication request event in global.asax, set the context with the roles set. In the end I chose the latter:
e.g.
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity formsId = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = formsId.Ticket;
// need to do this so MVC sitemap IsInRole works inside default acl module: MvcSiteMapProvider.DefaultAclModule
var authData = new AuthenticationModel(ticket.UserData);
var roles = new List<string>(authData.EffectiveRoles).ToArray();
HttpContext.Current.User = new GenericPrincipal(formsId, roles);
}
}
}
#jaffa, your approach helped me !! thanks. Here, is how I implemented it.. maybe it can help others too!
public class MenuVisibilityController : Controller, ISiteMapNodeVisibilityProvider
{
public bool IsVisible(SiteMapNode Node, HttpContext context, IDictionary<string, object> sourceMetadata)
{
return context.User.Identity.IsAuthenticated;
}
}
Implemented Visibility Provider for MVC sitemap and then used it for visibility of a particular node like below:
<mvcSiteMapNode title="Test Menu" controller="Account" action="Index" visibilityProvider="MyProject.Controllers.MenuVisibilityController, MyProject">
<mvcSiteMapNode title="Test Item 1" controller="Account" action="GetItems" />
</mvcSiteMapNode>
specifying implemented controller in VisibilityProvider should serve the purpose.

Resources