Pentaho Carte Rest Services giving 302 - pentaho

I am trying to evaluate Carte and add a job I created in the Spoon designer to a local file repository I also created.
I created the xml to add the job and wrote a test program.
The response however is always 302 - any idea how I can get past that to actually call the service ?
I have read that 302 means redirect so go grab the 'Location' header and make another call. In this case the location header again is "http://localhost:8181/kettle/addJob", and re-calling results in a further http 302 response. I seem to be stuck in a loop now ..
String fileName = "C:\\format.xml";
String url = "http://localhost:8181/kettle/addJob";
HttpClient httpClient = new HttpClient();
List authPrefs = new ArrayList();
authPrefs.add(AuthPolicy.BASIC);
httpClient.getParams().setParameter(
AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
Credentials creds = new UsernamePasswordCredentials("cluster",
"cluster");
AuthScope scope = new AuthScope("localhost", AuthScope.ANY_PORT);
httpClient.getState().setCredentials(scope, creds);
AuthPolicy.registerAuthScheme("Basic", BasicScheme.class);
PostMethod post = new PostMethod(url);
String xml = FileUtils.readFileToString(new File(fileName));
post.setRequestBody(xml);
int result = httpClient.executeMethod(post);

Related

Wicket 6 - Capturing HttpServletRequest parameters in Multipart form?

USing Wicket 6.17 and servlet 2.5, I have a form that allows file upload, and also has ReCaptcha (using Recaptcha4j). When the form has ReCaptcha without file upload, it works properly using the code:
final HttpServletRequest servletRequest = (HttpServletRequest ) ((WebRequest) getRequest()).getContainerRequest();
final String remoteAddress = servletRequest.getRemoteAddr();
final String challengeField = servletRequest.getParameter("recaptcha_challenge_field");
final String responseField = servletRequest.getParameter("recaptcha_response_field");
to get the challenge and response fields so that they can be validated.
This doesn't work when the form has the file upload because the form must be multipart for the upload to work, and so when I try to get the parameters in that fashion, it fails.
I have pursued trying to get the parameters differently using ServletFileUpload:
ServletFileUpload fileUpload = new ServletFileUpload(new DiskFileItemFactory(new FileCleaner()) );
String response = IOUtils.toString(servletRequest.getInputStream());
and
ServletFileUpload fileUpload = new ServletFileUpload(new DiskFileItemFactory(new FileCleaner()) );
List<FileItem> requests = fileUpload.parseRequest(servletRequest);
both of which always return empty.
Using Chrome's network console, I see the values that I'm looking for in the Request Payload, so I know that they are there somewhere.
Any advice on why the requests are coming back empty and how to find them would be greatly appreciated.
Update: I have also tried making the ReCaptcha component multipart and left out the file upload. The result is still the same that the response is empty, leaving me with the original conclusion about multipart form submission being the problem.
Thanks to the Wicket In Action book, I have found the solution:
MultipartServletWebRequest multiPartRequest = webRequest.newMultipartWebRequest(getMaxSize(), "ignored");
// multiPartRequest.parseFileParts(); // this is needed since Wicket 6.19.0+
IRequestParameters params = multiPartRequest.getRequestParameters();
allows me to read the values now using the getParameterValue() method.

RestSharp RestResponse is truncating content to 64 kb

Hi I am using the RestSharp to create the request to my web API. Unfortunately the response.content does not contain full response, which I am able to see when I perform request through browser or fiddler. The content is being truncated to 64 kb. I am attaching my code below.
Could you please advice what could solve this issue?
var request = new RestRequest("Products?productId={productId}&applicationId={applicationId}", Method.GET);
request.RequestFormat = DataFormat.Json;
request.AddParameter("productId", id, ParameterType.UrlSegment);
request.AddParameter("applicationId", Settings.ApplicationId, ParameterType.UrlSegment);
request.AddHeader("X-AppKey", token.AppKey);
request.AddHeader("X-Token", token.Token);
request.AddHeader("X-IsWebApi", "true");
RestResponse response = (RestResponse) client.Execute(request);
if (response.StatusCode == HttpStatusCode.Found)
{
// The following line failes because response.Content is truncated.
ShowProductModel showProductModel =
new JavaScriptSerializer().Deserialize<ShowProductModel>(response.Content);
// Do other things.
return ShowProductApi(showProductModel, q, d, sort, breadcrumb);
}
This is happening because RestSharp uses the HttpWebRequest class from the .NET Framework. This class has a static attribute called DefaultMaximumErrorResponseLength. This attribute determines the max length of an error response, and the default value for this attribute is 64Kb.
You can change the value of that atribbute before instatiating the RestRequest class.
Here's some code:
HttpWebRequest.DefaultMaximumErrorResponseLength = 1048576;
var request = new RestRequest("resource" + "/", Method.POST)
{
RequestFormat = DataFormat.Json,
JsonSerializer = new JsonSerializer()
};
That way your error response can be longer without problemns.
It looks like HttpStatusCode.Found may be causing the issue. That equates to Http Status Code 302 which is a form of redirect. I'm not entirely sure if that's necessarily the right thing to do in this case. If you have "found" the data you are looking for you should return a success level status code, e.g. 200 (Ok). Wikipedia has a list of HTTP Status Codes with summaries about what they mean and links off to lots of other resources.
I've created a little demonstrator solution (You can find it on GitHub) to show the difference. There is a WebApi server application that returns a list of values (Hex codes) and a Console client application that consumes the resources on the WebApi application.
Here is the ValuesFound resource which returns HTTP Status Code 302/Found:
public class ValuesFoundController : ApiController
{
public HttpResponseMessage Get(int count)
{
var result = Request.CreateResponse(HttpStatusCode.Found, Values.GetValues(count));
return result;
}
}
And the same again but returning the correct 200/OK response:
public class ValuesOkController : ApiController
{
public HttpResponseMessage Get(int count)
{
var result = Request.CreateResponse(HttpStatusCode.OK, Values.GetValues(count));
return result;
}
}
On the client side the important part of the code is this:
private static void ProcessRequest(int count, string resource)
{
var client = new RestClient("http://localhost:61038/api/");
var request = new RestRequest(resource+"?count={count}", Method.GET);
request.RequestFormat = DataFormat.Json;
request.AddParameter("count", count, ParameterType.UrlSegment);
RestResponse response = (RestResponse) client.Execute(request);
Console.WriteLine("Status was : {0}", response.StatusCode);
Console.WriteLine("Status code was : {0}", (int) response.StatusCode);
Console.WriteLine("Response.ContentLength is : {0}", response.ContentLength);
Console.WriteLine("Response.Content.Length is: {0}", response.Content.Length);
Console.WriteLine();
}
The count is the number of hex codes to return, and resource is the name of the resource (either ValuesOk or ValuesFound) which map to the controllers above.
The console application asks the user for a number and then shows the length of response for each HTTP Status Code. For low values, say 200, both versions return the same amount of content, but once the response content exceeds 64kb then the "Found" version gets truncated and the "Ok" version does not.
Trying the console application with a value of about 9999 demonstrates this:
How many things do you want returned?
9999
Waiting on the server...
Status was : OK
Status code was : 200
Response.ContentLength is : 109990
Response.Content.Length is: 109990
Status was : Redirect
Status code was : 302
Response.ContentLength is : 109990
Response.Content.Length is: 65536
So, why does RestSharp do this? I've no idea why it truncates content in one instance and not in the other. However, it could be assumed that in a situation where the server has asked the client to redirect to another resource location that content exceeding 64kb is unlikely to be valid.
For example, if you use Fiddler to look at what websites do, the responses in the 300 range (Redirection) such as 302/Found do have a small content payload that simply contain a little HTML so that the user can click the link to manually redirect if the browser did not automatically redirect for them. The real redirect is in the Http "Location" header.

Box.com create/update folder from salesforce using api v2

I am trying to create a new folder in the Box from a controller class in salesforce using the api version 2. I am receiving the access token and i am also been able to retrieve the items of a folder with a HTTP GET request.
But I am not able to create a new folder in BOX. Also not able to copy files from 1 folder to another or update information about a folder.
Below is the code to update the Description of my folder:
Http h = new Http();
HttpRequest req = new HttpRequest();
string endPointValue = 'https://api.box.com/2.0/folders/myfolder_id';
req.setEndpoint(endPointValue);
req.setHeader('Authorization', 'Bearer ' + myaccessToken);
req.setBody('description=' + EncodingUtil.urlEncode('New', 'U`enter code here`TF-8'));
req.setMethod('POST');
HttpResponse res = h.send(req);
I am getting the following response:
{"type":"error","status":400,"code":"bad_request","context_info":{"errors":[{"reason":"invalid_parameter","name":"entity-body","message":"Invalid value 'description=New'. Entity body should be a correctly nested resource attribute name\/value pair"}]},"help_url":"http:\/\/developers.box.com\/docs\/#errors","message":"Bad Request","request_id":"my request Id"}
Can anyone help me on this?
Thanks in advance!
According to documentation here, Box API expects request parameters in JSON format and request method has to be PUT. Try following:
Http h = new Http();
HttpRequest req = new HttpRequest();
string endPointValue = 'https://api.box.com/2.0/folders/myfolder_id';
req.setEndpoint(endPointValue);
req.setHeader('Authorization', 'Bearer ' + myaccessToken);
req.setBody('{"description" : "New folder description"}');
req.setMethod('PUT');
HttpResponse res = h.send(req);
P.S. you were also using EncodingUtil.urlEncode() method incorrectly. First parameter should be a string you are trying to make URL-safe and second parameter is encoding (see documentation here)

Issues performing a query to Solr via HttpClient using Solr 3.5 and HttpClient 4.2

I am trying to query my local Solr server using HttpClient and I cannot figure out why the parameters are not being added to the GET call.
My code for doing this is:
HttpRequestBase request = new HttpGet("http://localhost:8080/solr/select");
HttpParams params = new BasicHttpParams();
params.setParameter("q", query);
params.setParameter("start", String.valueOf(start));
params.setParameter("rows", String.valueOf(rows));
request.setParams(params);
HttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent();
return stringToStreamConversion(is); //500 error, NullPointerException, response is empty
I have tried to return several things in hopes of seeing what I would get and trying to figure out where the problem was. I have finally realized that I was only getting back the http://localhost:8080/solr/select when I returned
return request.getURI().toURL().toString();
I cannot figure out why the parameters are not getting added. If I do
return request.getQuery();
I get nothing back...any ideas? Thanks for the help in advance!
From what I have seen you are not able to associate your paeans with the request.
So, instead of creating a new HttpParams object and associating it with request, can you try the following approach ?
httpCclient.getParams().setParameter("q", query");
....
The simpler option is to use the approach I used in HTTPPostScheduler, like this:
URL url = new URL(completeUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("type", "submit");
conn.setDoOutput(true);
// Send HTTP POST
conn.connect();

IOException when making HttpWebRequest to local ASHX file

Greetings, all. Here is my situation. I am attempting to make an HttpWebRequest to a local handler file and I keep getting the following exception:
Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.
Now, I'm using a local handler file because I am writing some integration code for a third party that the site will be using. Until I have a test environment available for me to make requests to, I'm basically mocking the process with a local handler file. Here is the relevant code. Thanks.
WebRequest code (subRequest variable is object passed to the method executing this code):
XmlSerializer serializer;
XmlDocument xmlDoc = null;
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(requestUrl);
webRequest.Method = "POST";
webRequest.ContentType = "text/xml";
webRequest.KeepAlive = true;
webRequest.Accept = "*/*";
serializer = new XmlSerializer(subRequest.GetType());
XmlWriter writer = new XmlTextWriter(webRequest.GetRequestStream(), Encoding.UTF8);
serializer.Serialize(writer, subRequest);
writer.Close();
xmlDoc = new XmlDocument();
xmlDoc.Load(XmlReader.Create(webRequest.GetResponse().GetResponseStream()));
The "requestUrl" is defined as "http://localhost:2718/Handlers/MyHandler.ashx". I can hit the handler file just fine and have stepped through the code. All it does is assemble an XML response as a string and writes it out to the Response object:
context.Response.ContentType = "text/xml";
string newSubscriptionId = Utils.GetUniqueKey();
StringBuilder sb = new StringBuilder();
sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
// Assemble XML string here
context.Response.Write(sb.ToString());
As far as I can tell, this is all working just fine. But when my code hits the last line of the WebRequest chunk:
xmlDoc.Load(XmlReader.Create(webRequest.GetResponse().GetResponseStream()));
Is when the exception is thrown. Any ideas? Thanks in advance.
James
First, if you don't intend to reuse the connection or there's not going to be another request to the same schema/server/port, I would set KeepAlive to false.
The problem is that XmlDocument.Load() does not read the entire stream before the server closes the connection or that it keeps reading beyond the end and when the server keep-alive timeout is over, the connection is closed by the server. Also, you never close the response stream. To verify that this theory is correct, do something like:
// Optional -> webRequest.KeepAlive = false;
string xml = null;
using (StreamReader reader = new StreamReader (webRequest.GetResponse().GetResponseStream())) {
xml = reader.ReadToEnd ();
}
xmlDoc.LoadXml (xml);
and see if that fixes your problem.