AEM wcm.io testing Sling MockProperty name encoding issue - aem

I am experiencing an issue with the MockProperty implementation. My tests are currently failing because for some reason the ':' gets encoded to '%3A'. Why is this happening and how can I make this work?
NOTE: In my running code (outside of testing) this works all fine.
Resource resource = resourceResolver.getResource("path_to_a_valid_resource_here");
Node node = resource.adaptTo(Node.class);
PropertyIterator properties = node.getProperties();
while (properties.hasNext()){
Property property = properties.nextProperty();
String name = property.getName();
}

The returned String is UTF-8 encoded. You can obtain the decoded value it by calling String name = URLDecoder.decode(property.getName(), "UTF-8");
Why this was encoded in the first place is unknown to me, but my guess would be that the property name is treated as a URL and subsequently encoded in the ASCII set, hence the transformation of : to %3A

Related

Unable to read cookie value on client side that was set in GWT RPC

I had a GWT servelt on whose doGet method, I created a cookie as shown below:
Cookie nameCookie = new Cookie("name","adam");
response.addCookie(nameCookie);
I tried to read this on the client side as
String name = Cookies.getCookie("name");
But the output of string variable name was coming out as undefined.
I solved it by finding out that while creating a cookie, you also have to set the path for it.
So in the server side,
Cookie nameCookie = new Cookie("name","adam");
nameCookie.setPath("/");
response.addCookie(nameCookie);
Now the following client side code returns the proper value as adam
String name = Cookies.getCookie("name");

Java Rest Client - Need to add local Variable in URL

Rest client.
Can I add a local variable for value into URL string for a Rest client ?
Example
URL testurl = new URL("http://X.X.X.X:7001/lab2.local.rest1/api/v1/status/database?rxnum=1111");
The above works if I provide literal value for rxnum (i.e. 1111).
But I need rest client to utilize value of a local variable. exam
int rxvalue = 1111;
URL testurl = new URL("http://X.X.X.X:7001/lab2.local.rest1/api/v1/status/database?rxnum=+(rxvalue)+");
this doesn't work, obvious my URL string is incorrect. What is correct syntax to allow URL string to use value of local variable rxvalue?
thanks in advance
URL testurl = new URL("http://X.X.X.X:7001/lab2.local.rest1/api/v1/status/database?rxnum=" +rxvalue);
Simple String concatenation.
You are not building the URL string correctly. It is always a good idea to log url/print to be sure that you are creating the correct url. The problem lies in the way you are trying to concatenate the rxvalue, here is the correction in your code :
String urlString = "http://X.X.X.X:7001/lab2.local.rest1/api/v1/status/database?rxnum=" + rxvalue;
URL testurlWithString = new URL(urlString);
System.out.println(testurlWithString);

Spring MVC Rest, invoking using URL, escape characters & causing issue for getting the value in controller

I have a controller mapping as below
#RequestMapping(value = { "/search"}, method = RequestMethod.GET)
public #ResponseBody
Object searchProducts(#PathVariable("query") String query,
#RequestParam(value = "param1", required = false) String param1,
#RequestParam(value = "param2", required = false) String param2,)
when i use url as given below it works fine i even get the value populated by spring
http://host/app_name/search?param1=[value]&param2=[value]
But when escape character is used it breaks
http://host/app_name/search?param1=[value]&param2=[value]
Is there any configuration in springcontext or web.xml which will allow me to take care of encoding automatically ??
i have already tried setting below contect in web.xml but it does not work
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
& is an HTML escape sequence, and there are no requirements to treat it as & in URLs. Therefore it would be better to fix your internal system in order to make it generate correct URLs.
However, if you cannot do it for some reason, you can solve this problem in the following (hackish) way:
Create a Filter that would wrap original HttpServlerRequest into your subclass of HttpServlerRequestWrapper.
In that subclass create a map of "fixed" parameters (i.e. get parameters from the original request and create a new parameter map by stripping amp; from the begining of parameter names) and override getParameter*() methods to use that map.
Would make sense that Spring would treat it as part of the value, '&' is HTML encoded, not URL encoded.
I would try to figure out why the system is HTML encoding the '&' as '&' rather than building a proper GET string.
If you want to actually include an ampersand within the value of GET parameters, use %26 which decodes into '&' when passed through a URL.
Try:
HtmlUtils.htmlUnescape(query);

EntityFramework, AppHarbor and configuration variables

I'm having some trouble with EntityFramework (database first) and AppHarbor.
I'm trying to use the configuration string as inserted into the web.config by AppHarbor (I've added the metadata into the Sequelizer config option on the website), and I'm trying to add some additional values using code provided.
Currently I'm being a very bad person and embedding the string directly into my apps configuration provider - not good if the hosting provider switch DBs on us, so I'm looking to do it the proper way and use the values AppHarbor supply via the web.config.
This is the string as per provided by AppHarbor (passwords and server details removed):
metadata='res://*/MyDataEntities.csdl|res://*/MyDataEntities.ssdl|res://*/MyDataEntities.msl;';provider=System.Data.SqlClient;provider connection string='Server=servername.sequelizer.com;Database=databasename;User ID=username;Password=<snip>;'
If used "as is", that generates the following error:
The specified metadata path is not valid. A valid path must be either an existing directory, an existing file with extension '.csdl', '.ssdl', or '.msl', or a URI that identifies an embedded resource.
I then use the following code (purloined off of one of the AppHarbor support discussions) to append the required extra things EF needs...
if (String.IsNullOrWhiteSpace(ProductionDatabaseConnectionString))
{
// Get it on first read and cache it
var configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
var connectionString = configuration.ConnectionStrings.ConnectionStrings["SQLAppHarbor001"].ConnectionString;
// Add the required extra metadata for EF4.x
if (!connectionString.Contains("MultipleActiveResultSets=True;"))
connectionString += "MultipleActiveResultSets=True;";
if (!connectionString.Contains("App=EntityFramework;"))
connectionString += "App=EntityFramework;";
configuration.ConnectionStrings.ConnectionStrings["SQLAppHarbor001"].ConnectionString = connectionString;
configuration.Save();
ProductionDatabaseConnectionString = connectionString;
}
return ProductionDatabaseConnectionString;
That produces the connection string as follows:
metadata='res://*/MyDataEntities.csdl|res://*/MyDataEntities.ssdl|res://*/MyDataEntities.msl;';provider=System.Data.SqlClient;provider connection string='Server=servername.sequelizer.com;Database=databasename;User ID=username;Password=<snip>;'MultipleActiveResultSets=True;App=EntityFramework;
But that produces the error:
Format of the initialization string does not conform to specification starting at index 165.
Index 165 being the start of "provider connection string".
The working connection string I use embedded, which currently works without issue, is:
metadata='res://*/MyDataEntities.csdl|res://*/MyDataEntities.ssdl|res://*/MyDataEntities.msl;';provider=System.Data.SqlClient;provider connection string='Server=servername.sequelizer.com;Database=databasename;User ID=username;Password=<snip>;multipleactiveresultsets=True;App=EntityFramework'
The only real differences being that the "multipleactiveresultsets=True;App=EntityFramework" entries are inside the "provider connection string" string rather than outside.
Other people seem to be using EntityFramework on AppHarbor using the supplied configuration variables fine, so what an I doing wrong?
Update: Multiple Active Result Sets (MARS) can now be enabled for the injected connection string by using the Sequelizer admin panel. This is the recommended approach since the web.config no longer needs to be modified, which causes an AppDomain reload during startup
I came up against this today! I did the following:
var configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("~");
var connectionString = configuration.ConnectionStrings.ConnectionStrings["ConnStringAlias"].ConnectionString;
if (!connectionString.Contains("multipleactiveresultsets=True;"))
{
connectionString = connectionString.TrimEnd('\'');
connectionString = connectionString += "multipleactiveresultsets=True;\'";
configuration.ConnectionStrings.ConnectionStrings["ConnStringAlias"].ConnectionString = connectionString;
configuration.Save();
}
The MultipleActiveResultSets property must be inside the provider connection string, which is why you received an error regarding the format of your connection string.
I seen a few 'solutions' around but none seemed to work for me, including the solution at the bottom of a support page of how to do exactly this on AppHarbor's site. The solution provided even sends the application into an infinite loop as the application will restart every time the web.config file is saved, which is every time in the example.

How to know strong name of GWT serialization policy at the time of host page generation?

There is an excellent article describing a way to embed GWT RPC payload into the host page. A key element is missing there is how to know Strong Name of RPC serialization policy at run time.
Strong Name is computed at the compile time, put into the client and obfurscated. Strong name is sent to the server with RPC request as described here. What would you suggest to make this parameter available at the time of host page generation?
I have integrated GWT with spring with a custom SerializationPolicyProvider where I always had to rename <strong name>.gwt.rpc file and hard code the name in my custom SerializationPolicyProvider class. I got work around by looking at GWT docs. Strong Name is MD5 hash with length of 32. Each time RPC call is made to Spring based Controller's method: public String processCall(String payload), I parse the payload using following code to get strong name:
String strongName = null;
if(payload!=null){
StringTokenizer tokens = new StringTokenizer(payload,String.valueOf(AbstractSerializationStream.RPC_SEPARATOR_CHAR));
while(tokens.hasMoreTokens()){
String s = tokens.nextToken();
if(s.length() == 32){
strongName = s;
break;
}
}
}
Then in your SerializationPolicyProvider impl class use following:
to get SerializationPolicy:
return SerializationPolicyLoader.loadFromStream(servletContext.getResourceAsStream(moduleBaseURL+"/"+strongName+"gwt.rpc");
One solution seems to be using compiler -gen option. Get _Proxy.java from compiler output and extract SERIALIZATION_POLICY from it.