Peoplecode - how to create cookies? - cookies

We are trying to create a cookie in the PeopleSoft Peoplecode by using the %Response object.
However, the code we tried is failing.
&YourCookie = %Response.AddCookie("YourCookieName", "LR");
Another snippet we tried to create the cookie
Local object &Response = %Response;
Local object &YourCookie;
&YourCookie = &Response.CreateCookie("YourCookieName");
&YourCookie.Domain = %Request.AuthTokenDomain;
&YourCookie.MaxAge = -1; /* Makes this a session cookie (default) */
&YourCookie.Path = "/";
&YourCookie.Secure = True; /* Set to true if using https (will still work with http) */
&YourCookie.Value = "Set the cookie value here. Encrypt sensitive information.";
The document reference points to IScript functions called CreateCookie methods etc.
http://docs.oracle.com/cd/E15645_01/pt850pbr0/eng/psbooks/tpcr/chapter.htm?File=tpcr/htm/tpcr21.htm
However, these don't work in Peoplecode. We don't have the knowledge to create IScript or use it. Any insight with the People code API for cookies or IScript is much appreciated.

I just tested on PeopleTools 8.54.11 and was able to create a cookie using the snippet you provided above.
I did find I had an issue if I set
&YourCookie.Secure = True;
in an environment where I was using HTTP.
If you set Secure to False the cookie will be available in both HTTP and HTTPS
if you set Secure to True the cookie is only available in HTTPS
PeopleTools 8.54 Documentation showing the CreateCookie method

I have been trying to do this (same code snippet) from within signon peoplecode, tools release is 8.54.09. I can execute the first two lines of code, but as soon as the line of code executing the CreateCookie() method executes, I get tossed out / end up on the signon error page.
This seems to support the previous answer saying that the API has removed the method, but the answer before that says it has been successful on tools 8.54.11 -- does that mean they removed it, then put it back, and I happen to be stuck with a release where it was removed? :-/

Related

How to specify the database in an ArangoDb AQL query?

If have multiple databases defined on a particular ArangoDB server, how do I specify the database I'd like an AQL query to run against?
Running the query through the REST endpoint that includes the db name (substituted into [DBNAME] below) ie:
/_db/[DBNAME]/_api/cursor
doesn't seem to work. The error message says 'unknown path /_db/[DBNAME]/_api/cursor'
Is this something I have to specify in the query itself?
Also: The query I'm trying to run is:
FOR col in COLLECTIONS() RETURN col.name
Fwiw, I haven't found a way to set the "current" database through the REST API. Also, I'm accessing the REST API from C++ using fuerte.
Tom Regner deserves primary credit here for prompting the enquiry that produced this answer. I am posting my findings here as an answer to help others who might run into this.
I don't know if this is a fuerte bug, shortcoming or just an api caveat that wasn't clear to me... BUT...
In order for the '/_db/[DBNAME/' prefix in an endpoint (eg full endpoint '/_db/[DBNAME/_api/cursor') to be registered and used in the header of a ::arangodb::fuerte::Request, it is NOT sufficient (as of arangodb 3.5.3 and the fuerte version available at the time of this answer) to simply call:
std::unique_ptr<fuerte::Request> request;
const char *endpoint = "/_db/[DBNAME/_api/cursor";
request = fuerte::createRequest(fuerte::RestVerb::Post,endpoint);
// and adding any arguments to the request using a VPackBuilder...
// in this case the query (omitted)
To have the database name included as part of such a request, you must additionally call the following:
request->header.parseArangoPath(endpoint);
Failure to do so seems to result in an error about an 'unknown path'.
Note 1: Simply setting the database member variable, ie
request->header.database = "[DBNAME]";
does not work.
Note 2: that operations without the leading '/_db/[DBNAME]/' prefix, seem to work fine using the 'current' database. (which at least for me, seems to be stuck at '_system' since as far as I can tell, there doesn't seem to be an endpoint to change this via the HTTP REST Api.)
The docs aren't very helpful right now, so just incase someone is looking for a more complete example, then please consider the following code.
EventLoopService eventLoopService;
// adjust the connection for your environment!
std::shared_ptr<Connection> conn = ConnectionBuilder().endpoint("http://localhost:8529")
.authenticationType(AuthenticationType::Basic)
.user(?) // enter a user with access
.password(?) // enter the password
.connect(eventLoopService);
// create the request
std::unique_ptr<Request> request = createRequest(RestVerb::Post, ContentType::VPack);
// enter the database name (ensure the user has access)
request->header.database = ?;
// API endpoint to submit AQL queries
request->header.path = "/_api/cursor";
// Create a payload to be submitted to the API endpoint
VPackBuilder builder;
builder.openObject();
// here is your query
builder.add("query", VPackValue("for col in collections() return col.name"));
builder.close();
// add the payload to the request
request->addVPack(builder.slice());
// send the request (blocking)
std::unique_ptr<Response> response = conn->sendRequest(std::move(request));
// check the response code - it should be 201
unsigned int statusCode = response->statusCode();
// slice has the response data
VPackSlice slice = response->slices().front();
std::cout << slice.get("result").toJson() << std::endl;

JMeter - Verify a Specific Cookie Value was Used?

So in my Test Plan I have a Cookie Manager setup inside my Thread Group which sets a specific Cookie value for 1 Cookie. Let's call it, MYID. I'm trying to figure out a way to verify that this specific Cookie's value was used to complete this one HTTP Request, because if I set my MYID to a specific value *(which actually tells which web server to go to), say to "Server1", but Server1 is down, unavailable, etc... HAProxy should change this and send you to Server2.
So basically I want to try and make sure that Cookie MYID was equal to "Server1" all the way through the HTTP Request.
I am trying to use a BeanShell PostProcessor to verify the Cookie's value after the request is ran, but when I tried using some code I have inside a PreProcessor that sets a cookie in a different Test Plan of mine I get an error saying:
Error Message:
Typed variable declaration : Attempt to resolve method: getCookieManager() on undefined variable or class name: sampler
And below here is the Code slightly modified from a BeanShell PreProcessor in another Test Plan I have...
CODE:
import org.apache.jmeter.protocol.http.control.Cookie;
import org.apache.jmeter.protocol.http.control.CookieManager;
CookieManager manager = sampler.getCookieManager();
for (int i = 0; i < manager.getCookieCount(); i++) {
Cookie cookie = manager.get(i);
if (cookie.getName().equals("MYID")) {
if (cookie.getValue().equals("Server1")) {
log.info("OK: The Cookie contained the Correct Server Number...");
} else {
log.info("ERROR: The Cookie did NOT contain the Correct Server Number...");
}
break;
}
}
For the error, I was thinking the "sampler" object was no longer available since the Request was already run, or something along those lines, but I'm not sure...
Or, is there another JMeter object I should be using instead of the "BeanShell PostProcessor" in order to verify the Cookie's value was correct..?
Any thoughts or suggestion would be greatly appreciated!
Thanks in Advance,
Matt
If you trying to get cookie manager from the parent sampler in the Beanshell PostProcessor - you need to use ctx.getCurrentSampler(), not "sampler" as it is not exposed in script variables.
So just change this line:
CookieManager manager = sampler.getCookieManager();
to
CookieManager manager = ctx.getCurrentSampler().getCookieManager();
And your script should start working as you expect.
ctx is a shorthand to JMeterContext instance and getCurrentSampler() method name is self-explanatory.
For more information on Beanshell scripting check out How to use BeanShell: JMeter's favorite built-in component guide.

Redirecting root context path or binding it to a servlet or mapping it with a welcome-file

I am using Jetty-9 in embedded mode and need only one web application. Consequently I would like the root URL to go to the homepage of that application, i.e. something like
http://localhost:4444/
should end up in a servlet. I start out with:
ServletContextHandler scContext =
new ServletContextHandler(ServletContextHandler.SESSIONS);
scContext.setContextPath("/");
None of the following worked, neither
scContext.addServlet(ListsServlet.class, "/");
nor
scContext.setWelcomeFiles(new String[]{"/lists})
where /lists is mapped to the ListsServlet servlet. All I get is a 403 (Forbidden).
I do not use the DefaultServlet, which seems to handle welcome files. But since the ServletContextHandler has setWelcomeFiles I expected it to contain the logic to use them.
Any ideas?
For the 403 Forbidden error, you have some security setup that is not allowing you to access the handlers/servlets.
Eliminate that security (for now), verify that the rest is working, then add security a bit later to lock down specifics.
If you want to see some the suggestions below at work, consider looking at the code example in the answer from another stackoverflow: How to correctly support html5 <video> sources with jetty.
Welcome files are appended to the incoming request path if there is nothing present at that location. For example requesting a directory and then a welcome-file of 'index.html' is appended to the request path.
While this would work ...
scContext.setWelcomeFiles(new String[]{"lists"})
// Add Default Servlet (must be named "default")
ServletHolder holderDefault = new ServletHolder("default",DefaultServlet.class);
holderDefault.setInitParameter("resourceBase",baseDir.getAbsolutePath());
holderDefault.setInitParameter("dirAllowed","true");
holderDefault.setInitParameter("welcomeServlets","true");
holderDefault.setInitParameter("redirectWelcome","true");
scContext.addServlet(holderDefault,"/");
It's likely not what you are aiming for, as you said the root path only.
The above would also make changes to requests like /foo/ to /foo/lists
Instead, it might make more sense to use a Rewrite rule + handler instead of the welcome-files approach.
RewriteHandler rewrite = new RewriteHandler();
rewrite.setHandler(scContext);
RewritePatternRule rootRule = new RewritePatternRule();
rootRule.setPattern("/");
rootRule.setReplacement("/list");
rootRule.setTerminating(true);
rewrite.addRule(rootRule);
server.setHandler(rewrite);
This RewritePatternRule simply changes any request path / to /list and then forwards that request to the wrapped ssContext (if you want to see the /list on the browser, change it to a RedirectPatternRule instead.

OTRS Webservice as Requestor Test

I'm new to OTRS (3.2) and also new to PERL but I have been given the task of setting up OTRS so that it will make a call to our remote webservice so a record can be created on our end when a ticket is set as "Closed".
I set up various dynamic fields so the customer service rep can fill in additional data that will be passed into the webservice call along with ticket details.
I couldn't get the webservice call to trigger when the ticket was "Closed" but I did get it to trigger when the "priority" was changed so I'm just using that now to test the webservice.
I'm just using the Test.pm and TestSimple.pm files that were included with OTRS.
When I look at the Debugger for the Webserice, I can see that the calls were being made:
$VAR1 = {
'TicketID' => '6'
};
My webservice currently just has one method "create" which just returns true for testing.
however I get the following from the Test.pm
"Got no TicketNumber (2014-09-02 09:20:42, error)"
and the following from the TestSimple.pm
"Error in SOAP call: 404 Not Found at /TARGET/SHARE/var/otrs/Kernel/GenericInterface/Transport/HTTP/SOAP.pm line 578 (2014-09-02 09:20:43, error)
I've spent countless hours on Google but couldn't find anything on this. All I could find is code for the Test.pm and TestSimple.pm but nothing really helpful to help me create a custom invoker for my needs and configure the webservice in OTRS to get it to work.
Does anyone have any sample invokers that I can look at to see how to set it up?
Basically I need to pass the ticket information along with my custom dynamic fields to my webservice. From there I can create the record on my end and do whatever processing.
I'm not sure how to setup the Invoker to pass the necessary ticket fields and dynamic fields and how to make it call a specific method in my remote webservice.
I guess getting the Test.pm and TestSimple.pm to work is the first step then I can modify those for my needs. I have not used PERL at all so any help is greatly appreciated.
I'm also struggling with similar set of requirements too. I've also never programmed in PERL, but I can tell you at least that the "Got no TicketNumber" in the Test.pm is right from the PrepareRequest method, there you can see this block of code:
# we need a TicketNumber
if ( !IsStringWithData( $Param{Data}->{TicketNumber} ) ) {
return $Self->{DebuggerObject}->Error( Summary => 'Got no TicketNumber' );
}
You should change all references to TicketNumber to TicketID, or remove the validation whatsoever (also there is mapping to ReturnedData variable).
Invoking specific methods on your WS interface is quite simple (but poorly documented). The Invoker name that you specify in the "OTRS as requester" section of web service configuration corresponds to the WS method that will be called. So if you have WS interface with a method called "create" just name the Invoker "create" too.
As far as the gathering of dynamic field goes, can't help you on that one yet, sorry.
Cheers

gSoap: How to set or change cookies on client in Qt?

I'am use next code for authorization on server by service, and get other service'methods using cookie identifer for authorizathion.
TerminalControllerBinding soapObj;
soap_init1(soapObj.soap, SOAP_C_UTFSTRING);
soapObj.endpoint = "http://192.168.*.*/path/to/service";
ns1__getTemplatesResponse *response = new ns1__getTemplatesResponse;
std::string auth_res = "";
soapObj.ns1__auth("user", "password", auth_res);
QString sessid = QString::fromStdString(auth_res);
qDebug() << sessid;
soapObj.soap->cookies = soap_cookie(soapObj.soap, "sessid", sessid.toAscii().data(), ".");
Server not getting cookie "sessid"
I am kind of confused by the code you posted: You allocate memory for ns1__getTemplatesResponse, then do some apparently unrelated stuff; in fact you do not reference it again at all. Furthermore soap_cookie is a struct and soap->cookies is basically a list. So there is no magic that transfers the cookies to the server here.
I think what you want is soap_set_cookie. You can find a little more information on client side cookies here, but there isn't any example code. Much more helpful however is actually the server side documentation (the handling of cookies doesn't differ much).
Also notice that you either need to compile with -DWITH_COOKIES or define the macro yourself in stdsoap.h if you haven't done so already.