Message history for outbound component - spring-integration

How should I track int-http:outbound-gateway and int-jms:outbound-channel-adapter? Below are the mapping of the component corresponding to java classes. Please verify.
I need to call setShouldTrack(true) method on the following bean so that I can fetch these component details in message-history (name,type,timestamp)
int-ws:outbound-gateway org.springframework.integration.ws.MarshallingWebServiceOutboundGateway
int-http:inbound-gateway org.springframework.integration.http.inbound.HttpRequestHandlingMessagingGateway
int-http:outbound-gateway org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler
int-jms:message-driven-channel-adapter org.springframework.integration.jms.JmsSendingMessageHandler
int-jms:outbound-channel-adapter ??
Currently I am able to track int-http:inbound-gateway and int-jms:message-driven-channel-adapter.

Your question is not clear. All the MessageHandler implementations in the Framework are an extension of the AbstractMessageHandler and there is a setShouldTrack() method.
If you would like to call it manually, you can get access to them via their id. And this one is a composed id of the wrapping consumer endpoint and .handler suffix: https://docs.spring.io/spring-integration/docs/current/reference/html/overview.html#endpoint-bean-names
On the other hand it isn't clear why would one do that manually, if the <message-history> allows us to configure patterns for component names delimited with comma: https://docs.spring.io/spring-integration/docs/current/reference/html/system-management-chapter.html#message-history-config

Related

Spring-Content 1.2.7: Identifier for the ContentStore

What I intend to do: I'd like to use multiple ContentStores in the same system: one for freshly uploaded files (filesystem), one for (long term) archiving (AWS S3 or maybe GCS).
What I tried (and what actually does work):
Extended class File by another attribute private String contentStoreName;
Creating two ContentStores like described here: Spring-Content: Moving files from content store to another content store
Extending gettingstarted.FileContentController.setContent(Long, MultipartFile) by setting an identifier for the used ContentStore: f.get().setContentStoreName("regular");
Getting the content in dependence of the stored contentStoreName:
InputStream input;
if (Objects.equals(f.get().getContentStoreName(), "archive")) {
input = archiveContentStore.getContent(f.get());
} else {
input = regularContentStore.getContent(f.get());
}
Changing the contentStoreName when moving from one ContentStore to another:
Resource resource = regularContentStore.getResource(fileEntity.get());
archiveContentStore.setContent(fileEntity.get(), resource);
fileEntity.get().setContentStoreName("archive");
filesRepo.save(fileEntity.get());
The smell about this: Despite this code works, I guess it's not the intended way, because Spring-content usually does a lot with annotations and some magic in the background. But I can't find an annotation for an identifier / name for the ContentStore.
Question: Is there a more intended way of doing this in Spring-Content?
Beyond supporting multiple storage modules in a single application (via the FilesystemContentStore, et al annotations) Spring Content does not currently provide any logic for supporting classes of storage. That would be a layer that you need to create on top of Spring Content as you are starting to do.
In terms of Spring Content annotations it might be helpful for you to understand what modules manage what annotations.
Spring Content storage modules; FS, S3, etc all implement ContentStore and in doing so all provide management of the #ContentId and #ContentLength attributes (in addition to managing the actual content operations). Looks like you are using the ContentStore API (getContent/setContent) and therefore your entity's content id and length attributes will be managed for you.
Spring Content REST then provides management of #MimeType and #OriginalFileName attributes (in addition to providing comprehensive REST endpoints). My guess is that you are not using this and instead providing your own custom controller REST API that uses the 'contentStoreName' attribute to decide which store to put/get the content from. This approach seems fine.
That is all to say that a slightly more elegant approach, perhaps, that would allow you to use Spring Content REST might be to implement your own custom Archiving Storage module and encapsulate the "switching" logic you have above in its setContent/getContent/unsetContent methods. Note, this is actually quite easy (just 4 or 5 classes and I would point you at the GCP and Azure modules for inspiration). Note, that the REST API (for ContentStore) only calls those 3 APIs too so those are the only ones you would need to implement. This would mean you get to use Spring Content REST and all the features it provides; set of rest endpoints, byte range support and so on as well as encapsulating your "archiving" logic nicely.

Should I call Axios in each component on a page or multiple times on the parent page for each component?

I'm looking to understand what is the best practice when it comes to utilizing Axios to fetch data from Node.js. I have multiple graphs, cards and other components on the given page and am trying to understand if I should be calling Axios on the parent page for each component and passing the values as props to the component or rather call Axios and the data in each component itself.
Trying to understand what is seen as best practice.
From my understanding it is better to let each component be self standing (i.e. call its own data from the DB) rather than once on the page.
Much appreciated.
It's better to have a layer between components and axios (a class / function that wraps axios for example).
Then, each components will call that class and the class will call axios.
By doing this, you can let each component fetch its own data.
Then you can add a logic so that if 2 components try to fetch the same data, you will cache it and only fetch it once.
By doing this, you keep each component self sufficient, and you reduce the number of calls to the server
If the data is used only in a sub-component, there is no need to query it one level above, do it in the component itself for the sake of encapsulation: it will allow you to not leave behind useless axios code should you remove the sub-component later.
If the data is shared by multiple components, do the query once and pass it to every child that needs it.
N.B. What is a common practice however, is to have a component that is purely "presentational" (with no logic, only receiving props), and a parent component that does the query (and maybe some other logic) and passes the result as props to the presentational one. It allows to re-use the graphical layout of the presentational component with different input data somewhere else.

Liferay 7 - Multiple resourceCommands in single class?

I'm about to move from Liferay 6.2 to 7. I'v been using Spring in Liferay 6.2, but apparently using Spring on 7 doesn't have benefits of using component specific configuration via classes.
It seems to me that every single Liferay 7 ajax endpoint needs to be configured as single command class, leading to dozens of files per logical model/controller.
On LR 6.2 Spring I have had single controller which wraps every resource-endpoint to single file. Is this possible on LR 7 with components? If LR7 enforces to use single class-file per command, while is this forced instead of supporting single class with multiple methods (design-wise)?
I assume that you're talking about the serveResource phase of a portlet when you talk about Ajax endpoints.
If you go the ResourceCommand route: Yes, you'll need a single resource command for every named resource handler. However, you do not have to go this way, you can still implement in a single portlet class.
The one difference:
You're in control of your own portlet, which means that you can easily change and update it should you need a different behavior. Thus it's not a problem to go with a single (potentially larger) portlet class.
On the other hand Liferay's built-in components sometimes need to be updated by others (e.g. you), so separating them out into many smaller services is a great thing for Liferay users who intend to modify tiny aspects: They only need to override the single ResourceCommand they have in mind for their change.
Thus, you'll see excessive use of the ResourceCommand pattern all over Liferay. But you can totally ignore this for your own code and continue with individual named resource handlers in a single class.
That being said, some pseudocode (only written here, never compiled and tested) for such a portlet:
#Component(...)
public class MyPortlet extends GenericPortlet {
public void serveResource(ResourceRequest req, ResourceResponse res) {
String name = req.getParameter("name");
// handle request for named activity
}
}
(Edit of the code: Apologies, I completely mixed up the Action and Resource phases, rather suggested "Action" logic than "Resource")
And yet another alternative is to ditch the portlet implementation and just implement a Web Service - either through Liferay's Service Builder, or through REST. There are plenty of samples available for these cases as well, but your question appeared as if you were going the portlet route.

Spring Integration - modifying one property of the payload

In my SI flow I want to modify one property of the payload. At the beginning of the flow I populate a Java bean (let's call it MyFlowBean) and I send it via the difference components of the flow.
At one point I want to alter the property 'extractedValue' of this bean and I want to do it in the right way. I mean I am sure there is a component (a transformer??) where I can say e.g.
<transform propert='payload.extractedValue' value='[spEl expression]' />
Ok, I know there isn't such a tag in SI, it was just a sample.
Also I could achieve it with serviceActivator but it doesn't seem right to me to write a Java class that contain 2 lines of code and use this class in the service activator.
It has to be more elegant way.
Thanks,
V.
The Content Enricher pattern is for your and respectively the <enricher> component is present in the Spring Integration to achieve the desired goal:
<enricher>
<property name="extractedValue" expression="[spEl expression]"/>
</enricher>

how can I access endpoint properties set in faces-config.xml programmatically?

I am using the IBM Social Business Toolkit. I have defined a connection for my Notes app via endpoints in the faces-config xml file. I wonder how I can access this file pro grammatically since I could not find a service that returns me the base url of IBM Connections.
It's useful to remember that an endpoint definition is really just creating a managed bean. The managed bean has a variable name you refer to it - the managed-bean-name property. You can access this directly from SSJS or via ExtLibUtil.resolveVariable() in Java. The definition also tells you the Java class that's being used, e.g. com.ibm.sbt.services.endpoints.ConnectionsBasicEndpoint. That really gives you all the information you need to get or set the properties.
So from SSJS you can just cast it to the class name, e.g.
var myService:com.ibm.sbt.services.endpoints.ConnectionsBasicEndpoint = connections
So the bit after the colon will be the managed-bean-class value and the bit after the equals sign will be the managed-bean-name. In Java, you can use
ConnectionsBasicEndpoint myService = (ConnectionsBasicEndpoint) ExtLibUtil.resolveVariable(ExtLibUtil.getXspContext().getFacesContext(), "connections");
You'll then have access to all the methods of the class, so you should be able to retrieve what you need.
The properties are part of the Java class, who are referred to in the Faces-Config.xml. So get the class by his fully qualified name or by bean name and set or get the properties
I think the best route will most likely be what Paul is suggesting: resolve the variable by its name and use the getters to get the effective properties that way.
Sven's suggestion is a good one to keep in mind for other situations. By accessing the faces-config.xml file as a resource, you could load it into an XML parser and find the values using XPath. I'm doing much that sort of technique in the next version of the OpenNTF Domino API, which will have a set of methods for manipulating the Faces config. However, one key aspect there is that reading the XML file directly will just get you the string values, which may be EL expressions, whereas going the resolveVariable route will get you the real current properties.

Resources