Quarkus: Using placeholders in #Path - properties

With Spring MVC, it is possible to use placeholders with Path configurations. In #RequestMapping("${myapp.path}") the placeholder will be replaced with the myapp.path propert.
Is there an equivalent method for the #Path annotation in Quarkus? There the {myapp.path} part is interpreted to be a path parameter.
To prevent an X-Y Problem: I'm looking for a way to configure a path on application startup and looked towards the solution I've known from Spring.

So, after struggling for a bit, I found this solution. Tell me if it helped.
I used the brackets in the #Path annotation (in my interface class service).
Then I specified what my id parameter is by specifying it with the #PathParam annotation in my method.
#GET
#Path("api/{myId}")
#Produces(MediaType.APPLICATION_JSON)
public Response findArticlePriceById(#HeaderParam("header") String myheader, #PathParam("id") String myId, #QueryParam("name") String myName);
You can then just send that parameter as a string from where you call your method.
Response jsonResponse = myService.findArticlePriceById("my-header", "133", "my-name");
My GET request will be : localhost:8080/api/133?name=my-name

As it turns out, this is currently impossible. I've opened up an issue, so we'll see if it will be in the future.

Related

Flowable - concat dynamic variable and a string in http task (url)

I need to convert the base url according to the production and other environments.
I am using script task before a http task to perform this logic.
baseUrl = http://localhost:8080
baseUrl, is the output of the script task. Now I need to add this base url as a prefix in http task url
Url = ${baseUrl}/application/find (something like this).
I am getting the following issue
Unknown Property used in the expression ${baseUrl}/application/find
Script
var env = execution.getVariable("env")
if(env == "prod") {
var baseUrl = "http://localhost:8080";
execution.setVariable("baseUrl", baseUrl);
}
Please assist.
This typically means that it is unable to find a property in the expression (as the message says). The only expression you are using is baseUrl which means that the issue is around the baseUrl. The concatenation as you have done it is correct and doesn't need to have an adaption.
You should check if the variable really exists, this you can do by introducing a wait state before your HTTP task and check afterwards if the variable is created. Rather than using outputs, you can also use the Java API in your script task to create the variable:
execution.setVariable("baseUrl", "http://localhost:8080");
Assuming you are using Spring Boot, for your specific use-case it would be also an option to use the application.properties to specify your base-url and then refer to the baseUrl with the following expression:
${environment.getProperty("baseUrl")}/application/find
This will allow you to change the baseUrl independent of your process definition.

Activiti BPMN - How to pass username in variables/expression who have completed task?

I am very new to Activiti BPMN. I am creating a flow diagram in activiti. I m looking for how username (who has completed the task) can be pass into shell task arguments. so that I can fetch and save in db that user who has completed that task.
Any Help would be highly appreciated.
Thanks in advance...
Here's something I prepared for Java developers based on I think a blog post I saw
edit: https://community.alfresco.com/thread/224336-result-variable-in-javadelegate
RESULT VARIABLE
Option (1) – use expression language (EL) in the XML
<serviceTask id="serviceTask"
activiti:expression="#{myService.toUpperCase(myVar)}"
activiti:resultVariable="myVar" />
Java
public class MyService {
public String toUpperCase(String val) {
return val.toUpperCase();
}
}
The returned String is assigned to activiti:resultVariable
HACKING THE DATA MODEL DIRECTLY
Option (2) – use the execution environment
Java
public class MyService implements JavaDelegate {
public void execute(DelegateExecution execution) throws Exception {
String myVar = (String) execution.getVariable("myVar");
execution.setVariable("myVar", myVar.toUpperCase());
}
}
By contrast here we are being passed an ‘execution’, and we are pulling values out of it and twiddling them and putting them back.
This is somewhat analogous to a Servlet taking values we are passed in the HTMLRequest and then based on them doing different things in the response. (A stronger analogy would be a servlet Filter)
So in your particular instance (depnding on how you are invoking the shell script) using the Expression Language (EL) might be simplest and easiest.
Of course the value you want to pass has to be one that the process knows about (otherwise how can it pass a value it doesn't have a variable for?)
Hope that helps. :D
Usually in BPM engines you have a way to hook out listener to these kind of events. In Activiti if you are embedding it inside your service you can add an extra EventListener and then record the taskCompleted events which will contain the current logged in user.
https://www.activiti.org/userguide/#eventDispatcher
Hope this helps.
I have used activiti:taskListener from activiti app you need to configure below properties
1. I changed properties in task listener.
2. I used java script variable for holding task.assignee value.
Code Snip:-

How can I POST (as XML) an object to my ApiController using RestSharp?

I have an ASP.NET MVC4 website implementing a REST API, which I'm consuming from a client application. My ApiController methods take and return complex objects, as XML.
I recently discovered RestSharp, and have begun moving my client project over to that. However, I'm having real problems with it. It seems to almost work - it's so close that I can almost taste success - but I just can't get it to work 100%.
The objects I'm passing across the wire look something like this:
// The object I'm passing across the wire
public class Example
{
bool IsActive { get; set; }
string Name { get; set; }
}
My ApiController method looks like this:
// My ApiController method
public HttpResponseMessage PostExample(Example example)
{
if (ModelState.IsValid)
{
db.Examples.Add(example);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, example);
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
The problem occurs when I try to POST an object to my website, like this:
var example = new Example () { IsActive = true, Name = "foo" };
var request = new RestSharp.RestRequest("/api/example", RestSharp.Method.POST);
request.AddBody(example, XmlNamespace);
var client = new RestClient();
client.BaseUrl = "foo.com";
var response = client.Execute<Example>(request);
The code above does hit the PostExample method in my ApiController, and it has an Example object as the parameter. However the values of the properties of the Example object are not the same as I passed to the Execute method! In one case, the IsActive member was false instead of true, although I also saw a case where the Name member was null where it should have had a value.
I did some investigation using Fiddler, and it seems that the correct values are being created in the XML that RestSharp generates. However, the XML is not quite in the same format that the web server emits when doing a GET. The differences are subtle, but seem to make the difference between it working and not working. The framework at the web server end seems to be sensitive to these formatting differences, and is mis-interpreting the XML as a result.
Here's the XML I get from RestSharp:
<Example xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
<Name>foo</Name>
<IsActive>true</IsActive>
</Example>
This is what I get when doing a GET on the webserver (or when serializing using the DataContractSerializer, which is what I was previously doing):
<Example xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ExampleNamespace">
<IsActive>true</IsActive>
<Name>foo</Name>
</TagDto>
The RestSharp version has the following differences from the DataContractSerializer's version:
Fields are in a different order
RestSharp doesn't include the extra namespace XMLSchema-instance namespace
DataContractSerializer doesn't include any spaces or line-breaks (I added those above for readability)
I'm surprised that any of those make much of a difference, but clearly they do. Note also that until I added an explicit namespace in the AddBody call, this was missing in the generated XML (obviously), and the Example object passed into my ApiController was null.
Anyway, I noticed that RestSharp allows you to override the serializer, and provides a way to use the .NET XML serializer. I tried using that (to no avail).
This is what I added before the call to AddBody:
request.XmlSerializer = new RestSharp.Serializers.DotNetXmlSerializer(XmlNamespace);
..and this is what I get out:
<?xml version="1.0" encoding="utf-8"?>
<Example>
<Name>foo</Name>
<IsActive>true</IsActive>
</Example>
This is clearly no good, not least because it starts with an XML declaration, which I imagine would cause problems. There's no way to turn that off, because the RestSharp derived class provides no way to do so. Also, there's no namespace - and I can't get one to appear in the output no matter how I try to set the namespace in RestSharp (in the constructor for the DotNetXmlSerializer, by setting the Namespace member, or by passing in a namespace to AddBody). To my eyes, this class is nothing more than a trap.
It looks like my only option is to create my own serializer class and use the DataContractSerializer internally. Is that right, or am I missing something?
(BTW, I can set the RequestFormat of the request to JSON and it just works - but I'd still like to know how to get this working with XML).
I've had some issues with the AddBody calls not properly serializing JSON values, so there might be some similarity to your problem. Instead of AddBody, you could try:
request.AddParameter("text/xml", xmlAsString, ParameterType.RequestBody);
If that works, you could look to see about changing the second parameter to be the xml object and see if the serializer does what you want.
The other option could be the XmlMediaTypeFormatter.ReadFromStreamAsync isn't properly picking up a proper serializer; you could try overriding that function.
The issue above is because WebAPI is using the DataContractSerializer (as opposed to the XmlSerializer which is what you're after). To switch this around modify Global.asax as follows.
var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
xml.UseXmlSerializer = true;
However, I suggest you use the RESTSharp formatters for WebAPI (instead of using the .Net formatters). This is particularly useful if you're DTO's have circular references (the .net fx serializers don't handle this too gracefully).
In Global.asax, modify the formatters by putting in
GlobalConfiguration.Configuration.Formatters.XmlFormatter = //RestSharp XML serializer here
A quick overview of serialization in WebAPI is here and worth a browse

How can you use SessionAsSigner in a Java Bean called from an XPage?

According to Phillip Riand (see: discussion on openNTF) this is not possible... They need to know the design element to find out who signed it. Therefore, it is only available in SSJS.
There are 2 ways that I know of to use the sessionAsSigner object in Java beans:
1 By resolving the sessionAsSigner object:
FacesContext context = FacesContext.getCurrentInstance();
Session sessionAsSigner = context.getApplication().getVariableResolver().
resolveVariable(context, "sessionAsSigner");
2 By using the getCurrentSessionAsSigner() function from the com.ibm.xsp.extlib.util.ExtLibUtil class in the Extension Library.
To be able to use it (in Java as wel as SSJS) you'll want to make sure that all design elements were signed by the same user ID. If that's not the case, the sessionAsSigner object will not be available ('undefined').
I found that the solution is right at hand :-)
I changed my XPage (in this example an XAgent) to:
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
This is an xAgent returning json data...
<xp:this.afterRenderResponse><![CDATA[#{javascript:Controller.verify(sessionAsSigner)}]]></xp:this.afterRenderResponse>
and in the bean I simply used the session in the argument when I needed to open a database/document as signer. Sometimes the solution is so simple :-)
/John
This is quite an old post that I just stumbled upon. Tried some of the solutions mentioned above:
resolveVariable did not work for me, at least not for sessionAsSigner as this throws a runtime error (I can resolve plain old session, though...)
to be honest I didn't quite understand the Controller.verify(sessionAsSigner) method; is Controller something specific to XAgents? If so, I don't have an XAgent here, so can't use it
didn't feel like importing extra ExtLib classes here...
So I came up with another solution that appears to be very simple:
created a method in my javaBean that takes a session object as argument; since sessionAsSigner belongs to the same class as session I don't have to import something new.
Javacode is:
public void testSession(Session s) throws Exception{
System.out.println(" > test effective user for this session = "
+ s.getEffectiveUserName());
}
This is called from SSJS as either
mybean.testSession(session);
or
myBean.testSession(sessionAsSigner);
Maybe helps others, too

Getting Path (context root) to the Application in Restlet

I am needing to get the application root within a Restlet resource class (it extends ServerResource). My end goal is trying to return a full explicit path to another Resource.
I am currently using getRequest().getResourceRef().getPath() and this almost gets me what I need. This does not return the full URL (like http://example.com/app), it returns to me /resourceName. So two problems I'm having with that, one is it is missing the schema (the http or https part) and server name, the other is it does not return where the application has been mounted to.
So given a person resource at 'http://dev.example.com/app_name/person', I would like to find a way to get back 'http://dev.example.com/app_name'.
I am using Restlet 2.0 RC3 and deploying it to GAE.
It looks like getRequest().getRootRef().toString() gives me what I want. I tried using a combination of method calls of getRequest().getRootRef() (like getPath or getRelativePart) but either they gave me something I didn't want or null.
Just get the base url from service context, then share it with the resources and add resource path if needed.
MyServlet.init():
String contextPath = getServletContext().getContextPath();
getApplication().getContext().getAttributes().put("contextPath", contextPath);
MyResource:
String contextPath = getContext().getAttributes().get("contextPath");
request.getRootRef() or request.getHostRef()?
The servlet's context is accessible from the restlet's application:
org.restlet.Application app = org.restlet.Application.getCurrent();
javax.servlet.ServletContext ctx = ((javax.servlet.ServletContext) app.getContext().getAttributes().get("org.restlet.ext.servlet.ServletContext"));
String path = ctx.getResource("").toString();